Full Code of facebook/fresco for AI

main 322f67e65293 cached
2570 files
38.2 MB
4.1M tokens
553 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (16,466K chars total). Download the full file to get everything.
Repository: facebook/fresco
Branch: main
Commit: 322f67e65293
Files: 2570
Total size: 38.2 MB

Directory structure:
gitextract_dq5d7atw/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       ├── build.yml
│       ├── gradle-wrapper-validation.yml
│       └── release.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── animated-base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               ├── fresco/
│       │               │   └── animation/
│       │               │       ├── bitmap/
│       │               │       │   ├── cache/
│       │               │       │   │   ├── AnimationFrameCacheKey.kt
│       │               │       │   │   └── FrescoFrameCache.kt
│       │               │       │   └── wrapper/
│       │               │       │       ├── AnimatedDrawableBackendAnimationInformation.kt
│       │               │       │       └── AnimatedDrawableBackendFrameRenderer.kt
│       │               │       ├── drawable/
│       │               │       │   └── animator/
│       │               │       │       └── AnimatedDrawableValueAnimatorHelper.kt
│       │               │       └── factory/
│       │               │           ├── AnimatedFactoryV2Impl.kt
│       │               │           └── DefaultBitmapAnimationDrawableFactory.kt
│       │               └── imagepipeline/
│       │                   ├── animated/
│       │                   │   ├── base/
│       │                   │   │   ├── AnimatedDrawableBackend.java
│       │                   │   │   ├── AnimatedDrawableFrameInfo.java
│       │                   │   │   ├── AnimatedDrawableOptions.java
│       │                   │   │   ├── AnimatedDrawableOptionsBuilder.java
│       │                   │   │   ├── AnimatedImage.java
│       │                   │   │   ├── AnimatedImageFrame.java
│       │                   │   │   ├── AnimatedImageResult.java
│       │                   │   │   ├── AnimatedImageResultBuilder.java
│       │                   │   │   ├── AnimatedImageValidator.kt
│       │                   │   │   └── package-info.java
│       │                   │   ├── factory/
│       │                   │   │   ├── AnimatedImageDecoder.kt
│       │                   │   │   ├── AnimatedImageDecoderBase.kt
│       │                   │   │   └── AnimatedImageFactory.kt
│       │                   │   ├── impl/
│       │                   │   │   ├── AnimatedDrawableBackendImpl.java
│       │                   │   │   ├── AnimatedDrawableBackendProvider.java
│       │                   │   │   ├── AnimatedFrameCache.java
│       │                   │   │   ├── AnimatedImageCompositor.java
│       │                   │   │   └── package-info.java
│       │                   │   └── util/
│       │                   │       ├── AnimatedDrawableUtil.kt
│       │                   │       └── package-info.kt
│       │                   └── image/
│       │                       ├── CloseableAnimatedImage.java
│       │                       └── package-info.java
│       └── test/
│           └── java/
│               ├── android/
│               │   └── net/
│               │       └── http/
│               │           └── AndroidHttpClient.java
│               └── com/
│                   └── facebook/
│                       ├── fresco/
│                       │   └── animation/
│                       │       └── bitmap/
│                       │           ├── cache/
│                       │           │   └── FrescoFrameCacheTest.kt
│                       │           └── wrapper/
│                       │               ├── AnimatedDrawableBackendAnimationInformationTest.kt
│                       │               └── AnimatedDrawableBackendFrameRendererTest.kt
│                       └── imagepipeline/
│                           ├── animated/
│                           │   ├── impl/
│                           │   │   ├── AnimatedDrawableBackendImplTest.kt
│                           │   │   └── AnimatedFrameCacheTest.kt
│                           │   ├── testing/
│                           │   │   └── TestAnimatedDrawableBackend.java
│                           │   └── util/
│                           │       └── AnimatedDrawableUtilTest.kt
│                           └── producers/
│                               ├── AnimatedRepeatedPostprocessorProducerTest.kt
│                               └── AnimatedSingleUsePostprocessorProducerTest.kt
├── animated-drawable/
│   ├── .gitignore
│   ├── README.md
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── fresco/
│       │                   └── animation/
│       │                       ├── backend/
│       │                       │   ├── AnimationBackend.java
│       │                       │   ├── AnimationBackendDelegate.kt
│       │                       │   ├── AnimationBackendDelegateWithInactivityCheck.java
│       │                       │   └── AnimationInformation.java
│       │                       ├── bitmap/
│       │                       │   ├── BitmapAnimationBackend.kt
│       │                       │   ├── BitmapFrameCache.kt
│       │                       │   ├── BitmapFrameRenderer.kt
│       │                       │   ├── cache/
│       │                       │   │   ├── KeepLastFrameCache.kt
│       │                       │   │   └── NoOpCache.kt
│       │                       │   └── preparation/
│       │                       │       ├── BitmapFramePreparationStrategy.kt
│       │                       │       ├── BitmapFramePreparer.kt
│       │                       │       ├── DefaultBitmapFramePreparer.kt
│       │                       │       ├── FixedNumberBitmapFramePreparationStrategy.kt
│       │                       │       ├── FrameLoaderStrategy.kt
│       │                       │       ├── loadframe/
│       │                       │       │   ├── AnimationLoaderExecutor.kt
│       │                       │       │   └── FpsCompressorInfo.kt
│       │                       │       └── ondemandanimation/
│       │                       │           ├── AnimationBitmapFrame.kt
│       │                       │           ├── AnimationCoordinator.kt
│       │                       │           ├── AnimationLoaderFactory.kt
│       │                       │           ├── BufferFrameLoader.kt
│       │                       │           ├── CircularList.kt
│       │                       │           └── FrameLoader.kt
│       │                       ├── drawable/
│       │                       │   ├── AnimatedDrawable2.kt
│       │                       │   ├── AnimatedDrawable2DebugDrawListener.kt
│       │                       │   ├── AnimationFrameScheduler.kt
│       │                       │   ├── AnimationListener.kt
│       │                       │   ├── BaseAnimationListener.kt
│       │                       │   ├── KAnimatedDrawable2.kt
│       │                       │   └── animator/
│       │                       │       └── AnimatedDrawable2ValueAnimatorHelper.kt
│       │                       └── frame/
│       │                           ├── DropFramesFrameScheduler.kt
│       │                           └── FrameScheduler.java
│       └── test/
│           └── java/
│               ├── com/
│               │   └── facebook/
│               │       └── fresco/
│               │           └── animation/
│               │               ├── backend/
│               │               │   ├── AnimationBackendDelegateTest.kt
│               │               │   └── AnimationBackendDelegateWithInactivityCheckTest.kt
│               │               ├── bitmap/
│               │               │   ├── BitmapAnimationBackendTest.kt
│               │               │   └── preparation/
│               │               │       ├── DefaultBitmapFramePreparerTest.kt
│               │               │       └── FixedNumberBitmapFramePreparationStrategyTest.kt
│               │               └── frame/
│               │                   └── DropFramesFrameSchedulerTest.kt
│               └── javax/
│                   └── microedition/
│                       └── khronos/
│                           └── opengles/
│                               └── GL.java
├── animated-gif/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── facebook/
│       │   │           └── animated/
│       │   │               └── gif/
│       │   │                   ├── AnimatedImageGifValidator.kt
│       │   │                   ├── GifFrame.java
│       │   │                   ├── GifImage.java
│       │   │                   └── GifImageDecoder.kt
│       │   └── jni/
│       │       ├── Application.mk
│       │       ├── gifimage/
│       │       │   ├── Android.mk
│       │       │   ├── OnLoad.cpp
│       │       │   ├── gif.cpp
│       │       │   ├── jni_helpers.cpp
│       │       │   ├── jni_helpers.h
│       │       │   ├── locks.h
│       │       │   └── secure_memcpy.h
│       │       └── third-party/
│       │           └── giflib/
│       │               └── Android.mk
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── gif/
│                               └── GifImageDecoderTest.kt
├── animated-gif-lite/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── giflite/
│                               ├── GifDecoder.java
│                               ├── decoder/
│                               │   └── GifMetadataDecoder.java
│                               ├── draw/
│                               │   ├── MovieAnimatedImage.kt
│                               │   ├── MovieDrawer.kt
│                               │   ├── MovieFrame.kt
│                               │   └── MovieScaleHolder.kt
│                               └── drawable/
│                                   └── GifAnimationBackend.kt
├── animated-webp/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── animated/
│       │                   ├── webp/
│       │                   │   ├── WebPFrame.java
│       │                   │   ├── WebPImage.java
│       │                   │   └── WebPImageDecoder.kt
│       │                   └── webpdrawable/
│       │                       └── WebpAnimationBackend.kt
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── webp/
│                               └── WebPImageDecoderTest.kt
├── bots/
│   └── IssueCommands.txt
├── build.gradle
├── buildSrc/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── buildsrc/
│                               ├── FrescoConfig.kt
│                               ├── GradleDeps.kt
│                               ├── TestDeps.kt
│                               ├── dependencies-samples.kt
│                               └── dependencies.kt
├── ci/
│   ├── build-and-test.sh
│   └── print-debug-info.sh
├── docs/
│   ├── .gitignore
│   ├── CNAME
│   ├── Gemfile
│   ├── NOGREP
│   ├── README.md
│   ├── _config.yml
│   ├── _data/
│   │   ├── authors.yml
│   │   ├── nav.yml
│   │   ├── nav_docs.yml
│   │   ├── powered_by.yml
│   │   ├── powered_by_highlight.yml
│   │   └── promo.yml
│   ├── _docs/
│   │   ├── 03-customizing-image-formats.md
│   │   ├── animations.md
│   │   ├── building-from-source.md
│   │   ├── caching.md
│   │   ├── closeable-references.md
│   │   ├── concepts.md
│   │   ├── configure-image-pipeline.md
│   │   ├── datasources-datasubscribers.md
│   │   ├── drawee-branches.md
│   │   ├── faq.md
│   │   ├── gotchas.md
│   │   ├── image-requests.md
│   │   ├── images-in-notifications.md
│   │   ├── index.md
│   │   ├── intro-image-pipeline.md
│   │   ├── listening-to-events.md
│   │   ├── media-variations.md
│   │   ├── placeholder-failure-retry.md
│   │   ├── post-processor.md
│   │   ├── prefetching.md
│   │   ├── progress-bars.md
│   │   ├── progressive-jpegs.md
│   │   ├── proguard.md
│   │   ├── requesting-multiple-images.md
│   │   ├── resizing.md
│   │   ├── rotation.md
│   │   ├── rounded-corners-and-circles.md
│   │   ├── sample-apps.md
│   │   ├── scaletypes.md
│   │   ├── shared-transitions.md
│   │   ├── supported-uris.md
│   │   ├── troubleshooting.md
│   │   ├── using-controllerbuilder.md
│   │   ├── using-image-pipeline.md
│   │   ├── using-other-network-layers.md
│   │   ├── using-simpledraweeview.md
│   │   ├── webp-support.md
│   │   └── writing-custom-views.md
│   ├── _includes/
│   │   ├── blog_pagination.html
│   │   ├── content/
│   │   │   ├── gridblocks.html
│   │   │   └── items/
│   │   │       └── gridblock.html
│   │   ├── doc.html
│   │   ├── doc_paging.html
│   │   ├── footer.html
│   │   ├── head.html
│   │   ├── hero.html
│   │   ├── home_header.html
│   │   ├── nav.html
│   │   ├── nav_search.html
│   │   ├── plugins/
│   │   │   ├── all_share.html
│   │   │   ├── button.html
│   │   │   ├── fb_pagelike.html
│   │   │   ├── github_star.html
│   │   │   ├── github_watch.html
│   │   │   ├── google_share.html
│   │   │   ├── group_join.html
│   │   │   ├── like_button.html
│   │   │   ├── plugin_row.html
│   │   │   ├── post_social_plugins.html
│   │   │   ├── slideshow.html
│   │   │   └── twitter_share.html
│   │   ├── post.html
│   │   ├── powered_by.html
│   │   ├── react/
│   │   │   ├── collection_nav.html
│   │   │   ├── header_nav.html
│   │   │   ├── nav_blog.html
│   │   │   └── nav_docs.html
│   │   ├── social_plugins.html
│   │   └── ui/
│   │       └── button.html
│   ├── _layouts/
│   │   ├── basic.html
│   │   ├── blog.html
│   │   ├── blog_default.html
│   │   ├── default.html
│   │   ├── doc_default.html
│   │   ├── doc_page.html
│   │   ├── docs.html
│   │   ├── home.html
│   │   ├── page.html
│   │   ├── plain.html
│   │   ├── post.html
│   │   └── redirect.html
│   ├── _sass/
│   │   ├── _base.scss
│   │   ├── _blog.scss
│   │   ├── _buttons.scss
│   │   ├── _footer.scss
│   │   ├── _gridBlock.scss
│   │   ├── _header.scss
│   │   ├── _poweredby.scss
│   │   ├── _promo.scss
│   │   ├── _react_docs_nav.scss
│   │   ├── _react_header_nav.scss
│   │   ├── _reset.scss
│   │   ├── _search.scss
│   │   ├── _slideshow.scss
│   │   ├── _syntax-highlighting.scss
│   │   └── _tables.scss
│   ├── css/
│   │   └── main.scss
│   ├── docs/
│   │   └── index.html
│   ├── index.md
│   ├── javadoc/
│   │   ├── assets/
│   │   │   ├── customizations.css
│   │   │   ├── customizations.js
│   │   │   ├── doclava-developer-core.css
│   │   │   ├── doclava-developer-docs.css
│   │   │   ├── doclava-developer-docs.js
│   │   │   ├── doclava-developer-reference.js
│   │   │   ├── jquery-history.js
│   │   │   ├── navtree_data.js
│   │   │   ├── prettify.js
│   │   │   ├── search_autocomplete.js
│   │   │   └── style.css
│   │   ├── index.html
│   │   └── reference/
│   │       ├── classes.html
│   │       ├── com/
│   │       │   └── facebook/
│   │       │       ├── animated/
│   │       │       │   ├── gif/
│   │       │       │   │   ├── GifFrame.html
│   │       │       │   │   ├── GifImage.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── giflite/
│   │       │       │   │   ├── GifDecoder.html
│   │       │       │   │   ├── decoder/
│   │       │       │   │   │   ├── GifMetadataDecoder.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── draw/
│   │       │       │   │   │   ├── MovieAnimatedImage.html
│   │       │       │   │   │   ├── MovieDrawer.html
│   │       │       │   │   │   ├── MovieFrame.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── drawable/
│   │       │       │   │   │   ├── GifAnimationBackend.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── webp/
│   │       │       │   │   ├── WebPFrame.html
│   │       │       │   │   ├── WebPImage.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── webpdrawable/
│   │       │       │       ├── WebpAnimationBackend.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── binaryresource/
│   │       │       │   ├── BinaryResource.html
│   │       │       │   ├── ByteArrayBinaryResource.html
│   │       │       │   ├── FileBinaryResource.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── cache/
│   │       │       │   ├── common/
│   │       │       │   │   ├── BaseCacheEventListener.html
│   │       │       │   │   ├── CacheErrorLogger.CacheErrorCategory.html
│   │       │       │   │   ├── CacheErrorLogger.html
│   │       │       │   │   ├── CacheEvent.html
│   │       │       │   │   ├── CacheEventListener.EvictionReason.html
│   │       │       │   │   ├── CacheEventListener.html
│   │       │       │   │   ├── CacheKey.html
│   │       │       │   │   ├── CacheKeyUtil.html
│   │       │       │   │   ├── DebuggingCacheKey.html
│   │       │       │   │   ├── HasDebugData.html
│   │       │       │   │   ├── MultiCacheKey.html
│   │       │       │   │   ├── NoOpCacheErrorLogger.html
│   │       │       │   │   ├── NoOpCacheEventListener.html
│   │       │       │   │   ├── SimpleCacheKey.html
│   │       │       │   │   ├── WriterCallback.html
│   │       │       │   │   ├── WriterCallbacks.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── disk/
│   │       │       │       ├── DefaultDiskStorage.FileType.html
│   │       │       │       ├── DefaultDiskStorage.html
│   │       │       │       ├── DefaultEntryEvictionComparatorSupplier.html
│   │       │       │       ├── DiskCacheConfig.Builder.html
│   │       │       │       ├── DiskCacheConfig.html
│   │       │       │       ├── DiskStorage.DiskDumpInfo.html
│   │       │       │       ├── DiskStorage.DiskDumpInfoEntry.html
│   │       │       │       ├── DiskStorage.Entry.html
│   │       │       │       ├── DiskStorage.Inserter.html
│   │       │       │       ├── DiskStorage.html
│   │       │       │       ├── DiskStorageCache.Params.html
│   │       │       │       ├── DiskStorageCache.html
│   │       │       │       ├── DynamicDefaultDiskStorage.html
│   │       │       │       ├── EntryEvictionComparator.html
│   │       │       │       ├── EntryEvictionComparatorSupplier.html
│   │       │       │       ├── FileCache.html
│   │       │       │       ├── ScoreBasedEvictionComparatorSupplier.html
│   │       │       │       ├── SettableCacheEvent.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── callercontext/
│   │       │       │   ├── CallerContextVerifier.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── common/
│   │       │       │   ├── activitylistener/
│   │       │       │   │   ├── ActivityListener.html
│   │       │       │   │   ├── ActivityListenerManager.html
│   │       │       │   │   ├── BaseActivityListener.html
│   │       │       │   │   ├── ListenableActivity.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── disk/
│   │       │       │   │   ├── DiskTrimmable.html
│   │       │       │   │   ├── DiskTrimmableRegistry.html
│   │       │       │   │   ├── NoOpDiskTrimmableRegistry.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── executors/
│   │       │       │   │   ├── CallerThreadExecutor.html
│   │       │       │   │   ├── ConstrainedExecutorService.html
│   │       │       │   │   ├── DefaultSerialExecutorService.html
│   │       │       │   │   ├── HandlerExecutorService.html
│   │       │       │   │   ├── HandlerExecutorServiceImpl.html
│   │       │       │   │   ├── ScheduledFutureImpl.html
│   │       │       │   │   ├── SerialExecutorService.html
│   │       │       │   │   ├── StatefulRunnable.html
│   │       │       │   │   ├── UiThreadImmediateExecutorService.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── file/
│   │       │       │   │   ├── FileTree.html
│   │       │       │   │   ├── FileTreeVisitor.html
│   │       │       │   │   ├── FileUtils.CreateDirectoryException.html
│   │       │       │   │   ├── FileUtils.FileDeleteException.html
│   │       │       │   │   ├── FileUtils.ParentDirNotFoundException.html
│   │       │       │   │   ├── FileUtils.RenameException.html
│   │       │       │   │   ├── FileUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── internal/
│   │       │       │   │   ├── AndroidPredicates.html
│   │       │       │   │   ├── ByteStreams.html
│   │       │       │   │   ├── Closeables.html
│   │       │       │   │   ├── CountingOutputStream.html
│   │       │       │   │   ├── DoNotStrip.html
│   │       │       │   │   ├── Files.html
│   │       │       │   │   ├── Fn.html
│   │       │       │   │   ├── ImmutableList.html
│   │       │       │   │   ├── ImmutableMap.html
│   │       │       │   │   ├── ImmutableSet.html
│   │       │       │   │   ├── Ints.html
│   │       │       │   │   ├── Objects.ToStringHelper.html
│   │       │       │   │   ├── Objects.html
│   │       │       │   │   ├── Preconditions.html
│   │       │       │   │   ├── Predicate.html
│   │       │       │   │   ├── Sets.html
│   │       │       │   │   ├── Supplier.html
│   │       │       │   │   ├── Suppliers.html
│   │       │       │   │   ├── Throwables.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── lifecycle/
│   │       │       │   │   ├── AttachDetachListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── logging/
│   │       │       │   │   ├── FLog.html
│   │       │       │   │   ├── FLogDefaultLoggingDelegate.html
│   │       │       │   │   ├── LoggingDelegate.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── media/
│   │       │       │   │   ├── MediaUtils.html
│   │       │       │   │   ├── MimeTypeMapWrapper.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── memory/
│   │       │       │   │   ├── ByteArrayPool.html
│   │       │       │   │   ├── MemoryTrimType.html
│   │       │       │   │   ├── MemoryTrimmable.html
│   │       │       │   │   ├── MemoryTrimmableRegistry.html
│   │       │       │   │   ├── NoOpMemoryTrimmableRegistry.html
│   │       │       │   │   ├── Pool.html
│   │       │       │   │   ├── PooledByteArrayBufferedInputStream.html
│   │       │       │   │   ├── PooledByteBuffer.ClosedException.html
│   │       │       │   │   ├── PooledByteBuffer.html
│   │       │       │   │   ├── PooledByteBufferFactory.html
│   │       │       │   │   ├── PooledByteBufferInputStream.html
│   │       │       │   │   ├── PooledByteBufferOutputStream.html
│   │       │       │   │   ├── PooledByteStreams.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── references/
│   │       │       │   │   ├── CloseableReference.CloseableRefType.html
│   │       │       │   │   ├── CloseableReference.LeakHandler.html
│   │       │       │   │   ├── CloseableReference.html
│   │       │       │   │   ├── DefaultCloseableReference.html
│   │       │       │   │   ├── FinalizerCloseableReference.html
│   │       │       │   │   ├── HasBitmap.html
│   │       │       │   │   ├── NoOpCloseableReference.html
│   │       │       │   │   ├── OOMSoftReference.html
│   │       │       │   │   ├── RefCountCloseableReference.html
│   │       │       │   │   ├── ResourceReleaser.html
│   │       │       │   │   ├── SharedReference.NullReferenceException.html
│   │       │       │   │   ├── SharedReference.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── statfs/
│   │       │       │   │   ├── StatFsHelper.StorageType.html
│   │       │       │   │   ├── StatFsHelper.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── streams/
│   │       │       │   │   ├── LimitedInputStream.html
│   │       │       │   │   ├── TailAppendingInputStream.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── time/
│   │       │       │   │   ├── AwakeTimeSinceBootClock.html
│   │       │       │   │   ├── Clock.html
│   │       │       │   │   ├── CurrentThreadTimeClock.html
│   │       │       │   │   ├── MonotonicClock.html
│   │       │       │   │   ├── MonotonicNanoClock.html
│   │       │       │   │   ├── RealtimeSinceBootClock.html
│   │       │       │   │   ├── SystemClock.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── util/
│   │       │       │   │   ├── ByteConstants.html
│   │       │       │   │   ├── ExceptionWithNoStacktrace.html
│   │       │       │   │   ├── HashCodeUtil.html
│   │       │       │   │   ├── Hex.html
│   │       │       │   │   ├── SecureHashUtil.html
│   │       │       │   │   ├── StreamUtil.html
│   │       │       │   │   ├── TriState.html
│   │       │       │   │   ├── UriUtil.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── webp/
│   │       │       │       ├── BitmapCreator.html
│   │       │       │       ├── WebpBitmapFactory.WebpErrorLogger.html
│   │       │       │       ├── WebpBitmapFactory.html
│   │       │       │       ├── WebpSupportStatus.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── datasource/
│   │       │       │   ├── AbstractDataSource.DataSourceInstrumenter.html
│   │       │       │   ├── AbstractDataSource.html
│   │       │       │   ├── BaseBooleanSubscriber.html
│   │       │       │   ├── BaseDataSubscriber.html
│   │       │       │   ├── DataSource.html
│   │       │       │   ├── DataSources.html
│   │       │       │   ├── DataSubscriber.html
│   │       │       │   ├── FirstAvailableDataSourceSupplier.html
│   │       │       │   ├── IncreasingQualityDataSourceSupplier.html
│   │       │       │   ├── RetainingDataSourceSupplier.html
│   │       │       │   ├── SimpleDataSource.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── drawable/
│   │       │       │   └── base/
│   │       │       │       ├── DrawableWithCaches.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── drawee/
│   │       │       │   ├── backends/
│   │       │       │   │   └── pipeline/
│   │       │       │   │       ├── DefaultDrawableFactory.html
│   │       │       │   │       ├── DraweeConfig.Builder.html
│   │       │       │   │       ├── DraweeConfig.html
│   │       │       │   │       ├── Fresco.html
│   │       │       │   │       ├── PipelineDraweeController.html
│   │       │       │   │       ├── PipelineDraweeControllerBuilder.html
│   │       │       │   │       ├── PipelineDraweeControllerBuilderSupplier.html
│   │       │       │   │       ├── PipelineDraweeControllerFactory.html
│   │       │       │   │       ├── debug/
│   │       │       │   │       │   ├── DebugOverlayImageOriginColor.html
│   │       │       │   │       │   ├── DebugOverlayImageOriginListener.html
│   │       │       │   │       │   ├── package-descr.html
│   │       │       │   │       │   └── package-summary.html
│   │       │       │   │       ├── info/
│   │       │       │   │       │   ├── ForwardingImageOriginListener.html
│   │       │       │   │       │   ├── ForwardingImagePerfDataListener.html
│   │       │       │   │       │   ├── ImageLoadStatus.html
│   │       │       │   │       │   ├── ImageOrigin.html
│   │       │       │   │       │   ├── ImageOriginListener.html
│   │       │       │   │       │   ├── ImageOriginRequestListener.html
│   │       │       │   │       │   ├── ImageOriginUtils.html
│   │       │       │   │       │   ├── ImagePerfData.html
│   │       │       │   │       │   ├── ImagePerfDataListener.html
│   │       │       │   │       │   ├── ImagePerfMonitor.html
│   │       │       │   │       │   ├── ImagePerfNotifier.html
│   │       │       │   │       │   ├── ImagePerfState.html
│   │       │       │   │       │   ├── ImagePerfUtils.html
│   │       │       │   │       │   ├── VisibilityState.html
│   │       │       │   │       │   ├── internal/
│   │       │       │   │       │   │   ├── ImagePerfControllerListener.html
│   │       │       │   │       │   │   ├── ImagePerfControllerListener2.html
│   │       │       │   │       │   │   ├── ImagePerfImageOriginListener.html
│   │       │       │   │       │   │   ├── ImagePerfRequestListener.html
│   │       │       │   │       │   │   ├── package-descr.html
│   │       │       │   │       │   │   └── package-summary.html
│   │       │       │   │       │   ├── package-descr.html
│   │       │       │   │       │   └── package-summary.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── components/
│   │       │       │   │   ├── DeferredReleaser.Releasable.html
│   │       │       │   │   ├── DeferredReleaser.html
│   │       │       │   │   ├── DraweeEventTracker.Event.html
│   │       │       │   │   ├── DraweeEventTracker.html
│   │       │       │   │   ├── RetryManager.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── controller/
│   │       │       │   │   ├── AbstractDraweeController.html
│   │       │       │   │   ├── AbstractDraweeControllerBuilder.CacheLevel.html
│   │       │       │   │   ├── AbstractDraweeControllerBuilder.html
│   │       │       │   │   ├── BaseControllerListener.html
│   │       │       │   │   ├── ControllerListener.html
│   │       │       │   │   ├── ControllerViewportVisibilityListener.html
│   │       │       │   │   ├── ForwardingControllerListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── debug/
│   │       │       │   │   ├── DebugControllerOverlayDrawable.html
│   │       │       │   │   ├── listener/
│   │       │       │   │   │   ├── ImageLoadingTimeControllerListener.html
│   │       │       │   │   │   ├── ImageLoadingTimeListener.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── drawable/
│   │       │       │   │   ├── ArrayDrawable.html
│   │       │       │   │   ├── AutoRotateDrawable.html
│   │       │       │   │   ├── CloneableDrawable.html
│   │       │       │   │   ├── DrawableParent.html
│   │       │       │   │   ├── DrawableProperties.html
│   │       │       │   │   ├── DrawableUtils.html
│   │       │       │   │   ├── FadeDrawable.OnFadeListener.html
│   │       │       │   │   ├── FadeDrawable.html
│   │       │       │   │   ├── ForwardingDrawable.html
│   │       │       │   │   ├── InstrumentedDrawable.Listener.html
│   │       │       │   │   ├── InstrumentedDrawable.html
│   │       │       │   │   ├── MatrixDrawable.html
│   │       │       │   │   ├── OrientedDrawable.html
│   │       │       │   │   ├── ProgressBarDrawable.html
│   │       │       │   │   ├── Rounded.html
│   │       │       │   │   ├── RoundedBitmapDrawable.html
│   │       │       │   │   ├── RoundedColorDrawable.html
│   │       │       │   │   ├── RoundedCornersDrawable.Type.html
│   │       │       │   │   ├── RoundedCornersDrawable.html
│   │       │       │   │   ├── RoundedDrawable.html
│   │       │       │   │   ├── RoundedNinePatchDrawable.html
│   │       │       │   │   ├── ScaleTypeDrawable.html
│   │       │       │   │   ├── ScalingUtils.AbstractScaleType.html
│   │       │       │   │   ├── ScalingUtils.InterpolatingScaleType.html
│   │       │       │   │   ├── ScalingUtils.ScaleType.html
│   │       │       │   │   ├── ScalingUtils.StatefulScaleType.html
│   │       │       │   │   ├── ScalingUtils.html
│   │       │       │   │   ├── TransformAwareDrawable.html
│   │       │       │   │   ├── TransformCallback.html
│   │       │       │   │   ├── VisibilityAwareDrawable.html
│   │       │       │   │   ├── VisibilityCallback.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── generic/
│   │       │       │   │   ├── GenericDraweeHierarchy.html
│   │       │       │   │   ├── GenericDraweeHierarchyBuilder.html
│   │       │       │   │   ├── GenericDraweeHierarchyInflater.html
│   │       │       │   │   ├── RootDrawable.html
│   │       │       │   │   ├── RoundingParams.RoundingMethod.html
│   │       │       │   │   ├── RoundingParams.html
│   │       │       │   │   ├── WrappingUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── gestures/
│   │       │       │   │   ├── GestureDetector.ClickListener.html
│   │       │       │   │   ├── GestureDetector.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── interfaces/
│   │       │       │   │   ├── DraweeController.html
│   │       │       │   │   ├── DraweeHierarchy.html
│   │       │       │   │   ├── SettableDraweeHierarchy.html
│   │       │       │   │   ├── SimpleDraweeControllerBuilder.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── span/
│   │       │       │   │   ├── DraweeSpan.html
│   │       │       │   │   ├── DraweeSpanStringBuilder.DraweeSpanChangedListener.html
│   │       │       │   │   ├── DraweeSpanStringBuilder.html
│   │       │       │   │   ├── SimpleDraweeSpanTextView.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── view/
│   │       │       │       ├── AspectRatioMeasure.Spec.html
│   │       │       │       ├── AspectRatioMeasure.html
│   │       │       │       ├── DraweeHolder.html
│   │       │       │       ├── DraweeTransition.html
│   │       │       │       ├── DraweeView.html
│   │       │       │       ├── GenericDraweeView.html
│   │       │       │       ├── MultiDraweeHolder.html
│   │       │       │       ├── SimpleDraweeView.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── fresco/
│   │       │       │   ├── animation/
│   │       │       │   │   ├── backend/
│   │       │       │   │   │   ├── AnimationBackend.html
│   │       │       │   │   │   ├── AnimationBackendDelegate.html
│   │       │       │   │   │   ├── AnimationBackendDelegateWithInactivityCheck.InactivityListener.html
│   │       │       │   │   │   ├── AnimationBackendDelegateWithInactivityCheck.html
│   │       │       │   │   │   ├── AnimationInformation.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── bitmap/
│   │       │       │   │   │   ├── BitmapAnimationBackend.FrameListener.html
│   │       │       │   │   │   ├── BitmapAnimationBackend.FrameType.html
│   │       │       │   │   │   ├── BitmapAnimationBackend.html
│   │       │       │   │   │   ├── BitmapFrameCache.FrameCacheListener.html
│   │       │       │   │   │   ├── BitmapFrameCache.html
│   │       │       │   │   │   ├── BitmapFrameRenderer.html
│   │       │       │   │   │   ├── cache/
│   │       │       │   │   │   │   ├── AnimationFrameCacheKey.html
│   │       │       │   │   │   │   ├── FrescoFrameCache.html
│   │       │       │   │   │   │   ├── KeepLastFrameCache.html
│   │       │       │   │   │   │   ├── NoOpCache.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   ├── package-summary.html
│   │       │       │   │   │   ├── preparation/
│   │       │       │   │   │   │   ├── BitmapFramePreparationStrategy.html
│   │       │       │   │   │   │   ├── BitmapFramePreparer.html
│   │       │       │   │   │   │   ├── DefaultBitmapFramePreparer.html
│   │       │       │   │   │   │   ├── FixedNumberBitmapFramePreparationStrategy.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   └── wrapper/
│   │       │       │   │   │       ├── AnimatedDrawableBackendAnimationInformation.html
│   │       │       │   │   │       ├── AnimatedDrawableBackendFrameRenderer.html
│   │       │       │   │   │       ├── package-descr.html
│   │       │       │   │   │       └── package-summary.html
│   │       │       │   │   ├── drawable/
│   │       │       │   │   │   ├── AnimatedDrawable2.DrawListener.html
│   │       │       │   │   │   ├── AnimatedDrawable2.html
│   │       │       │   │   │   ├── AnimatedDrawable2DebugDrawListener.html
│   │       │       │   │   │   ├── AnimationListener.html
│   │       │       │   │   │   ├── BaseAnimationListener.html
│   │       │       │   │   │   ├── animator/
│   │       │       │   │   │   │   ├── AnimatedDrawable2ValueAnimatorHelper.html
│   │       │       │   │   │   │   ├── AnimatedDrawableValueAnimatorHelper.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── factory/
│   │       │       │   │   │   ├── AnimatedFactoryV2Impl.html
│   │       │       │   │   │   ├── ExperimentalBitmapAnimationDrawableFactory.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── frame/
│   │       │       │   │       ├── DropFramesFrameScheduler.html
│   │       │       │   │       ├── FrameScheduler.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── middleware/
│   │       │       │   │   ├── MiddlewareUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── ui/
│   │       │       │       └── common/
│   │       │       │           ├── BaseControllerListener2.html
│   │       │       │           ├── ControllerListener2.Extras.html
│   │       │       │           ├── ControllerListener2.html
│   │       │       │           ├── DimensionsInfo.html
│   │       │       │           ├── ForwardingControllerListener2.html
│   │       │       │           ├── LoggingListener.html
│   │       │       │           ├── MultiUriHelper.html
│   │       │       │           ├── OnDrawControllerListener.html
│   │       │       │           ├── package-descr.html
│   │       │       │           └── package-summary.html
│   │       │       ├── imageformat/
│   │       │       │   ├── DefaultImageFormatChecker.html
│   │       │       │   ├── DefaultImageFormats.html
│   │       │       │   ├── ImageFormat.FormatChecker.html
│   │       │       │   ├── ImageFormat.html
│   │       │       │   ├── ImageFormatChecker.html
│   │       │       │   ├── ImageFormatCheckerUtils.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── imagepipeline/
│   │       │       │   ├── animated/
│   │       │       │   │   ├── base/
│   │       │       │   │   │   ├── AnimatedDrawableBackend.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.BlendOperation.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.DisposalMethod.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.html
│   │       │       │   │   │   ├── AnimatedDrawableOptions.html
│   │       │       │   │   │   ├── AnimatedDrawableOptionsBuilder.html
│   │       │       │   │   │   ├── AnimatedImage.html
│   │       │       │   │   │   ├── AnimatedImageFrame.html
│   │       │       │   │   │   ├── AnimatedImageResult.html
│   │       │       │   │   │   ├── AnimatedImageResultBuilder.html
│   │       │       │   │   │   ├── DelegatingAnimatedDrawableBackend.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── factory/
│   │       │       │   │   │   ├── AnimatedFactory.html
│   │       │       │   │   │   ├── AnimatedFactoryProvider.html
│   │       │       │   │   │   ├── AnimatedImageDecoder.html
│   │       │       │   │   │   ├── AnimatedImageFactory.html
│   │       │       │   │   │   ├── AnimatedImageFactoryImpl.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── impl/
│   │       │       │   │   │   ├── AnimatedDrawableBackendImpl.html
│   │       │       │   │   │   ├── AnimatedDrawableBackendProvider.html
│   │       │       │   │   │   ├── AnimatedFrameCache.html
│   │       │       │   │   │   ├── AnimatedImageCompositor.Callback.html
│   │       │       │   │   │   ├── AnimatedImageCompositor.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── util/
│   │       │       │   │       ├── AnimatedDrawableUtil.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── backends/
│   │       │       │   │   ├── okhttp3/
│   │       │       │   │   │   ├── OkHttpImagePipelineConfigFactory.html
│   │       │       │   │   │   ├── OkHttpNetworkFetcher.OkHttpNetworkFetchState.html
│   │       │       │   │   │   ├── OkHttpNetworkFetcher.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── volley/
│   │       │       │   │       ├── RawRequest.html
│   │       │       │   │       ├── VolleyImagePipelineConfigFactory.html
│   │       │       │   │       ├── VolleyNetworkFetcher.VolleyNetworkFetchState.html
│   │       │       │   │       ├── VolleyNetworkFetcher.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── bitmaps/
│   │       │       │   │   ├── ArtBitmapFactory.html
│   │       │       │   │   ├── EmptyJpegGenerator.html
│   │       │       │   │   ├── GingerbreadBitmapFactory.html
│   │       │       │   │   ├── HoneycombBitmapCreator.html
│   │       │       │   │   ├── HoneycombBitmapFactory.html
│   │       │       │   │   ├── PlatformBitmapFactory.html
│   │       │       │   │   ├── PlatformBitmapFactoryProvider.html
│   │       │       │   │   ├── SimpleBitmapReleaser.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── cache/
│   │       │       │   │   ├── AbstractAdaptiveCountingMemoryCache.html
│   │       │       │   │   ├── BitmapMemoryCacheFactory.html
│   │       │       │   │   ├── BitmapMemoryCacheKey.html
│   │       │       │   │   ├── BitmapMemoryCacheTrimStrategy.html
│   │       │       │   │   ├── BoundedLinkedHashSet.html
│   │       │       │   │   ├── BufferedDiskCache.html
│   │       │       │   │   ├── CacheKeyFactory.html
│   │       │       │   │   ├── CountingLruBitmapMemoryCacheFactory.html
│   │       │       │   │   ├── CountingLruMap.html
│   │       │       │   │   ├── CountingMemoryCache.Entry.html
│   │       │       │   │   ├── CountingMemoryCache.EntryStateObserver.html
│   │       │       │   │   ├── CountingMemoryCache.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.DumpInfo.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.DumpInfoEntry.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.html
│   │       │       │   │   ├── DefaultBitmapMemoryCacheParamsSupplier.html
│   │       │       │   │   ├── DefaultCacheKeyFactory.html
│   │       │       │   │   ├── DefaultEncodedMemoryCacheParamsSupplier.html
│   │       │       │   │   ├── EncodedCountingMemoryCacheFactory.html
│   │       │       │   │   ├── EncodedMemoryCacheFactory.html
│   │       │       │   │   ├── ImageCacheStatsTracker.html
│   │       │       │   │   ├── InstrumentedMemoryCache.html
│   │       │       │   │   ├── InstrumentedMemoryCacheBitmapMemoryCacheFactory.html
│   │       │       │   │   ├── LruCountingMemoryCache.html
│   │       │       │   │   ├── MemoryCache.CacheTrimStrategy.html
│   │       │       │   │   ├── MemoryCache.html
│   │       │       │   │   ├── MemoryCacheParams.html
│   │       │       │   │   ├── MemoryCacheTracker.html
│   │       │       │   │   ├── NativeMemoryCacheTrimStrategy.html
│   │       │       │   │   ├── NoOpImageCacheStatsTracker.html
│   │       │       │   │   ├── StagingArea.html
│   │       │       │   │   ├── ValueDescriptor.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── common/
│   │       │       │   │   ├── BytesRange.html
│   │       │       │   │   ├── ImageDecodeOptions.html
│   │       │       │   │   ├── ImageDecodeOptionsBuilder.html
│   │       │       │   │   ├── Priority.html
│   │       │       │   │   ├── ResizeOptions.html
│   │       │       │   │   ├── RotationOptions.RotationAngle.html
│   │       │       │   │   ├── RotationOptions.html
│   │       │       │   │   ├── SourceUriType.html
│   │       │       │   │   ├── TooManyBitmapsException.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── core/
│   │       │       │   │   ├── CloseableReferenceFactory.html
│   │       │       │   │   ├── DefaultExecutorSupplier.html
│   │       │       │   │   ├── DiskStorageCacheFactory.html
│   │       │       │   │   ├── DiskStorageFactory.html
│   │       │       │   │   ├── DynamicDefaultDiskStorageFactory.html
│   │       │       │   │   ├── ExecutorSupplier.html
│   │       │       │   │   ├── FileCacheFactory.html
│   │       │       │   │   ├── ImagePipeline.html
│   │       │       │   │   ├── ImagePipelineConfig.Builder.html
│   │       │       │   │   ├── ImagePipelineConfig.DefaultImageRequestConfig.html
│   │       │       │   │   ├── ImagePipelineConfig.html
│   │       │       │   │   ├── ImagePipelineExperiments.Builder.html
│   │       │       │   │   ├── ImagePipelineExperiments.DefaultProducerFactoryMethod.html
│   │       │       │   │   ├── ImagePipelineExperiments.ProducerFactoryMethod.html
│   │       │       │   │   ├── ImagePipelineExperiments.html
│   │       │       │   │   ├── ImagePipelineFactory.html
│   │       │       │   │   ├── ImageTranscoderType.html
│   │       │       │   │   ├── MemoryChunkType.html
│   │       │       │   │   ├── NativeCodeSetup.html
│   │       │       │   │   ├── PriorityThreadFactory.html
│   │       │       │   │   ├── ProducerFactory.html
│   │       │       │   │   ├── ProducerSequenceFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── datasource/
│   │       │       │   │   ├── AbstractProducerToDataSourceAdapter.html
│   │       │       │   │   ├── BaseBitmapDataSubscriber.html
│   │       │       │   │   ├── BaseBitmapReferenceDataSubscriber.html
│   │       │       │   │   ├── BaseListBitmapDataSubscriber.html
│   │       │       │   │   ├── CloseableProducerToDataSourceAdapter.html
│   │       │       │   │   ├── ListDataSource.html
│   │       │       │   │   ├── ProducerToDataSourceAdapter.html
│   │       │       │   │   ├── SettableDataSource.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── debug/
│   │       │       │   │   ├── CloseableReferenceLeakTracker.Listener.html
│   │       │       │   │   ├── CloseableReferenceLeakTracker.html
│   │       │       │   │   ├── DebugImageTracker.html
│   │       │       │   │   ├── FlipperCacheKeyFactory.html
│   │       │       │   │   ├── FlipperCloseableReferenceLeakTracker.html
│   │       │       │   │   ├── FlipperImageTracker.ImageDebugData.html
│   │       │       │   │   ├── FlipperImageTracker.html
│   │       │       │   │   ├── LruMap.html
│   │       │       │   │   ├── NoOpCloseableReferenceLeakTracker.html
│   │       │       │   │   ├── NoOpDebugImageTracker.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── decoder/
│   │       │       │   │   ├── DecodeException.html
│   │       │       │   │   ├── DefaultImageDecoder.html
│   │       │       │   │   ├── ImageDecoder.html
│   │       │       │   │   ├── ImageDecoderConfig.Builder.html
│   │       │       │   │   ├── ImageDecoderConfig.html
│   │       │       │   │   ├── ProgressiveJpegConfig.html
│   │       │       │   │   ├── ProgressiveJpegParser.html
│   │       │       │   │   ├── SimpleProgressiveJpegConfig.DynamicValueConfig.html
│   │       │       │   │   ├── SimpleProgressiveJpegConfig.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── drawable/
│   │       │       │   │   ├── DrawableFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── filter/
│   │       │       │   │   ├── InPlaceRoundFilter.html
│   │       │       │   │   ├── IterativeBoxBlurFilter.html
│   │       │       │   │   ├── RenderScriptBlurFilter.html
│   │       │       │   │   ├── XferRoundFilter.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── image/
│   │       │       │   │   ├── CloseableAnimatedImage.html
│   │       │       │   │   ├── CloseableBitmap.html
│   │       │       │   │   ├── CloseableImage.html
│   │       │       │   │   ├── CloseableStaticBitmap.html
│   │       │       │   │   ├── EncodedImage.html
│   │       │       │   │   ├── EncodedImageOrigin.html
│   │       │       │   │   ├── HasImageMetadata.html
│   │       │       │   │   ├── ImageInfo.html
│   │       │       │   │   ├── ImmutableQualityInfo.html
│   │       │       │   │   ├── OriginalEncodedImageInfo.html
│   │       │       │   │   ├── QualityInfo.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── instrumentation/
│   │       │       │   │   ├── FrescoInstrumenter.Instrumenter.html
│   │       │       │   │   ├── FrescoInstrumenter.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── listener/
│   │       │       │   │   ├── BaseRequestListener.html
│   │       │       │   │   ├── BaseRequestListener2.html
│   │       │       │   │   ├── ForwardingRequestListener.html
│   │       │       │   │   ├── ForwardingRequestListener2.html
│   │       │       │   │   ├── RequestListener.html
│   │       │       │   │   ├── RequestListener2.html
│   │       │       │   │   ├── RequestLoggingListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── memory/
│   │       │       │   │   ├── AshmemMemoryChunk.html
│   │       │       │   │   ├── AshmemMemoryChunkPool.html
│   │       │       │   │   ├── BasePool.InvalidSizeException.html
│   │       │       │   │   ├── BasePool.InvalidValueException.html
│   │       │       │   │   ├── BasePool.PoolSizeViolationException.html
│   │       │       │   │   ├── BasePool.SizeTooLargeException.html
│   │       │       │   │   ├── BasePool.html
│   │       │       │   │   ├── BitmapCounter.html
│   │       │       │   │   ├── BitmapCounterConfig.Builder.html
│   │       │       │   │   ├── BitmapCounterConfig.html
│   │       │       │   │   ├── BitmapCounterProvider.html
│   │       │       │   │   ├── BitmapPool.html
│   │       │       │   │   ├── BitmapPoolBackend.html
│   │       │       │   │   ├── BitmapPoolType.html
│   │       │       │   │   ├── BucketMap.html
│   │       │       │   │   ├── BucketsBitmapPool.html
│   │       │       │   │   ├── BufferMemoryChunk.html
│   │       │       │   │   ├── BufferMemoryChunkPool.html
│   │       │       │   │   ├── DefaultBitmapPoolParams.html
│   │       │       │   │   ├── DefaultByteArrayPoolParams.html
│   │       │       │   │   ├── DefaultFlexByteArrayPoolParams.html
│   │       │       │   │   ├── DefaultNativeMemoryChunkPoolParams.html
│   │       │       │   │   ├── DummyBitmapPool.html
│   │       │       │   │   ├── DummyTrackingInUseBitmapPool.html
│   │       │       │   │   ├── FlexByteArrayPool.html
│   │       │       │   │   ├── GenericByteArrayPool.html
│   │       │       │   │   ├── LruBitmapPool.html
│   │       │       │   │   ├── LruBucketsPoolBackend.html
│   │       │       │   │   ├── MemoryChunk.html
│   │       │       │   │   ├── MemoryChunkPool.html
│   │       │       │   │   ├── MemoryChunkUtil.html
│   │       │       │   │   ├── MemoryPooledByteBuffer.html
│   │       │       │   │   ├── MemoryPooledByteBufferFactory.html
│   │       │       │   │   ├── MemoryPooledByteBufferOutputStream.InvalidStreamException.html
│   │       │       │   │   ├── MemoryPooledByteBufferOutputStream.html
│   │       │       │   │   ├── NativeMemoryChunk.html
│   │       │       │   │   ├── NativeMemoryChunkPool.html
│   │       │       │   │   ├── NoOpPoolStatsTracker.html
│   │       │       │   │   ├── PoolConfig.Builder.html
│   │       │       │   │   ├── PoolConfig.html
│   │       │       │   │   ├── PoolFactory.html
│   │       │       │   │   ├── PoolParams.html
│   │       │       │   │   ├── PoolStatsTracker.html
│   │       │       │   │   ├── SharedByteArray.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── multiuri/
│   │       │       │   │   ├── MultiUri.Builder.html
│   │       │       │   │   ├── MultiUri.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── nativecode/
│   │       │       │   │   ├── Bitmaps.html
│   │       │       │   │   ├── DalvikPurgeableDecoder.html
│   │       │       │   │   ├── ImagePipelineNativeLoader.html
│   │       │       │   │   ├── NativeBlurFilter.html
│   │       │       │   │   ├── NativeCodeInitializer.html
│   │       │       │   │   ├── NativeFiltersLoader.html
│   │       │       │   │   ├── NativeImageTranscoderFactory.html
│   │       │       │   │   ├── NativeJpegTranscoder.html
│   │       │       │   │   ├── NativeJpegTranscoderFactory.html
│   │       │       │   │   ├── NativeJpegTranscoderSoLoader.html
│   │       │       │   │   ├── NativeRoundingFilter.html
│   │       │       │   │   ├── StaticWebpNativeLoader.html
│   │       │       │   │   ├── WebpTranscoder.html
│   │       │       │   │   ├── WebpTranscoderFactory.html
│   │       │       │   │   ├── WebpTranscoderImpl.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── platform/
│   │       │       │   │   ├── ArtDecoder.html
│   │       │       │   │   ├── DefaultDecoder.html
│   │       │       │   │   ├── GingerbreadPurgeableDecoder.html
│   │       │       │   │   ├── KitKatPurgeableDecoder.html
│   │       │       │   │   ├── OreoDecoder.html
│   │       │       │   │   ├── PlatformDecoder.html
│   │       │       │   │   ├── PlatformDecoderFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── postprocessors/
│   │       │       │   │   ├── BlurPostProcessor.html
│   │       │       │   │   ├── IterativeBoxBlurPostProcessor.html
│   │       │       │   │   ├── RoundAsCirclePostprocessor.html
│   │       │       │   │   ├── RoundPostprocessor.html
│   │       │       │   │   ├── RoundedCornersPostprocessor.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── producers/
│   │       │       │   │   ├── AddImageTransformMetaDataProducer.html
│   │       │       │   │   ├── BaseConsumer.html
│   │       │       │   │   ├── BaseNetworkFetcher.html
│   │       │       │   │   ├── BaseProducerContext.html
│   │       │       │   │   ├── BaseProducerContextCallbacks.html
│   │       │       │   │   ├── BitmapMemoryCacheGetProducer.html
│   │       │       │   │   ├── BitmapMemoryCacheKeyMultiplexProducer.html
│   │       │       │   │   ├── BitmapMemoryCacheProducer.html
│   │       │       │   │   ├── BitmapPrepareProducer.html
│   │       │       │   │   ├── BitmapProbeProducer.html
│   │       │       │   │   ├── BranchOnSeparateImagesProducer.html
│   │       │       │   │   ├── Consumer.Status.html
│   │       │       │   │   ├── Consumer.html
│   │       │       │   │   ├── DataFetchProducer.html
│   │       │       │   │   ├── DecodeProducer.html
│   │       │       │   │   ├── DelayProducer.html
│   │       │       │   │   ├── DelegatingConsumer.html
│   │       │       │   │   ├── DiskCacheReadProducer.html
│   │       │       │   │   ├── DiskCacheWriteProducer.html
│   │       │       │   │   ├── EncodedCacheKeyMultiplexProducer.html
│   │       │       │   │   ├── EncodedMemoryCacheProducer.html
│   │       │       │   │   ├── EncodedProbeProducer.html
│   │       │       │   │   ├── ExperimentalThreadHandoffProducerQueueImpl.html
│   │       │       │   │   ├── FetchState.html
│   │       │       │   │   ├── HttpUrlConnectionNetworkFetcher.HttpUrlConnectionNetworkFetchState.html
│   │       │       │   │   ├── HttpUrlConnectionNetworkFetcher.html
│   │       │       │   │   ├── InternalProducerListener.html
│   │       │       │   │   ├── InternalRequestListener.html
│   │       │       │   │   ├── JobScheduler.JobRunnable.html
│   │       │       │   │   ├── JobScheduler.html
│   │       │       │   │   ├── LocalAssetFetchProducer.html
│   │       │       │   │   ├── LocalContentUriFetchProducer.html
│   │       │       │   │   ├── LocalContentUriThumbnailFetchProducer.html
│   │       │       │   │   ├── LocalExifThumbnailProducer.html
│   │       │       │   │   ├── LocalFetchProducer.html
│   │       │       │   │   ├── LocalFileFetchProducer.html
│   │       │       │   │   ├── LocalResourceFetchProducer.html
│   │       │       │   │   ├── LocalVideoThumbnailProducer.html
│   │       │       │   │   ├── MultiplexProducer.html
│   │       │       │   │   ├── NetworkFetchProducer.html
│   │       │       │   │   ├── NetworkFetcher.Callback.html
│   │       │       │   │   ├── NetworkFetcher.html
│   │       │       │   │   ├── NullProducer.html
│   │       │       │   │   ├── PartialDiskCacheProducer.html
│   │       │       │   │   ├── PostprocessedBitmapMemoryCacheProducer.CachedPostprocessorConsumer.html
│   │       │       │   │   ├── PostprocessedBitmapMemoryCacheProducer.html
│   │       │       │   │   ├── PostprocessorProducer.html
│   │       │       │   │   ├── PriorityNetworkFetcher.NonrecoverableException.html
│   │       │       │   │   ├── PriorityNetworkFetcher.PriorityFetchState.html
│   │       │       │   │   ├── PriorityNetworkFetcher.html
│   │       │       │   │   ├── PriorityStarvingThrottlingProducer.html
│   │       │       │   │   ├── Producer.html
│   │       │       │   │   ├── ProducerContext.ExtraKeys.html
│   │       │       │   │   ├── ProducerContext.html
│   │       │       │   │   ├── ProducerContextCallbacks.html
│   │       │       │   │   ├── ProducerListener.html
│   │       │       │   │   ├── ProducerListener2.html
│   │       │       │   │   ├── QualifiedResourceFetchProducer.html
│   │       │       │   │   ├── RemoveImageTransformMetaDataProducer.html
│   │       │       │   │   ├── ResizeAndRotateProducer.html
│   │       │       │   │   ├── SettableProducerContext.html
│   │       │       │   │   ├── StatefulProducerRunnable.html
│   │       │       │   │   ├── SwallowResultProducer.html
│   │       │       │   │   ├── ThreadHandoffProducer.html
│   │       │       │   │   ├── ThreadHandoffProducerQueue.html
│   │       │       │   │   ├── ThreadHandoffProducerQueueImpl.html
│   │       │       │   │   ├── ThrottlingProducer.html
│   │       │       │   │   ├── ThumbnailBranchProducer.html
│   │       │       │   │   ├── ThumbnailProducer.html
│   │       │       │   │   ├── ThumbnailSizeChecker.html
│   │       │       │   │   ├── WebpTranscodeProducer.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── request/
│   │       │       │   │   ├── BasePostprocessor.html
│   │       │       │   │   ├── BaseRepeatedPostProcessor.html
│   │       │       │   │   ├── HasImageRequest.html
│   │       │       │   │   ├── ImageRequest.CacheChoice.html
│   │       │       │   │   ├── ImageRequest.RequestLevel.html
│   │       │       │   │   ├── ImageRequest.html
│   │       │       │   │   ├── ImageRequestBuilder.BuilderException.html
│   │       │       │   │   ├── ImageRequestBuilder.html
│   │       │       │   │   ├── Postprocessor.html
│   │       │       │   │   ├── RepeatedPostprocessor.html
│   │       │       │   │   ├── RepeatedPostprocessorRunner.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── systrace/
│   │       │       │   │   ├── DefaultFrescoSystrace.html
│   │       │       │   │   ├── FrescoSystrace.ArgsBuilder.html
│   │       │       │   │   ├── FrescoSystrace.Systrace.html
│   │       │       │   │   ├── FrescoSystrace.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── transcoder/
│   │       │       │   │   ├── DownsampleUtil.html
│   │       │       │   │   ├── ImageTranscodeResult.html
│   │       │       │   │   ├── ImageTranscoder.html
│   │       │       │   │   ├── ImageTranscoderFactory.html
│   │       │       │   │   ├── JpegTranscoderUtils.html
│   │       │       │   │   ├── MultiImageTranscoderFactory.html
│   │       │       │   │   ├── SimpleImageTranscoder.html
│   │       │       │   │   ├── SimpleImageTranscoderFactory.html
│   │       │       │   │   ├── TranscodeStatus.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── transformation/
│   │       │       │       ├── BitmapTransformation.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── imageutils/
│   │       │       │   ├── BitmapUtil.html
│   │       │       │   ├── HeifExifUtil.html
│   │       │       │   ├── ImageMetaData.html
│   │       │       │   ├── JfifUtil.html
│   │       │       │   ├── WebpUtil.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── webpsupport/
│   │       │       │   ├── WebpBitmapFactoryImpl.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       └── widget/
│   │       │           └── text/
│   │       │               └── span/
│   │       │                   ├── BetterImageSpan.BetterImageSpanAlignment.html
│   │       │                   ├── BetterImageSpan.html
│   │       │                   ├── package-descr.html
│   │       │                   └── package-summary.html
│   │       ├── current.xml
│   │       ├── hierarchy.html
│   │       ├── index.html
│   │       ├── lists.js
│   │       ├── package-list
│   │       └── packages.html
│   ├── sample-license.md
│   ├── static/
│   │   ├── JSXTransformer.js
│   │   ├── js/
│   │   │   └── docsearch.js
│   │   ├── linkify.js
│   │   ├── pygments.css
│   │   ├── sample-images/
│   │   │   └── animation.keyframes
│   │   ├── site.css
│   │   └── transformer.js
│   └── support.md
├── drawee/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── facebook/
│       │   │           └── drawee/
│       │   │               ├── components/
│       │   │               │   ├── DeferredReleaser.java
│       │   │               │   ├── DeferredReleaserConcurrentImpl.java
│       │   │               │   ├── DraweeEventTracker.java
│       │   │               │   └── RetryManager.java
│       │   │               ├── controller/
│       │   │               │   ├── AbstractDraweeController.java
│       │   │               │   ├── AbstractDraweeControllerBuilder.java
│       │   │               │   ├── BaseControllerListener.java
│       │   │               │   ├── ControllerListener.java
│       │   │               │   ├── ControllerViewportVisibilityListener.java
│       │   │               │   ├── ForwardingControllerListener.java
│       │   │               │   └── package-info.java
│       │   │               ├── debug/
│       │   │               │   ├── DebugControllerOverlayDrawable.java
│       │   │               │   └── listener/
│       │   │               │       ├── ImageLoadingTimeControllerListener.kt
│       │   │               │       └── ImageLoadingTimeListener.kt
│       │   │               ├── drawable/
│       │   │               │   ├── ArrayDrawable.java
│       │   │               │   ├── AutoRotateDrawable.java
│       │   │               │   ├── CloneableDrawable.kt
│       │   │               │   ├── DrawableParent.kt
│       │   │               │   ├── DrawableProperties.kt
│       │   │               │   ├── DrawableUtils.kt
│       │   │               │   ├── FadeDrawable.java
│       │   │               │   ├── ForwardingDrawable.java
│       │   │               │   ├── InstrumentedDrawable.kt
│       │   │               │   ├── MatrixDrawable.java
│       │   │               │   ├── OrientedDrawable.kt
│       │   │               │   ├── ProgressBarDrawable.kt
│       │   │               │   ├── Rounded.kt
│       │   │               │   ├── RoundedBitmapDrawable.java
│       │   │               │   ├── RoundedColorDrawable.java
│       │   │               │   ├── RoundedCornersDrawable.java
│       │   │               │   ├── RoundedDrawable.java
│       │   │               │   ├── RoundedNinePatchDrawable.kt
│       │   │               │   ├── ScaleTypeDrawable.kt
│       │   │               │   ├── TransformAwareDrawable.kt
│       │   │               │   ├── TransformCallback.kt
│       │   │               │   ├── VisibilityAwareDrawable.kt
│       │   │               │   ├── VisibilityCallback.kt
│       │   │               │   └── package-info.kt
│       │   │               ├── generic/
│       │   │               │   ├── GenericDraweeHierarchy.java
│       │   │               │   ├── GenericDraweeHierarchyBuilder.java
│       │   │               │   ├── GenericDraweeHierarchyInflater.java
│       │   │               │   ├── RootDrawable.java
│       │   │               │   ├── RoundingParams.java
│       │   │               │   ├── WrappingUtils.java
│       │   │               │   └── package-info.java
│       │   │               ├── gestures/
│       │   │               │   └── GestureDetector.java
│       │   │               ├── interfaces/
│       │   │               │   ├── DraweeController.java
│       │   │               │   ├── DraweeHierarchy.java
│       │   │               │   ├── SettableDraweeHierarchy.java
│       │   │               │   ├── SimpleDraweeControllerBuilder.java
│       │   │               │   └── package-info.java
│       │   │               └── view/
│       │   │                   ├── AspectRatioMeasure.java
│       │   │                   ├── DraweeHolder.java
│       │   │                   ├── DraweeTransition.java
│       │   │                   ├── DraweeView.java
│       │   │                   ├── GenericDraweeView.java
│       │   │                   ├── MultiDraweeHolder.java
│       │   │                   ├── SimpleDraweeView.java
│       │   │                   └── package-info.java
│       │   └── res/
│       │       └── values/
│       │           └── attrs.xml
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       └── drawee/
│           │   │           ├── components/
│           │   │           │   └── DeferredReleaserStressTest.java
│           │   │           ├── controller/
│           │   │           │   └── AbstractDraweeControllerTest.java
│           │   │           ├── debug/
│           │   │           │   ├── DebugControllerOverlayDrawableInternalTest.java
│           │   │           │   ├── DebugControllerOverlayDrawableTest.java
│           │   │           │   └── DebugControllerOverlayDrawableTestHelper.java
│           │   │           ├── drawable/
│           │   │           │   ├── AndroidGraphicsTestUtils.java
│           │   │           │   ├── ArrayDrawableTest.java
│           │   │           │   ├── DrawableTestUtils.java
│           │   │           │   ├── DrawableUtilsTest.java
│           │   │           │   ├── FadeDrawableAllOnTest.java
│           │   │           │   ├── FadeDrawableOnFadeListenerTest.java
│           │   │           │   ├── FadeDrawableTest.java
│           │   │           │   ├── ForwardingDrawableTest.java
│           │   │           │   ├── MatrixDrawableTest.java
│           │   │           │   ├── OrientedDrawableTest.java
│           │   │           │   ├── RoundedBitmapDrawableTest.java
│           │   │           │   ├── RoundedColorDrawableTest.java
│           │   │           │   ├── RoundedCornersDrawableTest.java
│           │   │           │   ├── ScaleTypeDrawableTest.java
│           │   │           │   ├── ScalingUtilsTest.java
│           │   │           │   └── SettableDrawableTest.java
│           │   │           ├── generic/
│           │   │           │   ├── GenericDraweeHierarchyBuilderTest.java
│           │   │           │   └── RoundingParamsTest.java
│           │   │           ├── testing/
│           │   │           │   ├── DraweeMocks.java
│           │   │           │   └── DraweeMocksTest.java
│           │   │           └── view/
│           │   │               ├── AspectRatioMeasureTest.java
│           │   │               ├── DraweeHolderTest.java
│           │   │               ├── DraweeViewTest.java
│           │   │               └── MultiDraweeHolderTest.java
│           │   └── javax/
│           │       └── microedition/
│           │           └── khronos/
│           │               └── opengles/
│           │                   └── GL.java
│           └── resources/
│               └── org.robolectric.Config.properties
├── drawee-backends/
│   └── drawee-pipeline/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           ├── main/
│           │   ├── AndroidManifest.xml
│           │   └── java/
│           │       └── com/
│           │           └── facebook/
│           │               └── drawee/
│           │                   └── backends/
│           │                       └── pipeline/
│           │                           ├── DefaultDrawableFactory.java
│           │                           ├── DraweeConfig.java
│           │                           ├── Fresco.java
│           │                           ├── PipelineDraweeController.java
│           │                           ├── PipelineDraweeControllerBuilder.java
│           │                           ├── PipelineDraweeControllerBuilderSupplier.java
│           │                           ├── PipelineDraweeControllerFactory.java
│           │                           ├── info/
│           │                           │   ├── ForwardingImageOriginListener.java
│           │                           │   ├── ForwardingImagePerfDataListener.java
│           │                           │   ├── ImageOrigin.kt
│           │                           │   ├── ImageOriginListener.java
│           │                           │   ├── ImageOriginRequestListener.java
│           │                           │   ├── ImageOriginUtils.java
│           │                           │   ├── ImagePerfExtra.kt
│           │                           │   ├── ImagePerfMonitor.java
│           │                           │   └── internal/
│           │                           │       ├── ImagePerfRequestListener.java
│           │                           │       └── ImagePerfStateManager.java
│           │                           └── package-info.java
│           └── test/
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── drawee/
│                               └── backends/
│                                   └── pipeline/
│                                       └── info/
│                                           └── ImagePerfMonitorTest.java
├── drawee-span/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── drawee/
│       │                   └── span/
│       │                       ├── DraweeSpan.java
│       │                       ├── DraweeSpanStringBuilder.java
│       │                       └── SimpleDraweeSpanTextView.java
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── drawee/
│                           └── span/
│                               ├── DraweeSpanStringBuilderTest.java
│                               └── DraweeSpanTest.java
├── fbcore/
│   ├── AndroidManifest.xml
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-fresco.pro
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       ├── com/
│       │       │   └── facebook/
│       │       │       ├── common/
│       │       │       │   ├── activitylistener/
│       │       │       │   │   ├── ActivityListener.java
│       │       │       │   │   ├── ActivityListenerManager.java
│       │       │       │   │   ├── BaseActivityListener.java
│       │       │       │   │   └── ListenableActivity.java
│       │       │       │   ├── callercontext/
│       │       │       │   │   ├── ContextChain.java
│       │       │       │   │   └── ImageAttribution.java
│       │       │       │   ├── closeables/
│       │       │       │   │   └── AutoCleanupDelegate.kt
│       │       │       │   ├── disk/
│       │       │       │   │   ├── DiskTrimmable.kt
│       │       │       │   │   ├── DiskTrimmableRegistry.kt
│       │       │       │   │   ├── NoOpDiskTrimmableRegistry.kt
│       │       │       │   │   └── package-info.kt
│       │       │       │   ├── executors/
│       │       │       │   │   ├── CallerThreadExecutor.java
│       │       │       │   │   ├── ConstrainedExecutorService.java
│       │       │       │   │   ├── DefaultSerialExecutorService.java
│       │       │       │   │   ├── HandlerExecutorService.java
│       │       │       │   │   ├── HandlerExecutorServiceImpl.java
│       │       │       │   │   ├── ScheduledFutureImpl.java
│       │       │       │   │   ├── SerialExecutorService.java
│       │       │       │   │   ├── StatefulRunnable.java
│       │       │       │   │   └── UiThreadImmediateExecutorService.java
│       │       │       │   ├── file/
│       │       │       │   │   ├── FileTree.java
│       │       │       │   │   ├── FileTreeVisitor.java
│       │       │       │   │   └── FileUtils.java
│       │       │       │   ├── internal/
│       │       │       │   │   ├── AndroidPredicates.java
│       │       │       │   │   ├── ByteStreams.java
│       │       │       │   │   ├── Closeables.java
│       │       │       │   │   ├── CountingOutputStream.java
│       │       │       │   │   ├── DoNotStrip.java
│       │       │       │   │   ├── Files.java
│       │       │       │   │   ├── Fn.java
│       │       │       │   │   ├── ImmutableList.java
│       │       │       │   │   ├── ImmutableMap.java
│       │       │       │   │   ├── ImmutableSet.java
│       │       │       │   │   ├── Objects.java
│       │       │       │   │   ├── Preconditions.java
│       │       │       │   │   ├── Predicate.java
│       │       │       │   │   ├── Sets.java
│       │       │       │   │   ├── Supplier.java
│       │       │       │   │   ├── Suppliers.java
│       │       │       │   │   ├── Throwables.java
│       │       │       │   │   ├── package-info.java
│       │       │       │   │   └── proguard_annotations.pro
│       │       │       │   ├── lifecycle/
│       │       │       │   │   └── AttachDetachListener.kt
│       │       │       │   ├── logging/
│       │       │       │   │   ├── FLog.kt
│       │       │       │   │   ├── FLogDefaultLoggingDelegate.java
│       │       │       │   │   ├── LoggingDelegate.java
│       │       │       │   │   ├── logging.pro
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── media/
│       │       │       │   │   ├── MediaUtils.kt
│       │       │       │   │   └── MimeTypeMapWrapper.kt
│       │       │       │   ├── memory/
│       │       │       │   │   ├── ByteArrayPool.java
│       │       │       │   │   ├── DecodeBufferHelper.java
│       │       │       │   │   ├── MemoryTrimType.java
│       │       │       │   │   ├── MemoryTrimmable.java
│       │       │       │   │   ├── MemoryTrimmableRegistry.java
│       │       │       │   │   ├── NoOpMemoryTrimmableRegistry.java
│       │       │       │   │   ├── Pool.java
│       │       │       │   │   ├── PooledByteArrayBufferedInputStream.java
│       │       │       │   │   ├── PooledByteBuffer.kt
│       │       │       │   │   ├── PooledByteBufferFactory.java
│       │       │       │   │   ├── PooledByteBufferInputStream.java
│       │       │       │   │   ├── PooledByteBufferOutputStream.java
│       │       │       │   │   ├── PooledByteStreams.java
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── references/
│       │       │       │   │   ├── CloseableReference.java
│       │       │       │   │   ├── DefaultCloseableReference.java
│       │       │       │   │   ├── FinalizerCloseableReference.java
│       │       │       │   │   ├── HasBitmap.java
│       │       │       │   │   ├── NoOpCloseableReference.java
│       │       │       │   │   ├── OOMSoftReference.java
│       │       │       │   │   ├── RefCountCloseableReference.java
│       │       │       │   │   ├── ResourceReleaser.java
│       │       │       │   │   ├── SharedReference.java
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── statfs/
│       │       │       │   │   └── StatFsHelper.java
│       │       │       │   ├── streams/
│       │       │       │   │   ├── LimitedInputStream.kt
│       │       │       │   │   └── TailAppendingInputStream.kt
│       │       │       │   ├── time/
│       │       │       │   │   ├── AwakeTimeSinceBootClock.java
│       │       │       │   │   ├── Clock.java
│       │       │       │   │   ├── CurrentThreadTimeClock.java
│       │       │       │   │   ├── MonotonicClock.java
│       │       │       │   │   ├── MonotonicNanoClock.java
│       │       │       │   │   ├── RealtimeSinceBootClock.java
│       │       │       │   │   └── SystemClock.java
│       │       │       │   ├── util/
│       │       │       │   │   ├── ByteConstants.java
│       │       │       │   │   ├── ExceptionWithNoStacktrace.java
│       │       │       │   │   ├── HashCodeUtil.kt
│       │       │       │   │   ├── Hex.kt
│       │       │       │   │   ├── SecureHashUtil.kt
│       │       │       │   │   ├── StreamUtil.java
│       │       │       │   │   ├── TriState.java
│       │       │       │   │   └── UriUtil.java
│       │       │       │   └── webp/
│       │       │       │       ├── BitmapCreator.java
│       │       │       │       ├── WebpBitmapFactory.java
│       │       │       │       └── WebpSupportStatus.java
│       │       │       ├── datasource/
│       │       │       │   ├── AbstractDataSource.java
│       │       │       │   ├── BaseBooleanSubscriber.java
│       │       │       │   ├── BaseDataSubscriber.java
│       │       │       │   ├── DataSource.java
│       │       │       │   ├── DataSources.java
│       │       │       │   ├── DataSubscriber.java
│       │       │       │   ├── FirstAvailableDataSourceSupplier.java
│       │       │       │   ├── IncreasingQualityDataSourceSupplier.java
│       │       │       │   ├── RetainingDataSourceSupplier.java
│       │       │       │   ├── SimpleDataSource.kt
│       │       │       │   ├── SuccessfulVoidDataSource.kt
│       │       │       │   └── package-info.java
│       │       │       ├── memory/
│       │       │       │   └── helper/
│       │       │       │       └── HashCode.kt
│       │       │       └── widget/
│       │       │           └── text/
│       │       │               └── span/
│       │       │                   └── BetterImageSpan.java
│       │       └── pom.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           ├── common/
│           │           │   ├── callercontext/
│           │           │   │   └── ContextChainTest.kt
│           │           │   ├── executors/
│           │           │   │   ├── HandlerExecutorServiceImplTest.java
│           │           │   │   └── StatefulRunnableTest.java
│           │           │   ├── file/
│           │           │   │   └── FileUtilsTest.java
│           │           │   ├── media/
│           │           │   │   └── MediaUtilsTest.java
│           │           │   ├── references/
│           │           │   │   ├── CloseableReferenceTest.java
│           │           │   │   └── SharedReferenceTest.java
│           │           │   ├── streams/
│           │           │   │   ├── LimitedInputStreamTest.java
│           │           │   │   └── TailAppendingInputStreamTest.java
│           │           │   └── util/
│           │           │       ├── HashCodeUtilTest.java
│           │           │       ├── StreamUtilTest.java
│           │           │       ├── TriStateTest.java
│           │           │       └── UriUtilTest.java
│           │           ├── datasource/
│           │           │   ├── AbstractDataSourceTest.java
│           │           │   ├── DataSourceTestUtils.java
│           │           │   ├── DataSourcesTest.java
│           │           │   ├── FirstAvailableDataSourceSupplierTest.java
│           │           │   └── IncreasingQualityDataSourceSupplierTest.java
│           │           └── widget/
│           │               └── text/
│           │                   └── span/
│           │                       ├── BetterImageSpanMarginTest.java
│           │                       └── BetterImageSpanTest.java
│           └── resources/
│               └── robolectric.properties
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── imagepipeline/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── imagepipeline/
│       │                   ├── bitmaps/
│       │                   │   ├── Api31BitmapFactory.kt
│       │                   │   ├── ArtBitmapFactory.kt
│       │                   │   ├── EmptyJpegGenerator.kt
│       │                   │   ├── HoneycombBitmapCreator.kt
│       │                   │   └── PlatformBitmapFactoryProvider.kt
│       │                   ├── cache/
│       │                   │   ├── BitmapMemoryCacheKey.kt
│       │                   │   ├── BufferedDiskCache.kt
│       │                   │   ├── CacheKeyFactory.kt
│       │                   │   ├── CacheMissException.kt
│       │                   │   ├── DefaultBitmapMemoryCacheParamsSupplier.java
│       │                   │   ├── DefaultCacheKeyFactory.java
│       │                   │   ├── DefaultEncodedMemoryCacheParamsSupplier.java
│       │                   │   ├── EncodedCountingMemoryCacheFactory.java
│       │                   │   ├── EncodedMemoryCacheFactory.java
│       │                   │   ├── ImageCacheStatsTracker.kt
│       │                   │   ├── InstrumentedMemoryCache.java
│       │                   │   ├── InstrumentedMemoryCacheBitmapMemoryCacheFactory.java
│       │                   │   ├── MemoryCacheTracker.kt
│       │                   │   ├── NativeMemoryCacheTrimStrategy.java
│       │                   │   ├── NoOpImageCacheStatsTracker.java
│       │                   │   ├── StagingArea.java
│       │                   │   └── package-info.kt
│       │                   ├── core/
│       │                   │   ├── CloseableReferenceFactory.java
│       │                   │   ├── DiskCachesStore.kt
│       │                   │   ├── DiskCachesStoreFactory.kt
│       │                   │   ├── DiskStorageCacheFactory.java
│       │                   │   ├── DiskStorageFactory.kt
│       │                   │   ├── DownsampleMode.kt
│       │                   │   ├── DynamicDefaultDiskStorageFactory.java
│       │                   │   ├── FileCacheFactory.kt
│       │                   │   ├── ImagePipeline.kt
│       │                   │   ├── ImagePipelineConfig.kt
│       │                   │   ├── ImagePipelineConfigInterface.kt
│       │                   │   ├── ImagePipelineExperiments.kt
│       │                   │   ├── ImagePipelineFactory.java
│       │                   │   ├── ImageTranscoderType.java
│       │                   │   ├── MemoryChunkType.java
│       │                   │   ├── NativeCodeSetup.java
│       │                   │   ├── ProducerFactory.kt
│       │                   │   ├── ProducerSequenceFactory.kt
│       │                   │   └── package-info.kt
│       │                   ├── datasource/
│       │                   │   ├── AbstractProducerToDataSourceAdapter.kt
│       │                   │   ├── BaseBitmapDataSubscriber.kt
│       │                   │   ├── BaseBitmapReferenceDataSubscriber.kt
│       │                   │   ├── BaseListBitmapDataSubscriber.kt
│       │                   │   ├── CloseableProducerToDataSourceAdapter.java
│       │                   │   ├── ListDataSource.java
│       │                   │   ├── ProducerToDataSourceAdapter.kt
│       │                   │   ├── SettableDataSource.kt
│       │                   │   └── package-info.kt
│       │                   ├── debug/
│       │                   │   ├── CloseableReferenceLeakTracker.kt
│       │                   │   └── NoOpCloseableReferenceLeakTracker.kt
│       │                   ├── decoder/
│       │                   │   ├── DecodeException.kt
│       │                   │   ├── DefaultImageDecoder.java
│       │                   │   ├── ImageDecoderConfig.java
│       │                   │   ├── ProgressiveJpegConfig.java
│       │                   │   ├── ProgressiveJpegParser.java
│       │                   │   ├── SimpleProgressiveJpegConfig.java
│       │                   │   └── package-info.kt
│       │                   ├── filter/
│       │                   │   ├── InPlaceRoundFilter.kt
│       │                   │   ├── IterativeBoxBlurFilter.kt
│       │                   │   ├── NTSCDampeningFilterUtil.kt
│       │                   │   ├── RenderScriptBlurFilter.kt
│       │                   │   └── XferRoundFilter.kt
│       │                   ├── listener/
│       │                   │   ├── BaseRequestListener.kt
│       │                   │   ├── BaseRequestListener2.kt
│       │                   │   ├── ForwardingRequestListener.java
│       │                   │   ├── ForwardingRequestListener2.kt
│       │                   │   ├── RequestListener.java
│       │                   │   ├── RequestListener2.java
│       │                   │   ├── RequestLoggingListener.kt
│       │                   │   └── package-info.kt
│       │                   ├── memory/
│       │                   │   ├── BasePool.kt
│       │                   │   ├── BitmapCounter.java
│       │                   │   ├── BitmapCounterConfig.kt
│       │                   │   ├── BitmapCounterProvider.kt
│       │                   │   ├── BitmapPool.kt
│       │                   │   ├── BitmapPoolBackend.kt
│       │                   │   ├── BitmapPoolType.kt
│       │                   │   ├── Bucket.java
│       │                   │   ├── BucketMap.java
│       │                   │   ├── BucketsBitmapPool.kt
│       │                   │   ├── DefaultBitmapPoolParams.kt
│       │                   │   ├── DefaultByteArrayPoolParams.kt
│       │                   │   ├── DefaultFlexByteArrayPoolParams.kt
│       │                   │   ├── DefaultNativeMemoryChunkPoolParams.kt
│       │                   │   ├── DummyBitmapPool.kt
│       │                   │   ├── DummyTrackingInUseBitmapPool.kt
│       │                   │   ├── FlexByteArrayPool.kt
│       │                   │   ├── GenericByteArrayPool.kt
│       │                   │   ├── LruBitmapPool.java
│       │                   │   ├── LruBucketsPoolBackend.java
│       │                   │   ├── MemoryChunk.kt
│       │                   │   ├── MemoryChunkPool.java
│       │                   │   ├── MemoryChunkUtil.kt
│       │                   │   ├── MemoryPooledByteBuffer.kt
│       │                   │   ├── MemoryPooledByteBufferFactory.kt
│       │                   │   ├── MemoryPooledByteBufferOutputStream.kt
│       │                   │   ├── NoOpPoolStatsTracker.java
│       │                   │   ├── OOMSoftReferenceBucket.java
│       │                   │   ├── PoolBackend.kt
│       │                   │   ├── PoolConfig.kt
│       │                   │   ├── PoolFactory.kt
│       │                   │   ├── PoolParams.java
│       │                   │   ├── PoolStatsTracker.kt
│       │                   │   ├── SharedByteArray.java
│       │                   │   └── package-info.kt
│       │                   ├── multiuri/
│       │                   │   └── MultiUri.java
│       │                   ├── platform/
│       │                   │   ├── ArtDecoder.kt
│       │                   │   ├── DefaultDecoder.java
│       │                   │   ├── OreoDecoder.kt
│       │                   │   ├── PlatformDecoder.kt
│       │                   │   ├── PlatformDecoderFactory.kt
│       │                   │   ├── PlatformDecoderOptions.kt
│       │                   │   └── PreverificationHelper.kt
│       │                   ├── postprocessors/
│       │                   │   ├── BlurPostProcessor.kt
│       │                   │   ├── DownScaleBlurPostProcessor.kt
│       │                   │   ├── RoundPostprocessor.kt
│       │                   │   └── TintPostProcessor.kt
│       │                   ├── producers/
│       │                   │   ├── AddImageTransformMetaDataProducer.java
│       │                   │   ├── BaseConsumer.kt
│       │                   │   ├── BaseNetworkFetcher.kt
│       │                   │   ├── BaseProducerContext.java
│       │                   │   ├── BaseProducerContextCallbacks.kt
│       │                   │   ├── BitmapMemoryCacheGetProducer.kt
│       │                   │   ├── BitmapMemoryCacheKeyMultiplexProducer.java
│       │                   │   ├── BitmapMemoryCacheProducer.java
│       │                   │   ├── BitmapPrepareProducer.java
│       │                   │   ├── BitmapProbeProducer.java
│       │                   │   ├── BranchOnSeparateImagesProducer.java
│       │                   │   ├── Consumer.kt
│       │                   │   ├── CustomProducerSequenceFactory.java
│       │                   │   ├── DataFetchProducer.java
│       │                   │   ├── DecodeProducer.kt
│       │                   │   ├── DelayProducer.kt
│       │                   │   ├── DelegatingConsumer.kt
│       │                   │   ├── DiskCacheDecision.kt
│       │                   │   ├── DiskCacheReadProducer.java
│       │                   │   ├── DiskCacheWriteProducer.kt
│       │                   │   ├── EncodedCacheKeyMultiplexProducer.java
│       │                   │   ├── EncodedMemoryCacheProducer.java
│       │                   │   ├── EncodedProbeProducer.java
│       │                   │   ├── ExperimentalThreadHandoffProducerQueueImpl.kt
│       │                   │   ├── FetchState.kt
│       │                   │   ├── HttpUrlConnectionNetworkFetcher.java
│       │                   │   ├── InternalProducerListener.kt
│       │                   │   ├── InternalRequestListener.kt
│       │                   │   ├── JobScheduler.java
│       │                   │   ├── LocalAssetFetchProducer.kt
│       │                   │   ├── LocalContentUriFetchProducer.kt
│       │                   │   ├── LocalContentUriThumbnailFetchProducer.java
│       │                   │   ├── LocalExifThumbnailProducer.java
│       │                   │   ├── LocalFetchProducer.java
│       │                   │   ├── LocalFileFetchProducer.kt
│       │                   │   ├── LocalResourceFetchProducer.kt
│       │                   │   ├── LocalThumbnailBitmapSdk29Producer.java
│       │                   │   ├── LocalVideoThumbnailProducer.java
│       │                   │   ├── MultiplexProducer.java
│       │                   │   ├── NetworkFetchProducer.java
│       │                   │   ├── NetworkFetcher.java
│       │                   │   ├── PartialDiskCacheProducer.java
│       │                   │   ├── PostprocessedBitmapMemoryCacheProducer.java
│       │                   │   ├── PostprocessorProducer.kt
│       │                   │   ├── PriorityStarvingThrottlingProducer.java
│       │                   │   ├── Producer.kt
│       │                   │   ├── ProducerConstants.kt
│       │                   │   ├── ProducerContext.kt
│       │                   │   ├── ProducerContextCallbacks.kt
│       │                   │   ├── ProducerListener.java
│       │                   │   ├── ProducerListener2.java
│       │                   │   ├── QualifiedResourceFetchProducer.kt
│       │                   │   ├── RemoveImageTransformMetaDataProducer.kt
│       │                   │   ├── ResizeAndRotateProducer.java
│       │                   │   ├── SettableProducerContext.java
│       │                   │   ├── StatefulProducerRunnable.kt
│       │                   │   ├── SwallowResultProducer.java
│       │                   │   ├── ThreadHandoffProducer.kt
│       │                   │   ├── ThreadHandoffProducerQueue.java
│       │                   │   ├── ThreadHandoffProducerQueueImpl.kt
│       │                   │   ├── ThrottlingProducer.java
│       │                   │   ├── ThumbnailBranchProducer.java
│       │                   │   ├── ThumbnailProducer.kt
│       │                   │   ├── ThumbnailSizeChecker.kt
│       │                   │   └── package-info.kt
│       │                   ├── request/
│       │                   │   ├── BasePostprocessor.java
│       │                   │   ├── BaseRepeatedPostProcessor.kt
│       │                   │   ├── HasImageRequest.kt
│       │                   │   ├── ImageRequest.java
│       │                   │   ├── ImageRequestBuilder.java
│       │                   │   ├── Postprocessor.java
│       │                   │   ├── RepeatedPostprocessor.kt
│       │                   │   ├── RepeatedPostprocessorRunner.kt
│       │                   │   └── package-info.kt
│       │                   ├── transcoder/
│       │                   │   ├── MultiImageTranscoderFactory.kt
│       │                   │   ├── SimpleImageTranscoder.kt
│       │                   │   └── SimpleImageTranscoderFactory.kt
│       │                   └── xml/
│       │                       ├── XmlDrawableFactory.kt
│       │                       └── XmlFormatDecoder.kt
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       ├── common/
│           │   │       │   └── memory/
│           │   │       │       ├── PooledByteArrayBufferedInputStreamTest.kt
│           │   │       │       ├── PooledByteBufferInputStreamTest.kt
│           │   │       │       └── PooledByteStreamsTest.kt
│           │   │       └── imagepipeline/
│           │   │           ├── cache/
│           │   │           │   ├── BufferedDiskCacheTest.kt
│           │   │           │   └── StagingAreaTest.kt
│           │   │           ├── core/
│           │   │           │   ├── ImagePipelineConfigTest.kt
│           │   │           │   ├── ImagePipelineTest.java
│           │   │           │   └── ProducerSequenceFactoryTest.java
│           │   │           ├── datasource/
│           │   │           │   ├── CloseableProducerToDataSourceAdapterTest.kt
│           │   │           │   ├── ListDataSourceTest.kt
│           │   │           │   └── ProducerToDataSourceAdapterTest.kt
│           │   │           ├── decoder/
│           │   │           │   └── ProgressiveJpegParserTest.kt
│           │   │           ├── filter/
│           │   │           │   ├── InPlaceRoundFilterTest.kt
│           │   │           │   ├── IterativeBoxBlurFilterTest.kt
│           │   │           │   ├── RenderScriptBlurFilterTest.kt
│           │   │           │   └── XferRoundFilterTest.kt
│           │   │           ├── memory/
│           │   │           │   ├── BasePoolTest.kt
│           │   │           │   ├── BitmapCounterTest.kt
│           │   │           │   ├── BitmapPoolTest.java
│           │   │           │   ├── BucketMapTest.kt
│           │   │           │   ├── CloseableReferences.java
│           │   │           │   ├── FlexByteArrayPoolTest.java
│           │   │           │   ├── GenericByteArrayPoolTest.java
│           │   │           │   ├── LruBitmapPoolTest.kt
│           │   │           │   └── SharedByteArrayTest.java
│           │   │           ├── platform/
│           │   │           │   └── ArtDecoderTest.kt
│           │   │           ├── prioritization/
│           │   │           │   └── PriorityTest.kt
│           │   │           ├── producers/
│           │   │           │   ├── AddImageTransformMetaDataProducerTest.java
│           │   │           │   ├── BaseConsumerTest.kt
│           │   │           │   ├── BitmapMemoryCacheGetProducerTest.java
│           │   │           │   ├── BitmapMemoryCacheProducerTest.java
│           │   │           │   ├── BitmapPrepareProducerTest.java
│           │   │           │   ├── BranchOnSeparateImagesProducerTest.java
│           │   │           │   ├── DataFetchProducerTest.kt
│           │   │           │   ├── DecodeProducerTest.java
│           │   │           │   ├── DiskCacheReadProducerTest.java
│           │   │           │   ├── DiskCacheWriteProducerTest.java
│           │   │           │   ├── DownsampleUtilTest.kt
│           │   │           │   ├── EncodedMemoryCacheProducerTest.java
│           │   │           │   ├── HttpUrlConnectionNetworkFetcherTest.kt
│           │   │           │   ├── JobSchedulerTest.kt
│           │   │           │   ├── LocalAssetFetchProducerTest.kt
│           │   │           │   ├── LocalContentUriFetchProducerTest.kt
│           │   │           │   ├── LocalContentUriThumbnailFetchProducerTest.kt
│           │   │           │   ├── LocalExifThumbnailProducerTest.kt
│           │   │           │   ├── LocalFileFetchProducerTest.kt
│           │   │           │   ├── LocalResourceFetchProducerTest.kt
│           │   │           │   ├── LocalVideoThumbnailProducerTest.kt
│           │   │           │   ├── MultiplexProducerTest.java
│           │   │           │   ├── NetworkFetchProducerTest.java
│           │   │           │   ├── NetworkFetcherCallbackTest.java
│           │   │           │   ├── PartialDiskCacheProducerTest.java
│           │   │           │   ├── PostprocessedBitmapMemoryCacheProducerTest.java
│           │   │           │   ├── PriorityStarvingThrottlingProducerTest.java
│           │   │           │   ├── QualifiedResourceFetchProducerTest.kt
│           │   │           │   ├── RemoveImageTransformMetaDataProducerTest.java
│           │   │           │   ├── RepeatedPostprocessorProducerTest.java
│           │   │           │   ├── ResizeAndRotateProducerTest.kt
│           │   │           │   ├── SettableProducerContextTest.kt
│           │   │           │   ├── SingleUsePostprocessorProducerTest.java
│           │   │           │   ├── StatefulProducerRunnableTest.kt
│           │   │           │   ├── SwallowResultProducerTest.java
│           │   │           │   ├── ThreadHandoffProducerTest.kt
│           │   │           │   ├── ThrottlingProducerTest.java
│           │   │           │   ├── ThumbnailBranchProducerTest.java
│           │   │           │   └── ThumbnailSizeCheckerTest.kt
│           │   │           └── request/
│           │   │               ├── ForwardingRequestListenerTest.kt
│           │   │               ├── ImageRequestBuilderCacheEnabledTest.kt
│           │   │               └── ImageRequestTest.kt
│           │   └── org/
│           │       └── mockito/
│           │           └── configuration/
│           │               └── MockitoConfiguration.java
│           └── resources/
│               ├── org/
│               │   └── powermock/
│               │       └── extensions/
│               │           └── configuration.properties
│               └── org.robolectric.Config.properties
├── imagepipeline-backends/
│   ├── imagepipeline-okhttp3/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           └── backends/
│   │                               └── okhttp3/
│   │                                   ├── OkHttpImagePipelineConfigFactory.kt
│   │                                   ├── OkHttpNetworkFetcher.kt
│   │                                   ├── OkHttpNetworkFetcherException.kt
│   │                                   └── package-info.kt
│   └── imagepipeline-volley/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               └── backends/
│                                   └── volley/
│                                       ├── RawRequest.java
│                                       ├── VolleyImagePipelineConfigFactory.java
│                                       └── VolleyNetworkFetcher.java
├── imagepipeline-base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               ├── binaryresource/
│       │               │   ├── BinaryResource.kt
│       │               │   ├── ByteArrayBinaryResource.kt
│       │               │   └── FileBinaryResource.kt
│       │               ├── cache/
│       │               │   ├── common/
│       │               │   │   ├── BaseCacheEventListener.java
│       │               │   │   ├── CacheErrorLogger.java
│       │               │   │   ├── CacheEvent.java
│       │               │   │   ├── CacheEventListener.java
│       │               │   │   ├── CacheKey.java
│       │               │   │   ├── CacheKeyUtil.kt
│       │               │   │   ├── DebuggingCacheKey.java
│       │               │   │   ├── HasDebugData.kt
│       │               │   │   ├── MultiCacheKey.java
│       │               │   │   ├── NoOpCacheErrorLogger.java
│       │               │   │   ├── NoOpCacheEventListener.java
│       │               │   │   ├── SimpleCacheKey.java
│       │               │   │   ├── WriterCallback.java
│       │               │   │   ├── WriterCallbacks.java
│       │               │   │   └── package-info.java
│       │               │   └── disk/
│       │               │       ├── DefaultDiskStorage.kt
│       │               │       ├── DefaultEntryEvictionComparatorSupplier.java
│       │               │       ├── DiskCacheConfig.java
│       │               │       ├── DiskStorage.java
│       │               │       ├── DiskStorageCache.kt
│       │               │       ├── DynamicDefaultDiskStorage.java
│       │               │       ├── EntryEvictionComparator.java
│       │               │       ├── EntryEvictionComparatorSupplier.java
│       │               │       ├── FileCache.kt
│       │               │       ├── ScoreBasedEvictionComparatorSupplier.java
│       │               │       ├── SettableCacheEvent.java
│       │               │       └── package-info.java
│       │               ├── callercontext/
│       │               │   └── CallerContextVerifier.kt
│       │               ├── drawable/
│       │               │   └── base/
│       │               │       └── DrawableWithCaches.kt
│       │               ├── imageformat/
│       │               │   ├── DefaultImageFormatChecker.kt
│       │               │   ├── DefaultImageFormats.kt
│       │               │   ├── ImageFormat.kt
│       │               │   ├── ImageFormatChecker.kt
│       │               │   └── ImageFormatCheckerUtils.kt
│       │               ├── imagepipeline/
│       │               │   ├── animated/
│       │               │   │   └── factory/
│       │               │   │       ├── AnimatedFactory.kt
│       │               │   │       ├── AnimatedFactoryProvider.kt
│       │               │   │       └── package-info.kt
│       │               │   ├── bitmaps/
│       │               │   │   ├── PlatformBitmapFactory.java
│       │               │   │   ├── SimpleBitmapReleaser.java
│       │               │   │   └── package-info.kt
│       │               │   ├── cache/
│       │               │   │   ├── AbstractAdaptiveCountingMemoryCache.java
│       │               │   │   ├── BitmapMemoryCacheFactory.kt
│       │               │   │   ├── BitmapMemoryCacheTrimStrategy.kt
│       │               │   │   ├── BoundedLinkedHashSet.kt
│       │               │   │   ├── CountingLruBitmapMemoryCacheFactory.java
│       │               │   │   ├── CountingLruMap.java
│       │               │   │   ├── CountingMemoryCache.java
│       │               │   │   ├── CountingMemoryCacheInspector.kt
│       │               │   │   ├── LruCountingMemoryCache.java
│       │               │   │   ├── MemoryCache.kt
│       │               │   │   ├── MemoryCacheParams.kt
│       │               │   │   ├── ValueDescriptor.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── common/
│       │               │   │   ├── BytesRange.kt
│       │               │   │   ├── ImageDecodeOptions.java
│       │               │   │   ├── ImageDecodeOptionsBuilder.java
│       │               │   │   ├── Priority.kt
│       │               │   │   ├── ResizeOptions.kt
│       │               │   │   ├── RotationOptions.kt
│       │               │   │   ├── SourceUriType.kt
│       │               │   │   ├── TooManyBitmapsException.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── core/
│       │               │   │   ├── DefaultExecutorSupplier.kt
│       │               │   │   ├── ExecutorSupplier.kt
│       │               │   │   ├── PriorityThreadFactory.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── decoder/
│       │               │   │   ├── ImageDecoder.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── drawable/
│       │               │   │   ├── DrawableFactory.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── image/
│       │               │   │   ├── BaseCloseableImage.java
│       │               │   │   ├── BaseCloseableStaticBitmap.java
│       │               │   │   ├── CloseableBitmap.java
│       │               │   │   ├── CloseableImage.java
│       │               │   │   ├── CloseableStaticBitmap.java
│       │               │   │   ├── CloseableXml.kt
│       │               │   │   ├── DefaultCloseableImage.java
│       │               │   │   ├── DefaultCloseableStaticBitmap.java
│       │               │   │   ├── DefaultCloseableXml.kt
│       │               │   │   ├── EncodedImage.java
│       │               │   │   ├── HasImageMetadata.java
│       │               │   │   ├── ImageInfo.java
│       │               │   │   ├── ImageInfoImpl.java
│       │               │   │   ├── ImmutableQualityInfo.java
│       │               │   │   ├── QualityInfo.java
│       │               │   │   └── package-info.kt
│       │               │   ├── instrumentation/
│       │               │   │   └── FrescoInstrumenter.kt
│       │               │   ├── nativecode/
│       │               │   │   └── NativeImageTranscoderFactory.kt
│       │               │   ├── network/
│       │               │   │   └── NetworkResponseData.kt
│       │               │   ├── systrace/
│       │               │   │   ├── DefaultFrescoSystrace.kt
│       │               │   │   └── FrescoSystrace.kt
│       │               │   ├── transcoder/
│       │               │   │   ├── DownsampleUtil.kt
│       │               │   │   ├── ImageTranscodeResult.kt
│       │               │   │   ├── ImageTranscoder.kt
│       │               │   │   ├── ImageTranscoderFactory.kt
│       │               │   │   ├── JpegTranscoderUtils.kt
│       │               │   │   └── TranscodeStatus.kt
│       │               │   └── transformation/
│       │               │       ├── BitmapTransformation.kt
│       │               │       ├── CircularTransformation.kt
│       │               │       └── TransformationUtils.kt
│       │               └── imageutils/
│       │                   ├── BitmapUtil.kt
│       │                   ├── HeifExifUtil.kt
│       │                   ├── ImageMetaData.kt
│       │                   ├── JfifUtil.kt
│       │                   ├── StreamProcessor.kt
│       │                   ├── TiffUtil.kt
│       │                   └── WebpUtil.kt
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       ├── cache/
│           │   │       │   ├── common/
│           │   │       │   │   └── CacheEventAssert.kt
│           │   │       │   └── disk/
│           │   │       │       ├── DefaultDiskStorageTest.kt
│           │   │       │       ├── DefaultEntryEvictionComparatorSupplierTest.kt
│           │   │       │       ├── DiskStorageCacheTest.kt
│           │   │       │       ├── DynamicDefaultDiskStorageTest.kt
│           │   │       │       ├── ScoreBasedEvictionComparatorSupplierTest.kt
│           │   │       │       └── SettableCacheEventTest.kt
│           │   │       ├── imageformat/
│           │   │       │   └── ImageFormatCheckerTest.kt
│           │   │       ├── imagepipeline/
│           │   │       │   ├── cache/
│           │   │       │   │   ├── AbstractAdaptiveCountingMemoryCacheTest.kt
│           │   │       │   │   ├── BoundedLinkedHashSetTest.kt
│           │   │       │   │   ├── CountingLruMapTest.kt
│           │   │       │   │   └── LruCountingMemoryCacheTest.kt
│           │   │       │   ├── common/
│           │   │       │   │   ├── BytesRangeTest.kt
│           │   │       │   │   ├── ImageDecodeOptionsTest.kt
│           │   │       │   │   └── ResizeOptionsTest.kt
│           │   │       │   └── image/
│           │   │       │       ├── CloseableBitmapTest.kt
│           │   │       │       ├── CloseableStaticBitmapTest.kt
│           │   │       │       └── EncodedImageTest.kt
│           │   │       └── imageutils/
│           │   │           ├── BitmapUtilTest.kt
│           │   │           ├── JfifTestUtils.kt
│           │   │           ├── JfifTestUtilsTest.kt
│           │   │           ├── JfifUtilTest.kt
│           │   │           └── WebPUtilTest.kt
│           │   └── org/
│           │       └── mockito/
│           │           └── configuration/
│           │               └── MockitoConfiguration.java
│           └── resources/
│               ├── com/
│               │   └── facebook/
│               │       └── imageformat/
│               │           ├── heifs/
│               │           │   └── 1.heif
│               │           └── xmls/
│               │               ├── AndroidManifest.xml
│               │               ├── README.md
│               │               ├── compiled/
│               │               │   ├── layer_list.xml
│               │               │   ├── level_list.xml
│               │               │   ├── state_list.xml
│               │               │   └── vector_drawable.xml
│               │               ├── convert.sh
│               │               └── raw/
│               │                   └── drawable/
│               │                       ├── layer_list.xml
│               │                       ├── level_list.xml
│               │                       ├── state_list.xml
│               │                       └── vector_drawable.xml
│               └── org.robolectric.Config.properties
├── imagepipeline-base-test/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           └── testing/
│                               ├── DeltaQueue.java
│                               ├── FakeClock.java
│                               ├── ScheduledQueue.java
│                               ├── TestExecutorService.java
│                               ├── TestNativeLoader.kt
│                               ├── TestScheduledExecutorService.java
│                               ├── TestScheduledFuture.java
│                               ├── TrivialBufferPooledByteBuffer.java
│                               └── TrivialPooledByteBuffer.java
├── imagepipeline-native/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               └── nativecode/
│           │                   ├── Bitmaps.kt
│           │                   ├── DalvikPurgeableDecoder.kt
│           │                   └── ImagePipelineNativeLoader.kt
│           └── jni/
│               ├── Application.mk
│               ├── bitmaps/
│               │   ├── Android.mk
│               │   ├── Bitmaps.c
│               │   └── Bitmaps.h
│               ├── imagepipeline/
│               │   ├── Android.mk
│               │   ├── exceptions.cpp
│               │   ├── exceptions.h
│               │   ├── init.cpp
│               │   └── logging.h
│               └── memchunk/
│                   ├── Android.mk
│                   ├── NativeMemoryChunk.c
│                   └── NativeMemoryChunk.h
├── imagepipeline-test/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           ├── memory/
│                           │   ├── IntPair.java
│                           │   └── PoolStats.java
│                           └── testing/
│                               └── MockBitmapFactory.kt
├── memory-types/
│   ├── ashmem/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── imagepipeline/
│   │       │                   └── memory/
│   │       │                       ├── AshmemMemoryChunk.java
│   │       │                       └── AshmemMemoryChunkPool.java
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           ├── memory/
│   │                           │   ├── AshmemMemoryChunkPoolTest.kt
│   │                           │   ├── MemoryPooledByteBufferFactoryTest.java
│   │                           │   ├── MemoryPooledByteBufferOutputStreamTest.java
│   │                           │   └── MemoryPooledByteBufferTest.java
│   │                           └── testing/
│   │                               ├── FakeAshmemMemoryChunk.java
│   │                               └── FakeAshmemMemoryChunkPool.java
│   ├── nativememory/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── imagepipeline/
│   │       │                   └── memory/
│   │       │                       ├── NativeMemoryChunk.java
│   │       │                       └── NativeMemoryChunkPool.java
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           ├── memory/
│   │                           │   ├── MemoryPooledByteBufferFactoryTest.java
│   │                           │   ├── MemoryPooledByteBufferOutputStreamTest.java
│   │                           │   ├── MemoryPooledByteBufferTest.java
│   │                           │   ├── NativeMemoryChunkPoolTest.java
│   │                           │   └── TestUsingNativeMemoryChunk.java
│   │                           └── testing/
│   │                               ├── FakeNativeMemoryChunk.java
│   │                               └── FakeNativeMemoryChunkPool.java
│   └── simple/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           ├── main/
│           │   ├── AndroidManifest.xml
│           │   └── java/
│           │       └── com/
│           │           └── facebook/
│           │               └── imagepipeline/
│           │                   └── memory/
│           │                       ├── BufferMemoryChunk.kt
│           │                       └── BufferMemoryChunkPool.kt
│           └── test/
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               ├── memory/
│                               │   ├── BufferMemoryChunkPoolTest.java
│                               │   ├── MemoryPooledByteBufferFactoryTest.java
│                               │   ├── MemoryPooledByteBufferOutputStreamTest.java
│                               │   └── MemoryPooledByteBufferTest.java
│                               └── testing/
│                                   └── FakeBufferMemoryChunkPool.kt
├── middleware/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── middleware/
│                               ├── HasExtraData.kt
│                               └── MiddlewareUtils.kt
├── mockito-config/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── java/
│               └── org/
│                   └── mockito/
│                       └── configuration/
│                           └── MockitoConfiguration.java
├── native-filters/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               ├── nativecode/
│           │               │   ├── NativeBlurFilter.kt
│           │               │   ├── NativeFiltersLoader.kt
│           │               │   └── NativeRoundingFilter.kt
│           │               └── postprocessors/
│           │                   ├── IterativeBoxBlurPostProcessor.kt
│           │                   ├── RoundAsCirclePostprocessor.kt
│           │                   └── RoundedCornersPostprocessor.kt
│           └── jni/
│               ├── Application.mk
│               ├── filters/
│               │   ├── Android.mk
│               │   ├── blur_filter.c
│               │   ├── blur_filter.h
│               │   ├── rounding_filter.c
│               │   └── rounding_filter.h
│               └── native-filters/
│                   ├── Android.mk
│                   ├── exceptions_handling.cpp
│                   ├── exceptions_handling.h
│                   ├── init.cpp
│                   ├── java_globals.h
│                   └── logging.h
├── native-imagetranscoder/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               └── nativecode/
│           │                   ├── NativeJpegTranscoder.java
│           │                   ├── NativeJpegTranscoderFactory.java
│           │                   └── NativeJpegTranscoderSoLoader.java
│           └── jni/
│               ├── Application.mk
│               ├── native-imagetranscoder/
│               │   ├── Android.mk
│               │   ├── JpegTranscoder.cpp
│               │   ├── JpegTranscoder.h
│               │   ├── decoded_image.cpp
│               │   ├── decoded_image.h
│               │   ├── exceptions_handler.cpp
│               │   ├── exceptions_handler.h
│               │   ├── init.cpp
│               │   ├── java_globals.h
│               │   ├── jpeg/
│               │   │   ├── jpeg_codec.cpp
│               │   │   ├── jpeg_codec.h
│               │   │   ├── jpeg_error_handler.cpp
│               │   │   ├── jpeg_error_handler.h
│               │   │   ├── jpeg_memory_io.cpp
│               │   │   ├── jpeg_memory_io.h
│               │   │   ├── jpeg_stream_wrappers.cpp
│               │   │   └── jpeg_stream_wrappers.h
│               │   ├── logging.h
│               │   ├── transformations.cpp
│               │   └── transformations.h
│               └── third-party/
│                   └── libjpeg-turbo-2.1.5.1/
│                       ├── Android.mk
│                       ├── config.h
│                       ├── jconfig.h
│                       ├── jconfigint.h
│                       ├── jversion.h
│                       └── neon-compat.h
├── run_comparison.py
├── samples/
│   ├── README.md
│   ├── animation2/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── build.gradle
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── animation2/
│   │           │                   ├── AnimationApplication.java
│   │           │                   ├── MediaControlFragment.java
│   │           │                   ├── SampleData.java
│   │           │                   ├── StandaloneActivity.java
│   │           │                   ├── bitmap/
│   │           │                   │   ├── BitmapAnimationCacheSelectorConfigurator.java
│   │           │                   │   ├── BitmapAnimationDebugFragment.java
│   │           │                   │   ├── BitmapAnimationFragment.java
│   │           │                   │   ├── DebugBitmapAnimationFrameListener.java
│   │           │                   │   ├── ExampleBitmapAnimationFactory.java
│   │           │                   │   └── NaiveCacheAllFramesCachingBackend.java
│   │           │                   ├── color/
│   │           │                   │   ├── ExampleColorBackend.java
│   │           │                   │   └── SimpleColorFragment.java
│   │           │                   ├── local/
│   │           │                   │   └── LocalDrawableAnimationBackend.java
│   │           │                   └── utils/
│   │           │                       ├── AnimationBackendUtils.java
│   │           │                       ├── AnimationControlsManager.java
│   │           │                       └── SampleAnimationBackendConfigurator.java
│   │           └── res/
│   │               ├── drawable/
│   │               │   └── ic_play_pause_24dp.xml
│   │               ├── layout/
│   │               │   ├── activity_standalone.xml
│   │               │   ├── backends.xml
│   │               │   ├── cache_selector.xml
│   │               │   ├── controls.xml
│   │               │   ├── fragment_debug_bitmap.xml
│   │               │   ├── fragment_media_controls.xml
│   │               │   ├── fragment_simple_container.xml
│   │               │   └── frame_info.xml
│   │               ├── values/
│   │               │   ├── colors.xml
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               └── values-w820dp/
│   │                   └── dimens.xml
│   ├── comparison/
│   │   ├── build.gradle
│   │   ├── proguard.pro
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── comparison/
│   │           │                   ├── ComparisonApp.java
│   │           │                   ├── Drawables.java
│   │           │                   ├── MainActivity.kt
│   │           │                   ├── adapters/
│   │           │                   │   ├── AQueryAdapter.java
│   │           │                   │   ├── FrescoAdapter.java
│   │           │                   │   ├── GlideAdapter.java
│   │           │                   │   ├── ImageListAdapter.java
│   │           │                   │   ├── PicassoAdapter.java
│   │           │                   │   ├── UilAdapter.java
│   │           │                   │   └── VolleyAdapter.java
│   │           │                   ├── configs/
│   │           │                   │   ├── ConfigConstants.java
│   │           │                   │   ├── glide/
│   │           │                   │   │   └── SampleGlideModule.java
│   │           │                   │   ├── imagepipeline/
│   │           │                   │   │   └── ImagePipelineConfigFactory.java
│   │           │                   │   ├── picasso/
│   │           │                   │   │   └── SamplePicassoFactory.java
│   │           │                   │   ├── uil/
│   │           │                   │   │   └── SampleUilFactory.java
│   │           │                   │   └── volley/
│   │           │                   │       ├── SampleVolleyFactory.java
│   │           │                   │       └── VolleyMemoryCache.java
│   │           │                   ├── holders/
│   │           │                   │   ├── AQueryHolder.java
│   │           │                   │   ├── BaseViewHolder.java
│   │           │                   │   ├── FrescoHolder.java
│   │           │                   │   ├── GlideHolder.java
│   │           │                   │   ├── PicassoHolder.java
│   │           │                   │   ├── UilHolder.java
│   │           │                   │   ├── VolleyDraweeHolder.java
│   │           │                   │   └── VolleyHolder.java
│   │           │                   ├── instrumentation/
│   │           │                   │   ├── Instrumentation.java
│   │           │                   │   ├── Instrumented.java
│   │           │                   │   ├── InstrumentedDraweeView.java
│   │           │                   │   ├── InstrumentedImageView.java
│   │           │                   │   ├── InstrumentedNetworkImageView.java
│   │           │                   │   └── PerfListener.java
│   │           │                   └── urlsfetcher/
│   │           │                       ├── ImageFormat.java
│   │           │                       ├── ImageSize.java
│   │           │                       ├── ImageUrlsFetcher.java
│   │           │                       ├── ImageUrlsRequest.java
│   │           │                       └── ImageUrlsRequestBuilder.java
│   │           └── res/
│   │               ├── layout/
│   │               │   └── activity_main.xml
│   │               ├── menu/
│   │               │   └── menu_main.xml
│   │               └── values/
│   │                   ├── colors.xml
│   │                   ├── dimens.xml
│   │                   ├── strings.xml
│   │                   └── styles.xml
│   ├── contrib/
│   │   └── com/
│   │       └── facebook/
│   │           └── drawee/
│   │               └── drawable/
│   │                   └── CircleProgressBarDrawable.java
│   ├── gestures/
│   │   ├── build.gradle
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── samples/
│   │       │                   └── gestures/
│   │       │                       ├── MultiPointerGestureDetector.java
│   │       │                       └── TransformGestureDetector.java
│   │       └── test/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── gestures/
│   │           │                   ├── MotionEventTestUtils.java
│   │           │                   ├── MultiPointerGestureDetectorTest.java
│   │           │                   └── TransformGestureDetectorTest.java
│   │           └── resources/
│   │               └── org.robolectric.Config.properties
│   ├── scrollperf/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-scrollperf.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── facebook/
│   │       │   │           └── samples/
│   │       │   │               └── scrollperf/
│   │       │   │                   └── data/
│   │       │   │                       └── impl/
│   │       │   │                           ├── InfiniteSimpleAdapterTest.java
│   │       │   │                           └── LocalResourceSimpleAdapterTest.java
│   │       │   └── res/
│   │       │       └── values/
│   │       │           ├── colors.xml
│   │       │           └── strings_untranslated.xml
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── facebook/
│   │       │   │           └── samples/
│   │       │   │               └── scrollperf/
│   │       │   │                   ├── MainActivity.java
│   │       │   │                   ├── ScrollPerfApplication.java
│   │       │   │                   ├── conf/
│   │       │   │                   │   ├── Config.java
│   │       │   │                   │   └── Const.java
│   │       │   │                   ├── data/
│   │       │   │                   │   ├── Decorator.java
│   │       │   │                   │   ├── SimpleAdapter.java
│   │       │   │                   │   └── impl/
│   │       │   │                   │       ├── ContentProviderSimpleAdapter.java
│   │       │   │                   │       ├── DistinctUriDecorator.java
│   │       │   │                   │       └── LocalResourceSimpleAdapter.java
│   │       │   │                   ├── fragments/
│   │       │   │                   │   ├── MainFragment.java
│   │       │   │                   │   ├── SettingsFragment.java
│   │       │   │                   │   └── recycler/
│   │       │   │                   │       ├── VitoViewAdapter.java
│   │       │   │                   │       ├── VitoViewHolder.java
│   │       │   │                   │       └── VitoViewListAdapter.java
│   │       │   │                   ├── instrumentation/
│   │       │   │                   │   ├── Instrumentation.java
│   │       │   │                   │   ├── Instrumented.java
│   │       │   │                   │   ├── InstrumentedVitoView.java
│   │       │   │                   │   └── PerfListener.java
│   │       │   │                   ├── internal/
│   │       │   │                   │   └── ScrollPerfExecutorSupplier.java
│   │       │   │                   ├── postprocessor/
│   │       │   │                   │   └── DelayPostprocessor.java
│   │       │   │                   ├── preferences/
│   │       │   │                   │   └── SizePreferences.java
│   │       │   │                   └── util/
│   │       │   │                       ├── PipelineUtil.java
│   │       │   │                       ├── SizeUtil.java
│   │       │   │                       ├── TimeWaster.java
│   │       │   │                       ├── UI.java
│   │       │   │                       └── VitoUtil.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   ├── activity_main.xml
│   │       │       │   ├── content_listview.xml
│   │       │       │   ├── content_recyclerview.xml
│   │       │       │   ├── fragment_main.xml
│   │       │       │   └── size_preference.xml
│   │       │       ├── menu/
│   │       │       │   └── menu.xml
│   │       │       ├── values/
│   │       │       │   ├── array.xml
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   ├── strings_untranslated.xml
│   │       │       │   └── styles.xml
│   │       │       └── xml/
│   │       │           └── preferences.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── samples/
│   │                           └── scrollperf/
│   │                               └── util/
│   │                                   └── TimeWasterTest.java
│   ├── showcase/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-showcase.pro
│   │   ├── proguard-test.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── fresco/
│   │       │                   └── samples/
│   │       │                       └── showcase/
│   │       │                           └── ShowcaseRunTest.java
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── fresco/
│   │           │               └── samples/
│   │           │                   └── showcase/
│   │           │                       ├── BaseShowcaseFragment.java
│   │           │                       ├── BaseShowcaseKotlinFragment.kt
│   │           │                       ├── CustomImageFormatConfigurator.java
│   │           │                       ├── ExampleCategory.kt
│   │           │                       ├── ExampleDatabase.kt
│   │           │                       ├── ExampleItem.kt
│   │           │                       ├── ImageOptionsBottomSheet.kt
│   │           │                       ├── LithoSample.kt
│   │           │                       ├── LithoSampleHostFragment.kt
│   │           │                       ├── MainActivity.kt
│   │           │                       ├── ShowcaseApplication.kt
│   │           │                       ├── common/
│   │           │                       │   ├── CustomScaleTypes.java
│   │           │                       │   ├── DimensionUtils.kt
│   │           │                       │   ├── SimpleScaleTypeAdapter.java
│   │           │                       │   └── SpinnerUtils.kt
│   │           │                       ├── imageformat/
│   │           │                       │   ├── color/
│   │           │                       │   │   ├── ColorImageExample.java
│   │           │                       │   │   └── ImageFormatColorFragment.java
│   │           │                       │   ├── datauri/
│   │           │                       │   │   └── ImageFormatDataUriFragment.java
│   │           │                       │   ├── gif/
│   │           │                       │   │   └── ImageFormatGifFragment.java
│   │           │                       │   ├── keyframes/
│   │           │                       │   │   ├── AnimatableKeyframesDrawable.java
│   │           │                       │   │   ├── ImageFormatKeyframesFragment.java
│   │           │                       │   │   └── KeyframesDecoderExample.java
│   │           │                       │   ├── override/
│   │           │                       │   │   └── ImageFormatOverrideExample.java
│   │           │                       │   ├── pjpeg/
│   │           │                       │   │   └── ImageFormatProgressiveJpegFragment.java
│   │           │                       │   ├── svg/
│   │           │                       │   │   ├── ImageFormatSvgFragment.java
│   │           │                       │   │   └── SvgDecoderExample.java
│   │           │                       │   ├── webp/
│   │           │                       │   │   └── ImageFormatWebpFragment.java
│   │           │                       │   └── xml/
│   │           │                       │       └── ImageFormatXmlFragment.java
│   │           │                       ├── imagepipeline/
│   │           │                       │   ├── DurationCallback.java
│   │           │                       │   ├── ImagePipelineBitmapFactoryFragment.java
│   │           │                       │   ├── ImagePipelineDownsampleFragment.java
│   │           │                       │   ├── ImagePipelineNotificationFragment.java
│   │           │                       │   ├── ImagePipelinePostProcessorFragment.java
│   │           │                       │   ├── ImagePipelinePrefetchFragment.java
│   │           │                       │   ├── ImagePipelineQualifiedResourceFragment.java
│   │           │                       │   ├── ImagePipelineRegionDecodingFragment.java
│   │           │                       │   ├── ImagePipelineResizingFragment.java
│   │           │                       │   ├── PartialRequestFragment.java
│   │           │                       │   └── widget/
│   │           │                       │       └── ResizableFrameLayout.java
│   │           │                       ├── misc/
│   │           │                       │   ├── CheckerBoardDrawable.java
│   │           │                       │   ├── DebugImageListener.kt
│   │           │                       │   ├── DebugOverlaySupplierSingleton.java
│   │           │                       │   ├── ImageSourceSpinner.kt
│   │           │                       │   ├── ImageUriProvider.kt
│   │           │                       │   ├── LogcatImagePerfDataListener.java
│   │           │                       │   ├── LogcatRequestListener2.kt
│   │           │                       │   └── WelcomeFragment.java
│   │           │                       ├── permissions/
│   │           │                       │   └── StoragePermissionHelper.kt
│   │           │                       ├── postprocessor/
│   │           │                       │   ├── BasePostprocessorWithDurationCallback.java
│   │           │                       │   ├── BenchmarkPostprocessorForDuplicatedBitmap.java
│   │           │                       │   ├── BenchmarkPostprocessorForDuplicatedBitmapInPlace.java
│   │           │                       │   ├── BenchmarkPostprocessorForManualBitmapHandling.java
│   │           │                       │   ├── CachedWatermarkPostprocessor.java
│   │           │                       │   ├── FasterGreyScalePostprocessor.java
│   │           │                       │   ├── ScalingBlurPostprocessor.java
│   │           │                       │   ├── SlowGreyScalePostprocessor.java
│   │           │                       │   └── WatermarkPostprocessor.java
│   │           │                       ├── settings/
│   │           │                       │   └── SettingsFragment.java
│   │           │                       └── vito/
│   │           │                           ├── FrescoVitoImageDecodeOptions.java
│   │           │                           ├── FrescoVitoImageDecodeOptionsBuilder.java
│   │           │                           ├── FrescoVitoLithoDrawableImageSourceExample.kt
│   │           │                           ├── FrescoVitoLithoGalleryFragment.java
│   │           │                           ├── FrescoVitoLithoImageOptionsConfigFragment.kt
│   │           │                           ├── FrescoVitoLithoListenerExample.kt
│   │           │                           ├── FrescoVitoLithoRegionDecodeFragment.java
│   │           │                           ├── FrescoVitoLithoSectionsFragment.java
│   │           │                           ├── FrescoVitoLithoSimpleExample.kt
│   │           │                           ├── FrescoVitoRegionDecoder.java
│   │           │                           ├── ImageLayersFragment.java
│   │           │                           ├── ImageSourceConfigurator.kt
│   │           │                           ├── LithoSlideshowSample.kt
│   │           │                           ├── MultiUriFragment.kt
│   │           │                           ├── RetainingDataSourceSupplierFragment.java
│   │           │                           ├── SimpleGallerySectionSpec.java
│   │           │                           ├── SimpleListItemSpec.java
│   │           │                           ├── SimpleListSectionSpec.java
│   │           │                           ├── VitoMediaPickerFragment.kt
│   │           │                           ├── VitoRotationFragment.java
│   │           │                           ├── VitoRoundedCornersFragment.java
│   │           │                           ├── VitoScaleTypeFragment.java
│   │           │                           ├── VitoSimpleFragment.java
│   │           │                           ├── VitoSpanFragment.kt
│   │           │                           ├── VitoSpinners.kt
│   │           │                           ├── VitoViewKtxFragment.kt
│   │           │                           ├── VitoViewPrefetchFragment.kt
│   │           │                           ├── VitoViewRecyclerFragment.java
│   │           │                           ├── VitoViewSimpleFragment.java
│   │           │                           ├── ninepatch/
│   │           │                           │   ├── LithoNinePatchSample.kt
│   │           │                           │   └── NinePatchExample.java
│   │           │                           ├── renderer/
│   │           │                           │   ├── RendererColorFilterExampleFragment.kt
│   │           │                           │   ├── RendererExampleDrawable.kt
│   │           │                           │   ├── RendererExampleUtils.kt
│   │           │                           │   ├── RendererFadeExampleFragment.kt
│   │           │                           │   ├── RendererShapeExampleFragment.kt
│   │           │                           │   └── VitoLayerExample.kt
│   │           │                           ├── source/
│   │           │                           │   └── ImageRequestImageSource.kt
│   │           │                           └── transition/
│   │           │                               ├── ImageDetailsActivity.java
│   │           │                               └── VitoTransitionFragment.java
│   │           └── res/
│   │               ├── drawable/
│   │               │   ├── ic_error_black_96dp.xml
│   │               │   ├── ic_retry_black_48dp.xml
│   │               │   ├── ic_settings_black_24dp.xml
│   │               │   ├── resize_outline.xml
│   │               │   ├── side_nav_bar.xml
│   │               │   ├── xml_bitmap.xml
│   │               │   ├── xml_layer_list.xml
│   │               │   ├── xml_level_list.xml
│   │               │   ├── xml_nine_patch.xml
│   │               │   ├── xml_state_list.xml
│   │               │   └── xml_vector.xml
│   │               ├── drawable-anydpi/
│   │               │   ├── ic_arrow_left.xml
│   │               │   ├── ic_arrow_right.xml
│   │               │   └── ic_edit.xml
│   │               ├── layout/
│   │               │   ├── activity_main.xml
│   │               │   ├── activity_vito_transition_detail.xml
│   │               │   ├── app_bar_main.xml
│   │               │   ├── content_main.xml
│   │               │   ├── dialog_fragment_uri_override.xml
│   │               │   ├── fragment_format_color.xml
│   │               │   ├── fragment_format_datauri.xml
│   │               │   ├── fragment_format_gif.xml
│   │               │   ├── fragment_format_keyframes.xml
│   │               │   ├── fragment_format_override.xml
│   │               │   ├── fragment_format_progressive_jpeg.xml
│   │               │   ├── fragment_format_svg.xml
│   │               │   ├── fragment_format_webp.xml
│   │               │   ├── fragment_format_xml.xml
│   │               │   ├── fragment_image_layers.xml
│   │               │   ├── fragment_imagepipeline_bitmap_factory.xml
│   │               │   ├── fragment_imagepipeline_downsample.xml
│   │               │   ├── fragment_imagepipeline_notification.xml
│   │               │   ├── fragment_imagepipeline_postprocessor.xml
│   │               │   ├── fragment_imagepipeline_prefetch.xml
│   │               │   ├── fragment_imagepipeline_qualified_resource.xml
│   │               │   ├── fragment_imagepipeline_region_decoding.xml
│   │               │   ├── fragment_imagepipeline_resizing.xml
│   │               │   ├── fragment_litho_host.xml
│   │               │   ├── fragment_partial_request.xml
│   │               │   ├── fragment_recycler.xml
│   │               │   ├── fragment_scrolling_linear_layout.xml
│   │               │   ├── fragment_vito_image_options_config.xml
│   │               │   ├── fragment_vito_litho_region_decoding.xml
│   │               │   ├── fragment_vito_media_picker.xml
│   │               │   ├── fragment_vito_multi_uri.xml
│   │               │   ├── fragment_vito_retaining_supplier.xml
│   │               │   ├── fragment_vito_rotation.xml
│   │               │   ├── fragment_vito_rounded_corners.xml
│   │               │   ├── fragment_vito_scale_type.xml
│   │               │   ├── fragment_vito_simple.xml
│   │               │   ├── fragment_vito_text_span.xml
│   │               │   ├── fragment_vito_transition.xml
│   │               │   ├── fragment_vito_view_ktx.xml
│   │               │   ├── fragment_vito_view_prefetch.xml
│   │               │   ├── fragment_vito_view_simple.xml
│   │               │   ├── fragment_welcome.xml
│   │               │   ├── nav_header_main.xml
│   │               │   └── vito_recycler_item.xml
│   │               ├── menu/
│   │               │   └── main.xml
│   │               ├── raw/
│   │               │   ├── custom_color1.color
│   │               │   └── custom_color2.color
│   │               ├── values/
│   │               │   ├── colors.xml
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               ├── values-v21/
│   │               │   └── styles.xml
│   │               ├── values-w820dp/
│   │               │   └── dimens.xml
│   │               └── xml/
│   │                   └── preferences.xml
│   ├── zoomable/
│   │   ├── build.gradle
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── samples/
│   │                           └── zoomable/
│   │                               ├── AbstractAnimatedZoomableController.java
│   │                               ├── AnimatedZoomableController.java
│   │                               ├── DefaultZoomableController.java
│   │                               ├── DoubleTapGestureListener.java
│   │                               ├── GestureListenerWrapper.java
│   │                               ├── MultiGestureListener.java
│   │                               ├── MultiZoomableControllerListener.java
│   │                               ├── ZoomableController.java
│   │                               ├── ZoomableDraweeView.java
│   │                               └── ZoomableVitoView.java
│   └── zoomableapp/
│       ├── .gitignore
│       ├── build.gradle
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               ├── java/
│               │   └── com/
│               │       └── facebook/
│               │           └── samples/
│               │               └── zoomableapp/
│               │                   ├── MainActivity.java
│               │                   ├── MyPagerAdapter.java
│               │                   └── ZoomableApplication.java
│               └── res/
│                   ├── layout/
│                   │   ├── activity_main.xml
│                   │   └── zoomable_image.xml
│                   ├── menu/
│                   │   └── menu.xml
│                   └── values/
│                       ├── colors.xml
│                       ├── strings.xml
│                       └── styles.xml
├── settings.gradle
├── soloader/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           └── nativecode/
│                               └── NativeCodeInitializer.kt
├── static-webp/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── webpsupport/
│       │                   ├── AndroidManifest.xml
│       │                   ├── WebpBitmapFactoryTest.java
│       │                   └── WebpDecodingTest.java
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           ├── imagepipeline/
│           │           │   └── nativecode/
│           │           │       └── StaticWebpNativeLoader.kt
│           │           └── webpsupport/
│           │               ├── WebPImageDecoder.java
│           │               └── WebpBitmapFactoryImpl.java
│           └── jni/
│               ├── Application.mk
│               ├── static-webp/
│               │   ├── Android.mk
│               │   ├── decoded_image.cpp
│               │   ├── decoded_image.h
│               │   ├── exceptions.cpp
│               │   ├── exceptions.h
│               │   ├── java_globals.h
│               │   ├── jni_helpers.cpp
│               │   ├── jni_helpers.h
│               │   ├── logging.h
│               │   ├── streams.cpp
│               │   ├── streams.h
│               │   ├── transformations.cpp
│               │   ├── transformations.h
│               │   ├── webp.cpp
│               │   ├── webp.h
│               │   └── webp_bitmapfactory.cpp
│               └── third-party/
│                   ├── libjpeg-turbo-2.1.5.1/
│                   │   ├── Android.mk
│                   │   ├── config.h
│                   │   ├── jconfig.h
│                   │   ├── jconfigint.h
│                   │   ├── jversion.h
│                   │   └── neon-compat.h
│                   ├── libpng-1.6.37/
│                   │   ├── Android.mk
│                   │   └── pnglibconf.h
│                   └── libwebp-1.3.2/
│                       └── Android.mk
├── tools/
│   ├── flipper/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           └── debug/
│   │                               ├── DebugImageTracker.kt
│   │                               ├── FlipperCacheKeyFactory.kt
│   │                               ├── FlipperCloseableReferenceLeakTracker.kt
│   │                               ├── FlipperImageTracker.kt
│   │                               ├── LruMap.kt
│   │                               └── NoOpDebugImageTracker.kt
│   ├── flipper-fresco-plugin/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── flipper/
│   │                           └── plugins/
│   │                               └── fresco/
│   │                                   ├── FrescoFlipperDebugPrefHelper.java
│   │                                   ├── FrescoFlipperPlugin.java
│   │                                   ├── FrescoFlipperRequestListener.java
│   │                                   └── objecthelper/
│   │                                       └── FlipperObjectHelper.java
│   └── stetho/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               └── stetho/
│                                   ├── BaseFrescoStethoPlugin.kt
│                                   └── FrescoStethoPlugin.kt
├── ui-common/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── ui/
│                               └── common/
│                                   ├── BaseControllerListener2.kt
│                                   ├── ControllerListener2.kt
│                                   ├── DimensionsInfo.kt
│                                   ├── ForwardingControllerListener2.kt
│                                   ├── ImageLoadStatus.kt
│                                   ├── ImagePerfData.kt
│                                   ├── ImagePerfDataListener.kt
│                                   ├── ImagePerfDataNotifier.kt
│                                   ├── ImagePerfLoggingState.kt
│                                   ├── ImagePerfNotifier.kt
│                                   ├── ImagePerfNotifierHolder.kt
│                                   ├── ImagePerfState.kt
│                                   ├── ImageRenderingInfra.kt
│                                   ├── LegacyOnFadeListener.kt
│                                   ├── MultiUriHelper.kt
│                                   ├── NoOpImagePerfNotifier.kt
│                                   ├── OnDrawControllerListener.kt
│                                   ├── OnFadeListener.kt
│                                   ├── SimpleImagePerfNotifier.kt
│                                   ├── VisibilityAware.kt
│                                   ├── VisibilityState.kt
│                                   └── VitoUtils.kt
├── ui-core/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           └── java/
│               ├── AndroidManifest.xml
│               └── com/
│                   └── facebook/
│                       └── drawee/
│                           └── drawable/
│                               ├── ScalingUtils.java
│                               ├── SizingHint.kt
│                               └── Viewport.kt
├── urimod/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── urimod/
│                               ├── Dimensions.kt
│                               ├── FetchStrategy.kt
│                               ├── NopUriModifier.kt
│                               ├── UriModifier.kt
│                               └── UriModifierInterface.kt
├── viewport/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── viewport/
│                               ├── HasTransform.kt
│                               └── ViewportData.kt
└── vito/
    ├── compose/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── compose/
    │                                   └── VitoImage.kt
    ├── core/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       ├── core/
    │       │                       │   ├── AnimatedImagePerfLoggingListener.kt
    │       │                       │   ├── BaseVitoImageRequestListener.kt
    │       │                       │   ├── CombinedImageListener.kt
    │       │                       │   ├── ComposedImagePerfLoggingListener.kt
    │       │                       │   ├── DefaultFrescoVitoConfig.kt
    │       │                       │   ├── FrescoController2.kt
    │       │                       │   ├── FrescoDrawableInterface.kt
    │       │                       │   ├── FrescoVitoConfig.kt
    │       │                       │   ├── FrescoVitoPrefetcher.kt
    │       │                       │   ├── ImagePerfLoggingListener.kt
    │       │                       │   ├── ImagePipelineUtils.kt
    │       │                       │   ├── ListVitoImagePerfListener.kt
    │       │                       │   ├── NopDrawable.kt
    │       │                       │   ├── PrefetchConfig.kt
    │       │                       │   ├── PrefetchReason.kt
    │       │                       │   ├── PrefetchTarget.kt
    │       │                       │   ├── ReleaseStrategy.kt
    │       │                       │   ├── VitoImagePerfListener.kt
    │       │                       │   ├── VitoImagePipeline.kt
    │       │                       │   ├── VitoImageRequest.kt
    │       │                       │   └── VitoImageRequestListener.kt
    │       │                       ├── drawable/
    │       │                       │   ├── ArrayVitoDrawableFactory.kt
    │       │                       │   ├── BitmapDrawableFactory.kt
    │       │                       │   ├── CircularBorderBitmapDrawable.kt
    │       │                       │   └── RoundingUtils.kt
    │       │                       └── listener/
    │       │                           ├── BaseImageListener.kt
    │       │                           ├── ForwardingImageListener.kt
    │       │                           └── ImageListener.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               ├── core/
    │                               │   └── VitoImageRequestTest.kt
    │                               └── drawable/
    │                                   ├── BitmapDrawableFactoryTest.kt
    │                                   └── RoundingUtilsTest.kt
    ├── core-common-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── BaseVitoImagePerfListener.kt
    │                                       ├── CombinedImageListenerImpl.kt
    │                                       └── debug/
    │                                           ├── DebugDataProvider.kt
    │                                           ├── DebugOverlayDrawable.kt
    │                                           ├── DebugOverlayImageOriginColor.kt
    │                                           └── LightweightDebugOverlayDrawable.kt
    ├── core-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── ActualImageHandler.kt
    │                                       ├── BackgroundLayerHandler.kt
    │                                       ├── BorderRenderer.kt
    │                                       ├── DebugDataProvider.kt
    │                                       ├── DebugOverlayHandler.kt
    │                                       ├── DrawableExtensions.kt
    │                                       ├── ExtrasUtils.kt
    │                                       ├── ImageFetchSubscriber.kt
    │                                       ├── ImageLayerDataModel.kt
    │                                       ├── ImageLayerDataModelExtensions.kt
    │                                       ├── ImageReleaseScheduler.kt
    │                                       ├── ImageWithTransformationAndBorderRenderer.kt
    │                                       ├── KFrescoController.kt
    │                                       ├── KFrescoVitoDrawable.kt
    │                                       ├── KImageOptions.kt
    │                                       ├── NopImagePerfListener.kt
    │                                       ├── ProgressLayerHandler.kt
    │                                       ├── PropertyDelegates.kt
    │                                       └── ShapeCalculator.kt
    ├── core-java-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── core/
    │       │                           └── impl/
    │       │                               ├── DefaultImageDecodeOptionsProviderImpl.kt
    │       │                               ├── DrawableDataSubscriber.kt
    │       │                               ├── FrescoController2Impl.kt
    │       │                               ├── FrescoDrawable2.kt
    │       │                               ├── FrescoDrawable2Impl.kt
    │       │                               ├── FrescoVitoPrefetcherImpl.kt
    │       │                               ├── Hierarcher.kt
    │       │                               ├── HierarcherImpl.kt
    │       │                               ├── ImagePipelineUtilsImpl.kt
    │       │                               ├── ImageSourceToImagePipelineAdapter.kt
    │       │                               ├── NoOpFrescoVitoPrefetcher.kt
    │       │                               ├── VitoImagePipelineImpl.kt
    │       │                               ├── debug/
    │       │                               │   ├── BaseDebugOverlayFactory2.kt
    │       │                               │   ├── DebugOverlayFactory2.kt
    │       │                               │   ├── DefaultDebugOverlayFactory2.kt
    │       │                               │   ├── FrescoDrawable2DebugDataProviders.kt
    │       │                               │   ├── LightweightDebugOverlayFactory2.kt
    │       │                               │   └── NoOpDebugOverlayFactory2.kt
    │       │                               └── source/
    │       │                                   ├── DataSourceImageSource.kt
    │       │                                   ├── ImagePipelineImageSource.kt
    │       │                                   └── RetainingImageSource.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── FrescoDrawable2ImplTest.kt
    │                                       ├── HierarcherImplTest.kt
    │                                       ├── ImagePipelineUtilsImplTest.kt
    │                                       └── VitoImagePipelineImplTest.kt
    ├── drawable-holder/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           └── java/
    │               ├── AndroidManifest.xml
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── drawableholder/
    │                                   └── MultiVitoDrawableHolder.kt
    ├── drawee-support/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── draweesupport/
    │       │                           ├── ControllerListenerWrapper.kt
    │       │                           ├── DrawableFactoryWrapper.kt
    │       │                           ├── RoundingParamsWrapper.kt
    │       │                           └── VitoViewInflater.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── draweesupport/
    │                                   └── ControllerListenerWrapperTest.kt
    ├── init/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── init/
    │                                   └── FrescoVito.kt
    ├── ktx/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── ktx/
    │                                   ├── ImageSourceExtensions.kt
    │                                   └── ViewExtensions.kt
    ├── litho/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── litho/
    │                                   ├── FrescoVitoImage2Spec.kt
    │                                   └── FrescoVitoTapToRetryImageSpec.kt
    ├── litho-slideshow/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── litho/
    │                                   └── slideshow/
    │                                       ├── FrescoVitoSlideshowComponentSpec.kt
    │                                       └── FrescoVitoSlideshowDrawable.kt
    ├── nativecode/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── nativecode/
    │                                   ├── CircularBitmapTransformation.kt
    │                                   └── NativeCircularBitmapRounding.kt
    ├── options/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── options/
    │       │                           ├── AnimatedOptions.kt
    │       │                           ├── BitmapConfig.kt
    │       │                           ├── BorderOptions.kt
    │       │                           ├── DecodedImageOptions.kt
    │       │                           ├── EncodedImageOptions.kt
    │       │                           ├── ImageOptions.kt
    │       │                           ├── ImageOptionsDrawableFactory.kt
    │       │                           └── RoundingOptions.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── options/
    │                                   └── RoundingOptionsTest.kt
    ├── provider/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── provider/
    │                                   ├── FrescoVitoProvider.kt
    │                                   ├── components/
    │                                   │   └── FrescoVitoComponents.kt
    │                                   ├── impl/
    │                                   │   ├── DefaultFrescoVitoProvider.kt
    │                                   │   ├── NoOpCallerContextVerifier.kt
    │                                   │   └── kotlin/
    │                                   │       └── KFrescoVitoProvider.kt
    │                                   └── setup/
    │                                       └── FrescoVitoSetup.kt
    ├── renderer/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── renderer/
    │                                   ├── CanvasTransformation.kt
    │                                   ├── CanvasTransformationHandler.kt
    │                                   ├── ImageDataModel.kt
    │                                   ├── ImageRenderer.kt
    │                                   ├── Shape.kt
    │                                   └── util/
    │                                       └── ColorUtils.kt
    ├── source/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── source/
    │                                   ├── BitmapImageSource.kt
    │                                   ├── ColorImageSource.kt
    │                                   ├── DrawableImageSource.kt
    │                                   ├── DrawableResImageSource.kt
    │                                   ├── EmptyImageSource.kt
    │                                   ├── FirstAvailableImageSource.kt
    │                                   ├── ImageSource.kt
    │                                   ├── ImageSourceExtras.kt
    │                                   ├── ImageSourceProvider.kt
    │                                   ├── IncreasingQualityImageSource.kt
    │                                   ├── SingleImageSource.kt
    │                                   ├── SingleImageSourceImpl.kt
    │                                   ├── SmartFetchOptIn.kt
    │                                   ├── SmartImageSource.kt
    │                                   └── UriImageSource.kt
    ├── textspan/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── textspan/
    │                                   ├── VitoSpan.kt
    │                                   └── VitoSpanLoader.kt
    ├── tools/
    │   └── liveeditor/
    │       ├── build.gradle
    │       ├── gradle.properties
    │       └── src/
    │           └── main/
    │               ├── AndroidManifest.xml
    │               └── java/
    │                   └── com/
    │                       └── facebook/
    │                           └── fresco/
    │                               └── vito/
    │                                   └── tools/
    │                                       └── liveeditor/
    │                                           ├── ImageLiveEditor.kt
    │                                           ├── ImageOptionsSampleValues.kt
    │                                           ├── ImageSelector.kt
    │                                           ├── ImageSourceParser.kt
    │                                           ├── ImageSourceSampleValues.kt
    │                                           ├── ImageSourceSyntaxException.kt
    │                                           ├── ImageSourceUiUtil.kt
    │                                           ├── ImageTracker.kt
    │                                           ├── LiveEditorOnScreenButtonController.kt
    │                                           └── LiveEditorUiUtils.kt
    └── view/
        ├── build.gradle
        ├── gradle.properties
        └── src/
            └── main/
                ├── AndroidManifest.xml
                └── java/
                    └── com/
                        └── facebook/
                            └── fresco/
                                └── vito/
                                    └── view/
                                        ├── ImageViewWithAspectRatio.kt
                                        ├── VitoView.kt
                                        ├── impl/
                                        │   └── VitoViewImpl2.kt
                                        └── transition/
                                            └── VitoTransition.kt

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
We use GitHub Issues for bugs.

If you have a non-bug question, please ask on Stack Overflow: http://stackoverflow.com/questions/tagged/fresco

--- Please use this template, and delete everything above this line before submitting your issue --- 

### Description

[FILL THIS OUT: Explain what you did, what you expected to happen, and what actually happens.]

### Reproduction

[FILL THIS OUT: How can we reproduce the bug? Provide URLs to relevant images if possible, or a sample project.]

### Solution

[OPTIONAL: Do you know what needs to be done to address this issue? Ideally, provide a pull request which fixes this issue.]

### Additional Information

* Fresco version: [FILL THIS OUT]
* Platform version: [FILL THIS OUT: specific to a particular Android version? Device?]


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Thanks for submitting a PR! Please read these instructions carefully:

- [ ] Explain the **motivation** for making this change.
- [ ] Provide a **test plan** demonstrating that the code is solid.
- [ ] Match the **code formatting** of the rest of the codebase.
- [ ] Target the `main` branch

## Motivation (required)

What existing problem does the pull request solve?

## Test Plan (required)

A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI or updates the website. See [What is a Test Plan?][1] to learn more.  

If you have added code that should be tested, add tests.

## Next Steps

Sign the [CLA][2], if you haven't already.

Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.

Make sure all **tests pass** on [Circle CI][4]. PRs that break tests are unlikely to be merged.

For more info, see the [Contributing guide][4].

[1]: https://medium.com/@martinkonicek/what-is-a-test-plan-8bfc840ec171#.y9lcuqqi9
[2]: https://code.facebook.com/cla
[3]: http://circleci.com/gh/facebook/fresco
[4]: https://github.com/facebook/fresco/blob/main/CONTRIBUTING.md


================================================
FILE: .github/stale.yml
================================================
# Configuration for probot-stale - https://github.com/probot/stale
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 7
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
  - bug
  - enhancement
  - good first issue
  - help wanted
  - question
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
  Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
  You may also label this issue as "bug" or "enhancement" and I will leave it open.
  Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: >
  Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to reopen with up-to-date information.
only: issues


================================================
FILE: .github/workflows/build.yml
================================================
name: facebook/fresco/build
on:
  push:
    branches:
    - main
  pull_request:
    branches:
    - main
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - name: Print pre-setup debug info
      run: ./ci/print-debug-info.sh
    - uses: nttld/setup-ndk@v1
      id: setup-ndk
      with:
        ndk-version: r27b
    - name: Install JDK
      uses: actions/setup-java@v5
      with:
        distribution: 'temurin'
        java-version: |
          11
          17
        cache: gradle
    - name: Print post-setup debug info
      run: |
        ./ci/print-debug-info.sh
        echo "Printing Gradle Wrapper version"
        ./gradlew --version
      env:
        ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
    - name: Build & run tests
      run: ./ci/build-and-test.sh
      env:
        ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
    - name: Copy Results
      run: |
        mkdir -p ./gh_actions/test-results/junit
        find . -type f -regex ".*/build/test-results/.*xml" -exec cp {} ./gh_actions/test-results/junit \;
    - uses: actions/upload-artifact@v6
      with:
        path: "./gh_actions/test-results"


================================================
FILE: .github/workflows/gradle-wrapper-validation.yml
================================================
name: "Validate Gradle Wrapper"
on: [push, pull_request]

jobs:
  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: gradle/actions/wrapper-validation@v3


================================================
FILE: .github/workflows/release.yml
================================================
name: Publish

on:
  push:
    tags:
      - v*
  workflow_dispatch:
    inputs:
      tag:
        description: "Tag to upload artifacts to"
        required: false

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v6
    - name: Install JDK
      uses: actions/setup-java@v5
      with:
        distribution: 'temurin'
        java-version: |
          11
          17
        cache: gradle
    - name: Setup Android SDK
      uses: android-actions/setup-android@v3
    - name: Install NDK
      id: setup-ndk
      uses: nttld/setup-ndk@v1
      with:
        ndk-version: r27b
    - name: Register NDK
      run: |
        echo $PATH
        echo 'ndk.path=/opt/hostedtoolcache/ndk/r27b/x64' >> local.properties
    - name: Write GPG Sec Ring
      run: echo '${{ secrets.GPG_KEY_CONTENTS }}' | base64 -d > /tmp/secring.gpg
    - name: Update gradle.properties
      run: echo -e "signing.secretKeyRingFile=/tmp/secring.gpg\nsigning.keyId=${{ secrets.SIGNING_KEY_ID }}\nsigning.password=${{ secrets.SIGNING_PASSWORD }}\nmavenCentralPassword=${{ secrets.SONATYPE_NEXUS_PASSWORD }}\nmavenCentralUsername=${{ secrets.SONATYPE_NEXUS_USERNAME }}" >> gradle.properties
    - name: Upload Android Archives
      run: ./gradlew publish --no-daemon --no-parallel --info --stacktrace
      env:
        ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
    - name: Release and close
      run: ./gradlew closeAndReleaseRepository
      env:
        ANDROID_NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
    - name: Clean secrets
      if: always()
      run: rm /tmp/secring.gpg


================================================
FILE: .gitignore
================================================
.gradle
.DS_Store
.idea
build/
local.properties
localhost/
obj/
*.iml
Gemfile.lock
_site/

# Kotlin 2.0
# https://kotlinlang.org/docs/whatsnew20.html#new-directory-for-kotlin-data-in-gradle-projects
.kotlin


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
  advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <opensource-conduct@fb.com>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq



================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Fresco

We want to make contributing to this project as easy and transparent as
possible.

## Security bugs

Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a GitHub issue.

## Pull Requests

We welcome pull requests.

1. Fork the repo and create your branch from `main`.
2. If you've added code that should be tested, add tests.
3. If you've changed APIs, update the documentation. 
4. Make sure the test suite passes.
5. Make sure your code passes lint.
6. If you haven't already, complete the [Contributor License Agreement](https://code.facebook.com/cla) ("CLA").

## Getting started

In Android Studio, choose `File > Open..`. and select the `fresco` folder.

### Specify a path to the NDK

Fresco uses native code for a few features. To build Fresco you'll need to specify the path to the NDK.

In Android Studio, go to `File > Project Structure` and in the dialog set the `Android NDK location`. Android Studio stores the NDK location in to your `local.properties` file.

### Run a sample app

Select the **Showcase** app and click run:

![Running a sample Fresco app](https://cloud.githubusercontent.com/assets/346214/24415877/d48d894c-13da-11e7-8601-09627661de67.png)

You can use the drawer to select one of the demos:

<img width="364" alt="Fresco showcase app" src="https://cloud.githubusercontent.com/assets/346214/24416135/a9a4a07a-13db-11e7-9d19-25ae9cbc83d3.png">

Now you can change any code in Fresco and see the changes in the app.

Have fun hacking on Fresco! 😎

## Testing your changes

You can check your code compiles using:

```
cd fresco
./gradlew assembleDebug
```

You can run tests locally using:

```
cd fresco
./gradlew test
```

Circle CI will run the same tests and report on your pull request.

## Contributor License Agreement ("CLA")

In order to accept your pull request, we need you to submit a CLA. You only need
to do this once to work on any of Facebook's open source projects.

Complete your CLA here: <https://code.facebook.com/cla>.

## Our Development Process

Each pull request is first submitted into Facebook's internal repositories by a
Facebook team member. Once the commit has successfully passed Facebook's internal
test suite, it will be exported back out from Facebook's repository. We endeavour
to do this as soon as possible for all commits.

## Coding Style  

* 2 spaces for indentation rather than tabs
* 100 character line length
* Although officially archived, we still follow the practice of Oracle's 
[Coding Conventions for the Java Programming Language](http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).

## License

By contributing to Fresco, you agree that your contributions will be licensed
under its MIT license.


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) Meta Platforms, Inc. and affiliates.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# Fresco

<img alt="Fresco Logo" align="right" src="docs/static/sample-images/fresco_logo.svg" width="15%" />

[![Build Status](https://github.com/facebook/fresco/actions/workflows/build.yml/badge.svg?event=push)](https://github.com/facebook/fresco/actions/workflows/build.yml?query=event%3Apush)
[![License](https://img.shields.io/badge/license-MIT-brightgreen)](https://github.com/facebook/fresco/blob/main/LICENSE)

Fresco is a powerful system for displaying images in Android applications.

Fresco takes care of image loading and display, so you don't have to. It will load images from the network, local storage, or local resources, and display a placeholder until the image has arrived. It has two levels of cache; one in memory and another in internal storage.

In Android 4.x and lower, Fresco puts images in a special region of Android memory. This lets your application run faster - and suffer the dreaded `OutOfMemoryError` much less often.

Fresco also supports:

* streaming of progressive JPEGs
* display of animated GIFs and WebPs
* extensive customization of image loading and display
* and much more!

Find out more at our [website](http://frescolib.org/index.html).

## Requirements

Fresco can be included in any Android application.

Fresco supports Android 2.3 (Gingerbread) and later.

## Using Fresco in your application

If you are building with Gradle, simply add the following line to the `dependencies` section of your `build.gradle` file:

```groovy
implementation 'com.facebook.fresco:fresco:3.6.0'
```

For full details, visit the documentation on our web site, available in English and Chinese:

<a href="http://frescolib.org/docs/index.html"><img src="http://frescolib.org/static/GetStarted-en.png" width="150" height="42"/></a>

<a href="http://fresco-cn.org/docs/index.html"><img src="http://frescolib.org/static/GetStarted-zh.png" width="104" height="42"/></a>

## Join the Fresco community

Please use our [issues page](https://github.com/facebook/fresco/issues) to let us know of any problems.

For pull requests, please see the [CONTRIBUTING](https://github.com/facebook/fresco/blob/main/CONTRIBUTING.md) file for information on how to help out. See our [documentation](http://frescolib.org/docs/building-from-source.html) for information on how to build from source.


## License
Fresco is [MIT-licensed](https://github.com/facebook/fresco/blob/main/LICENSE).


================================================
FILE: animated-base/.gitignore
================================================
nativedeps/


================================================
FILE: animated-base/build.gradle
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import com.facebook.fresco.buildsrc.Deps
import com.facebook.fresco.buildsrc.GradleDeps
import com.facebook.fresco.buildsrc.TestDeps

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

kotlin {
    jvmToolchain(11)
}

dependencies {
    compileOnly Deps.inferAnnotation
    compileOnly Deps.javaxAnnotation
    compileOnly Deps.jsr305
    compileOnly Deps.AndroidX.androidxAnnotation

    api project(':fbcore')
    api project(':imagepipeline-base')
    api project(':imagepipeline')
    api project(':imagepipeline-native')
    api project(':memory-types:ashmem')
    api project(':memory-types:nativememory')
    api project(':memory-types:simple')
    api project(':animated-drawable')
    implementation Deps.Bolts.tasks
    implementation project(':vito:core')
    implementation project(':vito:options')
    implementation project(':middleware')

    testCompileOnly Deps.inferAnnotation
    testImplementation project(':imagepipeline-test')
    testImplementation project(':imagepipeline-base-test')
    testImplementation TestDeps.assertjCore
    testImplementation TestDeps.junit
    testImplementation TestDeps.festAssertCore
    testImplementation TestDeps.mockitoCore3
    testImplementation TestDeps.mockitoInline3
    testImplementation TestDeps.mockitoKotlin3
    testImplementation(TestDeps.robolectric) {
        exclude group: 'commons-logging', module: 'commons-logging'
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'
    }
}

android {
    ndkVersion GradleDeps.Native.version

    buildToolsVersion FrescoConfig.buildToolsVersion
    compileSdkVersion FrescoConfig.compileSdkVersion

    namespace "com.facebook.imagepipeline.animated"

    defaultConfig {
        minSdkVersion FrescoConfig.minSdkVersion
        targetSdkVersion FrescoConfig.targetSdkVersion
    }
    lintOptions {
        abortOnError false
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
}

apply plugin: "com.vanniktech.maven.publish"


================================================
FILE: animated-base/gradle.properties
================================================
POM_NAME=AnimatedBase
POM_DESCRIPTION=Base classes for animation support
POM_ARTIFACT_ID=animated-base
POM_PACKAGING=aar



================================================
FILE: animated-base/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.facebook.imagepipeline.animated"
    >
</manifest>


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/bitmap/cache/AnimationFrameCacheKey.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.cache

import android.net.Uri
import com.facebook.cache.common.CacheKey

/* Frame cache key for animation */

class AnimationFrameCacheKey
@JvmOverloads
constructor(imageId: Int, private val deepEquals: Boolean = false) : CacheKey {

  private val animationUriString: String = URI_PREFIX + imageId

  override fun containsUri(uri: Uri): Boolean = uri.toString().startsWith(animationUriString)

  override fun getUriString(): String = animationUriString

  override fun isResourceIdForDebugging(): Boolean = false

  override fun equals(o: Any?): Boolean {
    if (!deepEquals) {
      return super.equals(o)
    }

    if (this === o) {
      return true
    }
    if (o == null || javaClass != o.javaClass) {
      return false
    }

    val that = o as AnimationFrameCacheKey
    return animationUriString == that.animationUriString
  }

  override fun hashCode(): Int {
    if (!deepEquals) {
      return super.hashCode()
    }
    return animationUriString.hashCode()
  }

  companion object {
    private const val URI_PREFIX = "anim://"
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/bitmap/cache/FrescoFrameCache.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.cache

import android.graphics.Bitmap
import android.util.SparseArray
import androidx.annotation.VisibleForTesting
import com.facebook.common.logging.FLog
import com.facebook.common.references.CloseableReference
import com.facebook.fresco.animation.bitmap.BitmapAnimationBackend
import com.facebook.fresco.animation.bitmap.BitmapAnimationBackend.FrameType
import com.facebook.fresco.animation.bitmap.BitmapFrameCache
import com.facebook.fresco.animation.bitmap.BitmapFrameCache.FrameCacheListener
import com.facebook.imagepipeline.animated.impl.AnimatedFrameCache
import com.facebook.imagepipeline.image.CloseableBitmap
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.CloseableStaticBitmap
import com.facebook.imagepipeline.image.ImmutableQualityInfo
import com.facebook.imageutils.BitmapUtil
import javax.annotation.concurrent.GuardedBy

/** Bitmap frame cache that uses Fresco's [AnimatedFrameCache] to cache frames. */
class FrescoFrameCache(
    private val animatedFrameCache: AnimatedFrameCache,
    private val enableBitmapReusing: Boolean,
) : BitmapFrameCache {

  @GuardedBy("this")
  private val preparedPendingFrames = SparseArray<CloseableReference<CloseableImage>?>()

  @GuardedBy("this") private var lastRenderedItem: CloseableReference<CloseableImage>? = null

  @Synchronized
  override fun getCachedFrame(frameNumber: Int): CloseableReference<Bitmap>? =
      convertToBitmapReferenceAndClose(animatedFrameCache[frameNumber])

  @Synchronized
  override fun getFallbackFrame(frameNumber: Int): CloseableReference<Bitmap>? =
      convertToBitmapReferenceAndClose(CloseableReference.cloneOrNull(lastRenderedItem))

  @Synchronized
  override fun getBitmapToReuseForFrame(
      frameNumber: Int,
      width: Int,
      height: Int,
  ): CloseableReference<Bitmap>? {
    if (!enableBitmapReusing) {
      return null
    }
    return convertToBitmapReferenceAndClose(animatedFrameCache.forReuse)
  }

  @Synchronized
  override fun contains(frameNumber: Int): Boolean = animatedFrameCache.contains(frameNumber)

  @get:Synchronized
  override val sizeInBytes: Int
    get() = // This currently does not include the size of the animated frame cache
    getBitmapSizeBytes(lastRenderedItem) + preparedPendingFramesSizeBytes

  @Synchronized
  override fun clear() {
    CloseableReference.closeSafely(lastRenderedItem)
    lastRenderedItem = null
    for (i in 0 until preparedPendingFrames.size()) {
      CloseableReference.closeSafely(preparedPendingFrames.valueAt(i))
    }
    preparedPendingFrames.clear()
    // The frame cache will free items when needed
  }

  @Synchronized
  override fun onFrameRendered(
      frameNumber: Int,
      bitmapReference: CloseableReference<Bitmap>,
      @BitmapAnimationBackend.FrameType frameType: Int,
  ) {
    checkNotNull(bitmapReference)

    // Close up prepared references.
    removePreparedReference(frameNumber)

    // Create the new image reference and cache it.
    var closableReference: CloseableReference<CloseableImage?>? = null
    try {
      closableReference = createImageReference(bitmapReference)
      if (closableReference != null) {
        CloseableReference.closeSafely(lastRenderedItem)
        lastRenderedItem = animatedFrameCache.cache(frameNumber, closableReference)
      }
    } finally {
      CloseableReference.closeSafely(closableReference)
    }
  }

  @Synchronized
  override fun onFramePrepared(
      frameNumber: Int,
      bitmapReference: CloseableReference<Bitmap>,
      @BitmapAnimationBackend.FrameType frameType: Int,
  ) {
    checkNotNull(bitmapReference)
    var closableReference: CloseableReference<CloseableImage?>? = null
    try {
      closableReference = createImageReference(bitmapReference)
      if (closableReference == null) {
        return
      }
      val newReference = animatedFrameCache.cache(frameNumber, closableReference)
      if (CloseableReference.isValid(newReference)) {
        val oldReference = preparedPendingFrames[frameNumber]
        CloseableReference.closeSafely(oldReference)
        // For performance reasons, we don't clone the reference and close the original one
        // but cache the reference directly.
        preparedPendingFrames.put(frameNumber, newReference)
        FLog.v(
            TAG,
            "cachePreparedFrame(%d) cached. Pending frames: %s",
            frameNumber,
            preparedPendingFrames,
        )
      }
    } finally {
      CloseableReference.closeSafely(closableReference)
    }
  }

  override fun setFrameCacheListener(frameCacheListener: FrameCacheListener?) {
    // TODO (t15557326) Not supported for now
  }

  @get:Synchronized
  private val preparedPendingFramesSizeBytes: Int
    get() {
      var size = 0
      for (i in 0 until preparedPendingFrames.size()) {
        size += getBitmapSizeBytes(preparedPendingFrames.valueAt(i))
      }
      return size
    }

  @Synchronized
  private fun removePreparedReference(frameNumber: Int) {
    val existingPendingReference = preparedPendingFrames[frameNumber]
    if (existingPendingReference != null) {
      preparedPendingFrames.delete(frameNumber)
      CloseableReference.closeSafely(existingPendingReference)
      FLog.v(
          TAG,
          "removePreparedReference(%d) removed. Pending frames: %s",
          frameNumber,
          preparedPendingFrames,
      )
    }
  }

  override fun onAnimationPrepared(frameBitmaps: Map<Int, CloseableReference<Bitmap>>): Boolean =
      true

  override fun isAnimationReady(): Boolean = false

  companion object {
    private val TAG: Class<*> = FrescoFrameCache::class.java

    /**
     * Converts the given image reference to a bitmap reference and closes the original image
     * reference.
     *
     * @param closeableImage the image to convert. It will be closed afterwards and will be invalid
     * @return the closeable bitmap reference to be used
     */
    @JvmStatic
    @VisibleForTesting
    fun convertToBitmapReferenceAndClose(
        closeableImage: CloseableReference<CloseableImage>?
    ): CloseableReference<Bitmap>? {
      try {
        if (
            CloseableReference.isValid(closeableImage) &&
                closeableImage!!.get() is CloseableStaticBitmap
        ) {
          val closeableStaticBitmap = closeableImage.get() as CloseableStaticBitmap
          if (closeableStaticBitmap != null) {
            // We return a clone of the underlying bitmap reference that has to be manually closed
            // and then close the passed CloseableStaticBitmap in order to preserve correct
            // cache size calculations.
            return closeableStaticBitmap.cloneUnderlyingBitmapReference()
          }
        }
        // Not a bitmap reference, so we return null
        return null
      } finally {
        CloseableReference.closeSafely(closeableImage)
      }
    }

    private fun getBitmapSizeBytes(imageReference: CloseableReference<CloseableImage>?): Int {
      if (!CloseableReference.isValid(imageReference)) {
        return 0
      }
      return getBitmapSizeBytes(imageReference!!.get())
    }

    private fun getBitmapSizeBytes(image: CloseableImage?): Int {
      if (image !is CloseableBitmap) {
        return 0
      }
      return BitmapUtil.getSizeInBytes(image.underlyingBitmap)
    }

    private fun createImageReference(
        bitmapReference: CloseableReference<Bitmap>
    ): CloseableReference<CloseableImage?>? {
      // The given CloseableStaticBitmap will be cached and then released by the resource releaser
      // of the closeable reference
      val closeableImage =
          CloseableStaticBitmap.of(bitmapReference, ImmutableQualityInfo.FULL_QUALITY, 0)
      return CloseableReference.of(closeableImage)
    }
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendAnimationInformation.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.wrapper

import com.facebook.fresco.animation.backend.AnimationInformation
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend

/** [AnimationInformation] that wraps an [AnimatedDrawableBackend]. */
class AnimatedDrawableBackendAnimationInformation(
    private val animatedDrawableBackend: AnimatedDrawableBackend
) : AnimationInformation {

  override fun getFrameCount(): Int = animatedDrawableBackend.frameCount

  override fun getFrameDurationMs(frameNumber: Int): Int =
      animatedDrawableBackend.getDurationMsForFrame(frameNumber)

  override fun getLoopCount(): Int = animatedDrawableBackend.loopCount

  override fun getLoopDurationMs(): Int = animatedDrawableBackend.durationMs

  override fun width(): Int = animatedDrawableBackend.width

  override fun height(): Int = animatedDrawableBackend.height
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendFrameRenderer.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.wrapper

import android.graphics.Bitmap
import android.graphics.Rect
import com.facebook.common.logging.FLog
import com.facebook.common.references.CloseableReference
import com.facebook.fresco.animation.bitmap.BitmapFrameCache
import com.facebook.fresco.animation.bitmap.BitmapFrameRenderer
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import com.facebook.imagepipeline.animated.impl.AnimatedImageCompositor
import com.facebook.imagepipeline.animated.impl.AnimatedImageCompositor.Callback

/** [BitmapFrameRenderer] that wraps around an [AnimatedDrawableBackend]. */
class AnimatedDrawableBackendFrameRenderer(
    private val bitmapFrameCache: BitmapFrameCache,
    private var animatedDrawableBackend: AnimatedDrawableBackend,
    private val isNewRenderImplementation: Boolean,
) : BitmapFrameRenderer {

  private var animatedImageCompositor: AnimatedImageCompositor

  private val callback: AnimatedImageCompositor.Callback =
      object : AnimatedImageCompositor.Callback {
        override fun onIntermediateResult(frameNumber: Int, bitmap: Bitmap) {
          // We currently don't cache intermediate bitmaps here
        }

        override fun getCachedBitmap(frameNumber: Int): CloseableReference<Bitmap>? =
            bitmapFrameCache.getCachedFrame(frameNumber)
      }

  override fun setBounds(bounds: Rect?) {
    val newBackend = animatedDrawableBackend.forNewBounds(bounds)
    if (newBackend !== animatedDrawableBackend) {
      animatedDrawableBackend = newBackend
      animatedImageCompositor =
          AnimatedImageCompositor(animatedDrawableBackend, isNewRenderImplementation, callback)
    }
  }

  override val intrinsicWidth: Int
    get() = animatedDrawableBackend.width

  override val intrinsicHeight: Int
    get() = animatedDrawableBackend.height

  init {
    animatedImageCompositor =
        AnimatedImageCompositor(
            this@AnimatedDrawableBackendFrameRenderer.animatedDrawableBackend,
            isNewRenderImplementation,
            callback,
        )
  }

  override fun renderFrame(frameNumber: Int, targetBitmap: Bitmap): Boolean {
    try {
      animatedImageCompositor.renderFrame(frameNumber, targetBitmap)
    } catch (exception: IllegalStateException) {
      FLog.e(TAG, exception, "Rendering of frame unsuccessful. Frame number: %d", frameNumber)
      return false
    }
    return true
  }

  companion object {
    private val TAG: Class<*> = AnimatedDrawableBackendFrameRenderer::class.java
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/drawable/animator/AnimatedDrawableValueAnimatorHelper.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.drawable.animator

import android.animation.ValueAnimator
import android.animation.ValueAnimator.AnimatorUpdateListener
import android.graphics.drawable.Drawable
import com.facebook.fresco.animation.drawable.AnimatedDrawable2
import com.facebook.fresco.animation.drawable.animator.AnimatedDrawable2ValueAnimatorHelper.createValueAnimator

/**
 * Helper class to create [ValueAnimator]s for animated drawables. Currently, this class only
 * supports API 11 (Honeycomb) and above.
 *
 * Supported drawable types: - [AnimatedDrawable2]
 */
object AnimatedDrawableValueAnimatorHelper {

  /**
   * Create a value animator for the given animation drawable and max animation duration in ms.
   *
   * @param drawable the drawable to create the animator for
   * @param maxDurationMs the max duration in ms
   * @return the animator to use
   */
  @JvmStatic
  fun createValueAnimator(drawable: Drawable?, maxDurationMs: Int): ValueAnimator? =
      if (drawable is AnimatedDrawable2) {
        AnimatedDrawable2ValueAnimatorHelper.createValueAnimator(
            checkNotNull((drawable as AnimatedDrawable2?)),
            maxDurationMs,
        )
      } else {
        null
      }

  /**
   * Create a value animator for the given animation drawable.
   *
   * @param drawable the drawable to create the animator for
   * @return the animator to use
   */
  @JvmStatic
  fun createValueAnimator(drawable: Drawable?): ValueAnimator? {
    if (drawable is AnimatedDrawable2) {
      val animatedDrawable2 = drawable
      return createValueAnimator(
          animatedDrawable2,
          animatedDrawable2.loopCount,
          animatedDrawable2.loopDurationMs,
      )
    }
    return null
  }

  /**
   * Create an animator update listener to be used to update the drawable to be animated.
   *
   * @param drawable the drawable to create the animator update listener for
   * @return the listener to use
   */
  @JvmStatic
  fun createAnimatorUpdateListener(drawable: Drawable?): AnimatorUpdateListener? =
      if (drawable is AnimatedDrawable2) {
        AnimatedDrawable2ValueAnimatorHelper.createAnimatorUpdateListener(
            checkNotNull((drawable as AnimatedDrawable2?))
        )
      } else {
        null
      }
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/factory/AnimatedFactoryV2Impl.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.factory

import android.content.Context
import android.graphics.Rect
import com.facebook.cache.common.CacheKey
import com.facebook.common.executors.DefaultSerialExecutorService
import com.facebook.common.executors.SerialExecutorService
import com.facebook.common.executors.UiThreadImmediateExecutorService
import com.facebook.common.internal.DoNotStrip
import com.facebook.common.internal.Supplier
import com.facebook.common.internal.Suppliers
import com.facebook.common.time.RealtimeSinceBootClock
import com.facebook.fresco.animation.bitmap.preparation.ondemandanimation.FrameLoaderListener
import com.facebook.fresco.animation.drawable.AnimatedDrawable2
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import com.facebook.imagepipeline.animated.base.AnimatedImageResult
import com.facebook.imagepipeline.animated.factory.AnimatedFactory
import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendImpl
import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendProvider
import com.facebook.imagepipeline.animated.util.AnimatedDrawableUtil
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
import com.facebook.imagepipeline.cache.CountingMemoryCache
import com.facebook.imagepipeline.core.ExecutorSupplier
import com.facebook.imagepipeline.drawable.DrawableFactory
import com.facebook.imagepipeline.image.CloseableImage
import javax.annotation.concurrent.NotThreadSafe

/**
 * [AnimatedFactory] implementation for animations v2 that creates [AnimatedDrawable2] drawables.
 *
 * This factory handles the creation of animated drawables for GIF and WebP formats. It manages the
 * backend providers and utilities needed for animation processing.
 */
@NotThreadSafe
@DoNotStrip
class AnimatedFactoryV2Impl
@DoNotStrip
constructor(
    private val platformBitmapFactory: PlatformBitmapFactory,
    private val executorSupplier: ExecutorSupplier,
    private val backingCache: CountingMemoryCache<CacheKey, CloseableImage>,
    private val downscaleFrameToDrawableDimensions: Boolean,
    private val useBufferLoaderStrategy: Boolean,
    var animationFpsLimit: Int,
    var bufferLengthMilliseconds: Int,
    var serialExecutorService: SerialExecutorService?,
    private val enableBufferFrameLoaderFix: Boolean = false,
    private val frameLoaderListener: FrameLoaderListener? = null,
    private val enableSingleFrameRendering: Boolean = false,
) : AnimatedFactory {

  private var animatedDrawableBackendProvider: AnimatedDrawableBackendProvider? = null
  private var animatedDrawableUtil: AnimatedDrawableUtil? = null
  private var animatedDrawableFactory: DrawableFactory? = null

  override fun getAnimatedDrawableFactory(context: Context?): DrawableFactory? {
    if (animatedDrawableFactory == null) {
      animatedDrawableFactory = createDrawableFactory()
    }
    return animatedDrawableFactory
  }

  private fun createDrawableFactory(): DefaultBitmapAnimationDrawableFactory {
    val cachingStrategySupplier: Supplier<Int> = Supplier {
      DefaultBitmapAnimationDrawableFactory.CACHING_STRATEGY_FRESCO_CACHE_NO_REUSING
    }

    val finalSerialExecutorService =
        serialExecutorService ?: DefaultSerialExecutorService(executorSupplier.forDecode())

    val numberOfFramesToPrepareSupplier: Supplier<Int> = Supplier { NUMBER_OF_FRAMES_TO_PREPARE }

    val useDeepEquals = Suppliers.BOOLEAN_FALSE

    return DefaultBitmapAnimationDrawableFactory(
        getAnimatedDrawableBackendProvider(),
        UiThreadImmediateExecutorService.getInstance(),
        finalSerialExecutorService,
        RealtimeSinceBootClock.get(),
        platformBitmapFactory,
        backingCache,
        cachingStrategySupplier,
        numberOfFramesToPrepareSupplier,
        useDeepEquals,
        Suppliers.of(useBufferLoaderStrategy),
        Suppliers.of(downscaleFrameToDrawableDimensions),
        Suppliers.of(animationFpsLimit),
        Suppliers.of(bufferLengthMilliseconds),
        null,
        enableBufferFrameLoaderFix,
        frameLoaderListener,
        enableSingleFrameRendering,
    )
  }

  private fun getAnimatedDrawableUtil(): AnimatedDrawableUtil {
    return animatedDrawableUtil ?: AnimatedDrawableUtil().also { animatedDrawableUtil = it }
  }

  private fun getAnimatedDrawableBackendProvider(): AnimatedDrawableBackendProvider {
    if (animatedDrawableBackendProvider == null) {
      animatedDrawableBackendProvider =
          object : AnimatedDrawableBackendProvider {
            override fun get(
                animatedImageResult: AnimatedImageResult,
                bounds: Rect?,
            ): AnimatedDrawableBackend {
              return AnimatedDrawableBackendImpl(
                  getAnimatedDrawableUtil(),
                  animatedImageResult,
                  bounds,
                  downscaleFrameToDrawableDimensions,
              )
            }
          }
    }
    return animatedDrawableBackendProvider as AnimatedDrawableBackendProvider
  }

  companion object {
    private const val NUMBER_OF_FRAMES_TO_PREPARE = 3
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/fresco/animation/factory/DefaultBitmapAnimationDrawableFactory.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.factory

import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Rect
import android.graphics.drawable.Drawable
import com.facebook.cache.common.CacheKey
import com.facebook.common.internal.Preconditions
import com.facebook.common.internal.Supplier
import com.facebook.common.internal.Suppliers
import com.facebook.common.time.MonotonicClock
import com.facebook.fresco.animation.backend.AnimationBackend
import com.facebook.fresco.animation.backend.AnimationBackendDelegateWithInactivityCheck
import com.facebook.fresco.animation.bitmap.BitmapAnimationBackend
import com.facebook.fresco.animation.bitmap.BitmapFrameCache
import com.facebook.fresco.animation.bitmap.BitmapFrameRenderer
import com.facebook.fresco.animation.bitmap.cache.AnimationFrameCacheKey
import com.facebook.fresco.animation.bitmap.cache.FrescoFrameCache
import com.facebook.fresco.animation.bitmap.cache.KeepLastFrameCache
import com.facebook.fresco.animation.bitmap.cache.NoOpCache
import com.facebook.fresco.animation.bitmap.preparation.BitmapFramePreparationStrategy
import com.facebook.fresco.animation.bitmap.preparation.BitmapFramePreparer
import com.facebook.fresco.animation.bitmap.preparation.DefaultBitmapFramePreparer
import com.facebook.fresco.animation.bitmap.preparation.FixedNumberBitmapFramePreparationStrategy
import com.facebook.fresco.animation.bitmap.preparation.FrameLoaderStrategy
import com.facebook.fresco.animation.bitmap.preparation.ondemandanimation.FrameLoaderFactory
import com.facebook.fresco.animation.bitmap.preparation.ondemandanimation.FrameLoaderListener
import com.facebook.fresco.animation.bitmap.wrapper.AnimatedDrawableBackendAnimationInformation
import com.facebook.fresco.animation.bitmap.wrapper.AnimatedDrawableBackendFrameRenderer
import com.facebook.fresco.animation.drawable.AnimatedDrawable2
import com.facebook.fresco.animation.drawable.KAnimatedDrawable2
import com.facebook.fresco.middleware.HasExtraData
import com.facebook.fresco.vito.core.AnimatedImagePerfLoggingListener
import com.facebook.fresco.vito.options.ImageOptions
import com.facebook.fresco.vito.options.ImageOptionsDrawableFactory
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import com.facebook.imagepipeline.animated.base.AnimatedImageResult
import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendProvider
import com.facebook.imagepipeline.animated.impl.AnimatedFrameCache
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
import com.facebook.imagepipeline.cache.CountingMemoryCache
import com.facebook.imagepipeline.drawable.DrawableFactory
import com.facebook.imagepipeline.image.CloseableAnimatedImage
import com.facebook.imagepipeline.image.CloseableImage
import java.util.concurrent.ExecutorService
import java.util.concurrent.ScheduledExecutorService

/** Animation factory for [AnimatedDrawable2]. */
class DefaultBitmapAnimationDrawableFactory(
    private val animatedDrawableBackendProvider: AnimatedDrawableBackendProvider,
    private val scheduledExecutorServiceForUiThread: ScheduledExecutorService,
    private val executorServiceForFramePreparing: ExecutorService,
    private val monotonicClock: MonotonicClock,
    private val platformBitmapFactory: PlatformBitmapFactory,
    private val backingCache: CountingMemoryCache<CacheKey, CloseableImage>?,
    private val cachingStrategySupplier: Supplier<Int>,
    private val numberOfFramesToPrepareSupplier: Supplier<Int>,
    private val useDeepEqualsForCacheKey: Supplier<Boolean>,
    private val useNewBitmapRender: Supplier<Boolean>,
    private val downscaleFrameToDrawableDimensions: Supplier<Boolean>,
    private val animationFpsLimit: Supplier<Int>,
    private val bufferLengthMilliseconds: Supplier<Int>,
    private val animatedImagePerfLoggingListener: AnimatedImagePerfLoggingListener? = null,
    private val enableBufferFrameLoaderFix: Boolean = false,
    private val frameLoaderListener: FrameLoaderListener? = null,
    private val enableSingleFrameRendering: Boolean = false,
) : DrawableFactory, ImageOptionsDrawableFactory {

  // Change the value to true to use KAnimatedDrawable2.kt
  private val useRendererAnimatedDrawable: Supplier<Boolean> = Suppliers.BOOLEAN_FALSE

  override fun supportsImageType(image: CloseableImage): Boolean {
    return image is CloseableAnimatedImage
  }

  override fun createDrawable(image: CloseableImage): Drawable? {
    if (!supportsImageType(image)) {
      return null
    }
    val closeable = image as CloseableAnimatedImage
    val animatedImage = closeable.image

    val animationBackend =
        createAnimationBackend(
            Preconditions.checkNotNull(closeable.imageResult),
            animatedImage?.animatedBitmapConfig,
            null,
        )
    return if (useRendererAnimatedDrawable.get()) {
      KAnimatedDrawable2(animationBackend)
    } else {
      AnimatedDrawable2(animationBackend)
    }
  }

  override fun createDrawable(
      resources: Resources,
      closeableImage: CloseableImage,
      imageOptions: ImageOptions,
  ): Drawable? {
    if (!supportsImageType(closeableImage)) {
      return null
    }
    val closeable = closeableImage as CloseableAnimatedImage
    val animatedImage = closeable.image

    // Log drawable creation start
    val imageId =
        closeable.imageResult?.source ?: "unknown_${System.identityHashCode(closeableImage)}"
    val startTime = System.nanoTime()
    animatedImagePerfLoggingListener?.onDrawableCreationStart(imageId, startTime)

    val animationBackend: AnimationBackend =
        runCatching {
              createAnimationBackend(
                  Preconditions.checkNotNull(closeable.imageResult),
                  animatedImage?.animatedBitmapConfig,
                  imageOptions,
              )
            }
            .getOrElse { e ->
              when (e) {
                is NullPointerException -> {
                  val uri = closeableImage.getExtra<Any?>(HasExtraData.KEY_URI_SOURCE)
                  if (uri != null) {
                    throw NullPointerException("${e.message} uri=${uri}")
                  } else {
                    throw e
                  }
                }
                else -> throw e
              }
            }

    val drawable =
        if (useRendererAnimatedDrawable.get()) {
          KAnimatedDrawable2(animationBackend)
        } else {
          AnimatedDrawable2(animationBackend)
        }

    // Log drawable creation success
    val endTime = System.nanoTime()
    animatedImagePerfLoggingListener?.onDrawableCreationEnd(imageId, endTime, true)

    return drawable
  }

  /**
   * Creates an animation backend for the given animated image result. * * @param
   * animatedImageResult The animated image result to create a backend for
   *
   * @param animatedBitmapConfig Optional bitmap configuration for the animation
   * @param imageOptions Optional image options for customizing the animation
   * @return An animation backend for the given parameters
   */
  private fun createAnimationBackend(
      animatedImageResult: AnimatedImageResult,
      animatedBitmapConfig: Bitmap.Config?,
      imageOptions: ImageOptions?,
  ): AnimationBackend {
    val animatedDrawableBackend = createAnimatedDrawableBackend(animatedImageResult)
    val animationInfo = AnimatedDrawableBackendAnimationInformation(animatedDrawableBackend)

    val bitmapFrameCache = createBitmapFrameCache(animatedImageResult)
    val bitmapFrameRenderer =
        AnimatedDrawableBackendFrameRenderer(
            bitmapFrameCache,
            animatedDrawableBackend,
            useNewBitmapRender.get(),
        )

    val numberOfFramesToPrefetch = numberOfFramesToPrepareSupplier.get()
    var bitmapFramePreparationStrategy: BitmapFramePreparationStrategy? = null
    var bitmapFramePreparer: BitmapFramePreparer? = null
    if (numberOfFramesToPrefetch > 0) {
      bitmapFramePreparationStrategy =
          FixedNumberBitmapFramePreparationStrategy(numberOfFramesToPrefetch)
      bitmapFramePreparer = createBitmapFramePreparer(bitmapFrameRenderer, animatedBitmapConfig)
    }

    val roundingOptions = imageOptions?.roundingOptions

    val animatedOptions = imageOptions?.animatedOptions

    if (useNewBitmapRender.get()) {
      bitmapFramePreparationStrategy =
          FrameLoaderStrategy(
              animatedImageResult.source,
              animationInfo,
              bitmapFrameRenderer,
              FrameLoaderFactory(
                  platformBitmapFactory,
                  animationFpsLimit.get(),
                  bufferLengthMilliseconds.get(),
                  enableBufferFrameLoaderFix,
                  frameLoaderListener,
                  enableSingleFrameRendering,
              ),
              downscaleFrameToDrawableDimensions.get(),
          )
    }

    val bitmapAnimationBackend =
        BitmapAnimationBackend(
            platformBitmapFactory,
            bitmapFrameCache,
            animationInfo,
            bitmapFrameRenderer,
            useNewBitmapRender.get(),
            bitmapFramePreparationStrategy,
            bitmapFramePreparer,
            roundingOptions,
            animatedOptions,
        )

    // Set the animated image performance logging listener
    bitmapAnimationBackend.setAnimatedImagePerfLoggingListener(animatedImagePerfLoggingListener)

    return AnimationBackendDelegateWithInactivityCheck.createForBackend(
        bitmapAnimationBackend,
        monotonicClock,
        scheduledExecutorServiceForUiThread,
    )
  }

  private fun createBitmapFramePreparer(
      bitmapFrameRenderer: BitmapFrameRenderer,
      animatedBitmapConfig: Bitmap.Config?,
  ): BitmapFramePreparer {
    return DefaultBitmapFramePreparer(
        platformBitmapFactory,
        bitmapFrameRenderer,
        animatedBitmapConfig ?: Bitmap.Config.ARGB_8888,
        executorServiceForFramePreparing,
    )
  }

  private fun createAnimatedDrawableBackend(
      animatedImageResult: AnimatedImageResult
  ): AnimatedDrawableBackend {
    val animatedImage = animatedImageResult.image
    val initialBounds = Rect(0, 0, animatedImage.width, animatedImage.height)
    return animatedDrawableBackendProvider.get(animatedImageResult, initialBounds)
  }

  private fun createBitmapFrameCache(animatedImageResult: AnimatedImageResult): BitmapFrameCache {
    return when (cachingStrategySupplier.get()) {
      CACHING_STRATEGY_FRESCO_CACHE ->
          FrescoFrameCache(createAnimatedFrameCache(animatedImageResult), true)
      CACHING_STRATEGY_FRESCO_CACHE_NO_REUSING ->
          FrescoFrameCache(createAnimatedFrameCache(animatedImageResult), false)
      CACHING_STRATEGY_KEEP_LAST_CACHE -> KeepLastFrameCache()
      CACHING_STRATEGY_NO_CACHE -> NoOpCache()
      else -> NoOpCache()
    }
  }

  private fun createAnimatedFrameCache(
      animatedImageResult: AnimatedImageResult
  ): AnimatedFrameCache {
    return AnimatedFrameCache(
        AnimationFrameCacheKey(animatedImageResult.hashCode(), useDeepEqualsForCacheKey.get()),
        backingCache ?: throw IllegalStateException("backingCache is null"),
    )
  }

  companion object {
    const val CACHING_STRATEGY_NO_CACHE = 0
    const val CACHING_STRATEGY_FRESCO_CACHE = 1
    const val CACHING_STRATEGY_FRESCO_CACHE_NO_REUSING = 2
    const val CACHING_STRATEGY_KEEP_LAST_CACHE = 3
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableBackend.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import com.facebook.common.references.CloseableReference;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/**
 * Interface that {@link com.facebook.fresco.animation.drawable.BaseAnimatedDrawable} uses that
 * abstracts out the image format.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public interface AnimatedDrawableBackend {

  /**
   * Gets the original result of the decode.
   *
   * @return the original result of the code
   */
  AnimatedImageResult getAnimatedImageResult();

  /**
   * Gets the duration of the animation.
   *
   * @return the duration of the animation in milliseconds
   */
  int getDurationMs();

  /**
   * Gets the number of frames in the animation.
   *
   * @return the number of frames in the animation
   */
  int getFrameCount();

  /**
   * Gets the number of loops to run the animation for.
   *
   * @return the number of loops, or 0 to indicate infinite
   */
  int getLoopCount();

  /**
   * Gets the width of the image.
   *
   * @return the width of the image
   */
  int getWidth();

  /**
   * Gets the height of the image.
   *
   * @return the height of the image
   */
  int getHeight();

  /**
   * Gets the rendered width of the image. This may be smaller than the underlying image width if
   * the image is being rendered to a small bounds or to reduce memory requirements.
   *
   * @return the rendered width of the image
   */
  int getRenderedWidth();

  /**
   * Gets the rendered height of the image. This may be smaller than the underlying image height if
   * the image is being rendered to a small bounds or to reduce memory requirements.
   *
   * @return the rendered height of the image
   */
  int getRenderedHeight();

  /**
   * Gets info about the specified frame.
   *
   * @param frameNumber the frame number (0-based)
   * @return the frame info
   */
  AnimatedDrawableFrameInfo getFrameInfo(int frameNumber);

  /**
   * Renders the specified frame onto the canvas.
   *
   * @param frameNumber the frame number (0-based)
   * @param canvas the canvas to render onto
   */
  void renderFrame(int frameNumber, Canvas canvas);

  /**
   * Renders the specified frame onto the canvas. The idea is the same than renderFrame(...) with
   * this differences: 1) Creates a new bitmap on each call. This allows to not block threads. 2)
   * Blend is applied here
   *
   * @param frameNumber the frame number (0-based)
   * @param canvas the canvas to render onto
   */
  void renderDeltas(int frameNumber, Canvas canvas);

  /**
   * Gets the frame index for specified timestamp.
   *
   * @param timestampMs the timestamp
   * @return the frame index for the timestamp or the last frame number if the timestamp is outside
   *     the duration of the entire animation
   */
  int getFrameForTimestampMs(int timestampMs);

  /**
   * Gets the timestamp relative to the first frame that this frame number starts at.
   *
   * @param frameNumber the frame number
   * @return the time in milliseconds
   */
  int getTimestampMsForFrame(int frameNumber);

  /**
   * Gets the duration of the specified frame.
   *
   * @param frameNumber the frame number
   * @return the time in milliseconds
   */
  int getDurationMsForFrame(int frameNumber);

  /**
   * Gets the frame number to use for the preview frame.
   *
   * @return the frame number to use for the preview frame
   */
  int getFrameForPreview();

  /**
   * Creates a new {@link AnimatedDrawableBackend} with the same parameters but with a new bounds.
   *
   * @param bounds the bounds
   * @return an {@link AnimatedDrawableBackend} with the new bounds (this may be the same instance
   *     if the bounds don't require a new backend)
   */
  AnimatedDrawableBackend forNewBounds(@Nullable Rect bounds);

  /**
   * Gets the number of bytes currently used by the backend for caching (for debugging)
   *
   * @return the number of bytes currently used by the backend for caching
   */
  int getMemoryUsage();

  /**
   * Gets a pre-decoded frame. This will only return non-null if the {@code ImageDecodeOptions} were
   * configured to decode all frames at decode time.
   *
   * @param frameNumber the index of the frame to get
   * @return a reference to the preview bitmap which must be released by the caller when done or
   *     null if there is no preview bitmap set
   */
  @Nullable
  CloseableReference<Bitmap> getPreDecodedFrame(int frameNumber);

  /**
   * Gets whether it has the decoded frame. This will only return true if the {@code
   * ImageDecodeOptions} were configured to decode all frames at decode time.
   *
   * @param frameNumber the index of the frame to get
   * @return true if the result has the decoded frame
   */
  boolean hasPreDecodedFrame(int frameNumber);

  /** Instructs the backend to drop its caches. */
  void dropCaches();
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableFrameInfo.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import com.facebook.infer.annotation.Nullsafe;

/** Info per frame returned by {@link AnimatedDrawableBackend}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedDrawableFrameInfo {

  /** How to dispose of the current frame before rendering the next frame. */
  public enum DisposalMethod {

    /** Do not dipose the frame. Leave as-is. */
    DISPOSE_DO_NOT,

    /** Dispose to the background color */
    DISPOSE_TO_BACKGROUND,

    /** Dispose to the previous frame */
    DISPOSE_TO_PREVIOUS
  }

  /**
   * Indicates how transparent pixels of the current frame are blended with those of the previous
   * canvas.
   */
  public enum BlendOperation {
    /** Blend * */
    BLEND_WITH_PREVIOUS,
    /** Do not blend * */
    NO_BLEND,
  }

  public final int frameNumber;
  public final int xOffset;
  public final int yOffset;
  public final int width;
  public final int height;
  public final BlendOperation blendOperation;
  public final DisposalMethod disposalMethod;

  public AnimatedDrawableFrameInfo(
      int frameNumber,
      int xOffset,
      int yOffset,
      int width,
      int height,
      BlendOperation blendOperation,
      DisposalMethod disposalMethod) {
    this.frameNumber = frameNumber;
    this.xOffset = xOffset;
    this.yOffset = yOffset;
    this.width = width;
    this.height = height;
    this.blendOperation = blendOperation;
    this.disposalMethod = disposalMethod;
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptions.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.concurrent.Immutable;

/** Options for creating {@link com.facebook.fresco.animation.drawable.AnimatedDrawable2}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
@Immutable
public class AnimatedDrawableOptions {

  /** Default options. */
  public static AnimatedDrawableOptions DEFAULTS = AnimatedDrawableOptions.newBuilder().build();

  /** Whether all the rendered frames should be held in memory disregarding other constraints. */
  public final boolean forceKeepAllFramesInMemory;

  /** Whether the drawable can use worker threads to optimistically prefetch frames. */
  public final boolean allowPrefetching;

  /**
   * The maximum bytes that the backend can use to cache image frames in memory or -1 to use the
   * default
   */
  public final int maximumBytes;

  /** Whether to enable additional verbose debugging diagnostics. */
  public final boolean enableDebugging;

  /** Creates {@link AnimatedDrawableOptions} with default options. */
  public AnimatedDrawableOptions(AnimatedDrawableOptionsBuilder builder) {
    this.forceKeepAllFramesInMemory = builder.getForceKeepAllFramesInMemory();
    this.allowPrefetching = builder.getAllowPrefetching();
    this.maximumBytes = builder.getMaximumBytes();
    this.enableDebugging = builder.getEnableDebugging();
  }

  /**
   * Creates a new builder.
   *
   * @return the builder
   */
  public static AnimatedDrawableOptionsBuilder newBuilder() {
    return new AnimatedDrawableOptionsBuilder();
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptionsBuilder.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import com.facebook.infer.annotation.Nullsafe;

/** Builder for {@link AnimatedDrawableOptions}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedDrawableOptionsBuilder {

  private boolean mForceKeepAllFramesInMemory;
  private boolean mAllowPrefetching = true;
  private int mMaximumBytes = -1;
  private boolean mEnableDebugging;

  /**
   * Gets whether all the rendered frames should be held in memory disregarding other constraints.
   *
   * @return whether all the rendered frames should be held in memory
   */
  public boolean getForceKeepAllFramesInMemory() {
    return mForceKeepAllFramesInMemory;
  }

  /**
   * Sets whether all the rendered frames should be held in memory disregarding other constraints.
   *
   * @param forceKeepAllFramesInMemory whether to force the frames to be held in memory
   * @return this builder
   */
  public AnimatedDrawableOptionsBuilder setForceKeepAllFramesInMemory(
      boolean forceKeepAllFramesInMemory) {
    mForceKeepAllFramesInMemory = forceKeepAllFramesInMemory;
    return this;
  }

  /**
   * Gets whether the drawable can use worker threads to optimistically prefetch frames.
   *
   * @return whether the backend can use worker threads to prefetch frames
   */
  public boolean getAllowPrefetching() {
    return mAllowPrefetching;
  }

  /**
   * Sets whether the drawable can use worker threads to optimistically prefetch frames.
   *
   * @param allowPrefetching whether the backend can use worker threads to prefetch frames
   * @return this builder
   */
  public AnimatedDrawableOptionsBuilder setAllowPrefetching(boolean allowPrefetching) {
    mAllowPrefetching = allowPrefetching;
    return this;
  }

  /**
   * Gets the maximum bytes that the backend can use to cache image frames in memory.
   *
   * @return maximumBytes maximum bytes that the backend can use to cache image frames in memory or
   *     -1 to use the default
   */
  public int getMaximumBytes() {
    return mMaximumBytes;
  }

  /**
   * Sets the maximum bytes that the backend can use to cache image frames in memory.
   *
   * @param maximumBytes maximum bytes that the backend can use to cache image frames in memory or
   *     -1 to use the default
   * @return this builder
   */
  public AnimatedDrawableOptionsBuilder setMaximumBytes(int maximumBytes) {
    mMaximumBytes = maximumBytes;
    return this;
  }

  /**
   * Gets whether to enable additional verbose debugging diagnostics.
   *
   * @return whether to enable additional verbose debugging diagnostics
   */
  public boolean getEnableDebugging() {
    return mEnableDebugging;
  }

  /**
   * Sets whether to enable additional verbose debugging diagnostics.
   *
   * @param enableDebugging whether to enable additional verbose debugging diagnostics
   * @return this builder
   */
  public AnimatedDrawableOptionsBuilder setEnableDebugging(boolean enableDebugging) {
    mEnableDebugging = enableDebugging;
    return this;
  }

  /**
   * Builds the immutable options instance.
   *
   * @return the options instance
   */
  public AnimatedDrawableOptions build() {
    return new AnimatedDrawableOptions(this);
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImage.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import android.graphics.Bitmap;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/** Common interface for an animated image. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public interface AnimatedImage {

  int LOOP_COUNT_INFINITE = 0;

  /**
   * Disposes the instance. This will free native resources held by this instance. Once called,
   * other methods on this instance may throw. Note, the underlying native resources may not
   * actually be freed until all associated instances of {@link AnimatedImageFrame} are disposed or
   * finalized as well.
   */
  void dispose();

  /**
   * Gets the width of the image (also known as the canvas in WebP nomenclature).
   *
   * @return the width of the image
   */
  int getWidth();

  /**
   * Gets the height of the image (also known as the canvas in WebP nomenclature).
   *
   * @return the height of the image
   */
  int getHeight();

  /**
   * Gets the number of frames in the image.
   *
   * @return the number of frames in the image
   */
  int getFrameCount();

  /**
   * Gets the duration of the animated image.
   *
   * @return the duration of the animated image in milliseconds
   */
  int getDuration();

  /**
   * Gets the duration of each frame of the animated image.
   *
   * @return an array that is the size of the number of frames containing the duration of each frame
   *     in milliseconds
   */
  int[] getFrameDurations();

  /**
   * Gets the number of loops to run the animation for.
   *
   * @return the number of loops, or 0 to indicate infinite
   */
  int getLoopCount();

  /**
   * Creates an {@link AnimatedImageFrame} at the specified index.
   *
   * @param frameNumber the index of the frame
   * @return a newly created {@link AnimatedImageFrame}
   */
  AnimatedImageFrame getFrame(int frameNumber);

  /**
   * Returns whether {@link AnimatedImageFrame#renderFrame} supports scaling to arbitrary sizes or
   * whether scaling must be done externally.
   *
   * @return whether rendering supports scaling
   */
  boolean doesRenderSupportScaling();

  /**
   * Gets the size of bytes of the encoded image data (which is the data kept in memory for the
   * image).
   *
   * @return the size in bytes of the encoded image data
   */
  int getSizeInBytes();

  /**
   * Gets the frame info for the specified frame.
   *
   * @param frameNumber the frame to get the info for
   * @return the frame info
   */
  AnimatedDrawableFrameInfo getFrameInfo(int frameNumber);

  /**
   * Gets the Bitmap.Config to decode the Bitmap of Animated Frames.
   *
   * @return Bitmap.Config for Animated Image
   */
  @Nullable
  Bitmap.Config getAnimatedBitmapConfig();
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageFrame.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import android.graphics.Bitmap;
import com.facebook.infer.annotation.Nullsafe;

/** Common interface for a frame of an animated image. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public interface AnimatedImageFrame {

  /**
   * Disposes the instance. This will free native resources held by this instance. Once called,
   * other methods on this instance may throw. Note, the underlying native resources may not
   * actually be freed until all associated instances {@link AnimatedImage} are disposed or
   * finalized as well.
   */
  void dispose();

  /**
   * Renders the frame to the specified bitmap. The bitmap must have a width and height that is at
   * least as big as the specified width and height and it must be in RGBA_8888 color format.
   *
   * @param width the width to render to (the image is scaled to this width)
   * @param height the height to render to (the image is scaled to this height)
   * @param bitmap the bitmap to render into
   */
  void renderFrame(int width, int height, Bitmap bitmap);

  /**
   * Gets the duration of the frame.
   *
   * @return the duration of the frame in milliseconds
   */
  int getDurationMs();

  /**
   * Gets the width of the frame.
   *
   * @return the width of the frame
   */
  int getWidth();

  /**
   * Gets the height of the frame.
   *
   * @return the height of the frame
   */
  int getHeight();

  /**
   * Gets the x-offset of the frame relative to the image canvas.
   *
   * @return the x-offset of the frame
   */
  int getXOffset();

  /**
   * Gets the y-offset of the frame relative to the image canvas.
   *
   * @return the y-offset of the frame
   */
  int getYOffset();
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResult.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import android.graphics.Bitmap;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.transformation.BitmapTransformation;
import com.facebook.infer.annotation.Nullsafe;
import java.util.List;
import javax.annotation.Nullable;

/**
 * The result of decoding an animated image. Contains the {@link AnimatedImage} as well as
 * additional data.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedImageResult {

  private final AnimatedImage mImage;
  private final int mFrameForPreview;
  private @Nullable String mSource;
  private @Nullable CloseableReference<Bitmap> mPreviewBitmap;
  private @Nullable List<CloseableReference<Bitmap>> mDecodedFrames;
  private @Nullable BitmapTransformation mBitmapTransformation;

  AnimatedImageResult(AnimatedImageResultBuilder builder) {
    mImage = Preconditions.checkNotNull(builder.getImage(), "AnimatedImage cannot be null");
    mFrameForPreview = builder.getFrameForPreview();
    mPreviewBitmap = builder.getPreviewBitmap();
    mDecodedFrames = builder.getDecodedFrames();
    mBitmapTransformation = builder.getBitmapTransformation();
    mSource = builder.getSource();
  }

  private AnimatedImageResult(AnimatedImage image) {
    mImage = Preconditions.checkNotNull(image, "AnimatedImage cannot be null");
    mFrameForPreview = 0;
  }

  /**
   * Creates an {@link AnimatedImageResult} with no additional options.
   *
   * @param image the image
   * @return the result
   */
  public static AnimatedImageResult forAnimatedImage(AnimatedImage image) {
    return new AnimatedImageResult(image);
  }

  /**
   * Creates an {@link AnimatedImageResultBuilder} for creating an {@link AnimatedImageResult}.
   *
   * @param image the image
   * @return the builder
   */
  public static AnimatedImageResultBuilder newBuilder(AnimatedImage image) {
    return new AnimatedImageResultBuilder(image);
  }

  /**
   * Gets the underlying image.
   *
   * @return the underlying image
   */
  public AnimatedImage getImage() {
    return mImage;
  }

  /**
   * Gets the animated result source uri
   *
   * @return source uri
   */
  @Nullable
  public String getSource() {
    return mSource;
  }

  /**
   * Gets the frame that should be used for the preview image. If the preview bitmap was fetched,
   * this is the frame that it's for.
   *
   * @return the frame that should be used for the preview image
   */
  public int getFrameForPreview() {
    return mFrameForPreview;
  }

  /**
   * Gets a decoded frame. This will only return non-null if the {@code ImageDecodeOptions} were
   * configured to decode all frames at decode time.
   *
   * @param index the index of the frame to get
   * @return a reference to the preview bitmap which must be released by the caller when done or
   *     null if there is no preview bitmap set
   */
  public synchronized @Nullable CloseableReference<Bitmap> getDecodedFrame(int index) {
    if (mDecodedFrames != null) {
      return CloseableReference.cloneOrNull(mDecodedFrames.get(index));
    }
    return null;
  }

  /**
   * Gets whether it has the decoded frame. This will only return true if the {@code
   * ImageDecodeOptions} were configured to decode all frames at decode time.
   *
   * @param index the index of the frame to get
   * @return true if the result has the decoded frame
   */
  public synchronized boolean hasDecodedFrame(int index) {
    return mDecodedFrames != null && mDecodedFrames.get(index) != null;
  }

  /**
   * Gets the transformation that is to be applied to the image, or null if none.
   *
   * @return the transformation that is to be applied to the image, or null if none
   */
  public @Nullable BitmapTransformation getBitmapTransformation() {
    return mBitmapTransformation;
  }

  /**
   * Gets the bitmap for the preview frame. This will only return non-null if the {@code
   * ImageDecodeOptions} were configured to decode the preview frame.
   *
   * @return a reference to the preview bitmap which must be released by the caller when done or
   *     null if there is no preview bitmap set
   */
  @Nullable
  public synchronized CloseableReference<Bitmap> getPreviewBitmap() {
    return CloseableReference.cloneOrNull(mPreviewBitmap);
  }

  /** Disposes the result, which releases the reference to any bitmaps. */
  public synchronized void dispose() {
    CloseableReference.closeSafely(mPreviewBitmap);
    mPreviewBitmap = null;
    CloseableReference.closeSafely(mDecodedFrames);
    mDecodedFrames = null;
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResultBuilder.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base;

import android.graphics.Bitmap;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.transformation.BitmapTransformation;
import com.facebook.infer.annotation.Nullsafe;
import java.util.List;
import javax.annotation.Nullable;

/** Builder for {@link AnimatedImageResult}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedImageResultBuilder {

  private final AnimatedImage mImage;
  private @Nullable CloseableReference<Bitmap> mPreviewBitmap;
  private @Nullable List<CloseableReference<Bitmap>> mDecodedFrames;
  private int mFrameForPreview;
  private @Nullable BitmapTransformation mBitmapTransformation;
  private @Nullable String mSource;

  AnimatedImageResultBuilder(AnimatedImage image) {
    mImage = image;
  }

  /**
   * Gets the image for the result.
   *
   * @return the image
   */
  public AnimatedImage getImage() {
    return mImage;
  }

  /**
   * Gets the preview bitmap. This method returns a new reference. The caller must close it.
   *
   * @return the reference to the preview bitmap or null if none was set. This returns a reference
   *     that must be released by the caller
   */
  public @Nullable CloseableReference<Bitmap> getPreviewBitmap() {
    return CloseableReference.cloneOrNull(mPreviewBitmap);
  }

  /**
   * Sets a preview bitmap.
   *
   * @param previewBitmap the preview. The method clones the reference.
   * @return this builder
   */
  public AnimatedImageResultBuilder setPreviewBitmap(
      @Nullable CloseableReference<Bitmap> previewBitmap) {
    mPreviewBitmap = CloseableReference.cloneOrNull(previewBitmap);
    return this;
  }

  /**
   * Gets the frame that should be used for the preview image. If the preview bitmap was fetched,
   * this is the frame that it's for.
   *
   * @return the frame that should be used for the preview image
   */
  public int getFrameForPreview() {
    return mFrameForPreview;
  }

  /**
   * Sets the frame that should be used for the preview image. If the preview bitmap was fetched,
   * this is the frame that it's for.
   *
   * @return the frame that should be used for the preview image
   */
  public AnimatedImageResultBuilder setFrameForPreview(int frameForPreview) {
    mFrameForPreview = frameForPreview;
    return this;
  }

  /**
   * Gets the decoded frames. Only used if the {@code ImageDecodeOptions} were configured to decode
   * all frames at decode time.
   *
   * @return the references to the decoded frames or null if none was set. This returns references
   *     that must be released by the caller
   */
  public @Nullable List<CloseableReference<Bitmap>> getDecodedFrames() {
    return CloseableReference.cloneOrNull(mDecodedFrames);
  }

  /**
   * @return animated image uri path
   */
  @Nullable
  public String getSource() {
    return mSource;
  }

  /**
   * Sets the decoded frames. Only used if the {@code ImageDecodeOptions} were configured to decode
   * all frames at decode time.
   *
   * @param decodedFrames the decoded frames. The method clones the references.
   */
  public AnimatedImageResultBuilder setDecodedFrames(
      @Nullable List<CloseableReference<Bitmap>> decodedFrames) {
    mDecodedFrames = CloseableReference.cloneOrNull(decodedFrames);
    return this;
  }

  /**
   * Gets the transformation that is to be applied to the image, or null if none.
   *
   * @return the transformation that is to be applied to the image, or null if none
   */
  @Nullable
  public BitmapTransformation getBitmapTransformation() {
    return mBitmapTransformation;
  }

  /**
   * Sets the transformation that is to be applied to the image.
   *
   * @param bitmapTransformation the transformation that is to be applied to the image
   */
  public AnimatedImageResultBuilder setBitmapTransformation(
      @Nullable BitmapTransformation bitmapTransformation) {
    mBitmapTransformation = bitmapTransformation;
    return this;
  }

  /**
   * Sets the source of the animated image
   *
   * @param source uri path
   * @return bitmapTransformation the transformation that is to be applied to the image
   */
  public AnimatedImageResultBuilder setSource(@Nullable String source) {
    mSource = source;
    return this;
  }

  /**
   * Builds the {@link AnimatedImageResult}. The preview bitmap and the decoded frames are closed
   * after build is called, so this should not be called more than once or those fields will be lost
   * after the first call.
   *
   * @return the result
   */
  public AnimatedImageResult build() {
    try {
      return new AnimatedImageResult(this);
    } finally {
      CloseableReference.closeSafely(mPreviewBitmap);
      mPreviewBitmap = null;
      CloseableReference.closeSafely(mDecodedFrames);
      mDecodedFrames = null;
    }
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageValidator.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.base

import com.facebook.imagepipeline.image.EncodedImage

interface AnimatedImageValidator {
  fun validateImage(encodedImage: EncodedImage): ValidationResult
}

sealed class ValidationResult(val isValid: Boolean, val message: String? = null) {

  object Success : ValidationResult(true)

  class Failure(message: String) : ValidationResult(false, message)
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/package-info.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** Base classes and abstractions for the animation framework. */
package com.facebook.imagepipeline.animated.base;


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageDecoder.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.factory

import com.facebook.imagepipeline.animated.base.AnimatedImage
import com.facebook.imagepipeline.common.ImageDecodeOptions
import java.nio.ByteBuffer

interface AnimatedImageDecoder {

  /**
   * Factory method to create the AnimatedImage from a native pointer
   *
   * @param nativePtr The native pointer
   * @param sizeInBytes The size in byte to allocate
   * @param options The options for decoding
   * @return The AnimatedImage allocation
   */
  fun decodeFromNativeMemory(
      nativePtr: Long,
      sizeInBytes: Int,
      options: ImageDecodeOptions,
  ): AnimatedImage?

  /**
   * Factory method to create the AnimatedImage from a ByteBuffer
   *
   * @param byteBuffer The ByteBuffer containing the image
   * @param options The options for decoding
   * @return The AnimatedImage allocation
   */
  fun decodeFromByteBuffer(byteBuffer: ByteBuffer, options: ImageDecodeOptions): AnimatedImage?
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageDecoderBase.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.factory

import android.annotation.SuppressLint
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.Rect
import com.facebook.common.references.CloseableReference
import com.facebook.fresco.vito.core.AnimatedImagePerfLoggingListener
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import com.facebook.imagepipeline.animated.base.AnimatedImage
import com.facebook.imagepipeline.animated.base.AnimatedImageResult
import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendImpl
import com.facebook.imagepipeline.animated.impl.AnimatedDrawableBackendProvider
import com.facebook.imagepipeline.animated.impl.AnimatedImageCompositor
import com.facebook.imagepipeline.animated.util.AnimatedDrawableUtil
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
import com.facebook.imagepipeline.common.ImageDecodeOptions
import com.facebook.imagepipeline.image.CloseableAnimatedImage
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.CloseableStaticBitmap
import com.facebook.imagepipeline.image.ImmutableQualityInfo

/**
 * Base class for animated image decoders that provides common functionality for decoding animated
 * images. This class contains the shared logic for creating preview bitmaps, decoding all frames,
 * and creating closeable images.
 */
abstract class AnimatedImageDecoderBase(
    protected val platformBitmapFactory: PlatformBitmapFactory,
    protected val downscaleFrameToDrawableDimensions: Boolean,
    protected val isNewRenderImplementation: Boolean,
    protected val treatAnimatedImagesAsStateful: Boolean = true,
) {

  protected val animatedDrawableBackendProvider: AnimatedDrawableBackendProvider =
      createAnimatedDrawableBackendProvider(downscaleFrameToDrawableDimensions)

  private var animatedImagePerfLoggingListener: AnimatedImagePerfLoggingListener? = null

  fun setAnimatedImagePerfLoggingListener(listener: AnimatedImagePerfLoggingListener?) {
    this.animatedImagePerfLoggingListener = listener
  }

  companion object {
    /** Creates an AnimatedDrawableBackendProvider for animated image decoding. */
    fun createAnimatedDrawableBackendProvider(
        downscaleFrameToDrawableDimensions: Boolean
    ): AnimatedDrawableBackendProvider {
      return object : AnimatedDrawableBackendProvider {
        override fun get(
            animatedImageResult: AnimatedImageResult,
            bounds: Rect?,
        ): AnimatedDrawableBackend {
          return AnimatedDrawableBackendImpl(
              AnimatedDrawableUtil(),
              animatedImageResult,
              bounds,
              downscaleFrameToDrawableDimensions,
          )
        }
      }
    }
  }

  protected fun getCloseableImage(
      sourceUri: String?,
      options: ImageDecodeOptions,
      image: AnimatedImage,
      bitmapConfig: Bitmap.Config,
  ): CloseableImage {
    var decodedFrames: List<CloseableReference<Bitmap>?>? = null
    var previewBitmap: CloseableReference<Bitmap>? = null
    try {
      val frameForPreview = if (options.useLastFrameForPreview) (image.frameCount - 1) else 0
      if (options.forceStaticImage) {
        return CloseableStaticBitmap.of(
            createPreviewBitmap(image, bitmapConfig, frameForPreview),
            ImmutableQualityInfo.FULL_QUALITY,
            0,
        )
      }

      if (options.decodeAllFrames) {
        decodedFrames = decodeAllFrames(image, bitmapConfig)
        previewBitmap = CloseableReference.cloneOrNull(decodedFrames[frameForPreview])
      }

      if (options.decodePreviewFrame && previewBitmap == null) {
        previewBitmap = createPreviewBitmap(image, bitmapConfig, frameForPreview)
      }

      // Log CloseableAnimatedImage creation start
      val imageId = sourceUri ?: "unknown_${System.identityHashCode(image)}"
      val startTime = System.nanoTime()
      animatedImagePerfLoggingListener?.onCloseableAnimatedImageCreationStart(imageId, startTime)

      val animatedImageResult =
          AnimatedImageResult.newBuilder(image)
              .setPreviewBitmap(previewBitmap)
              .setFrameForPreview(frameForPreview)
              .setDecodedFrames(decodedFrames)
              .setBitmapTransformation(options.bitmapTransformation)
              .setSource(sourceUri)
              .build()
      val closeableAnimatedImage =
          CloseableAnimatedImage(animatedImageResult, treatAnimatedImagesAsStateful)

      // Log CloseableAnimatedImage creation success
      val endTime = System.nanoTime()
      animatedImagePerfLoggingListener?.onCloseableAnimatedImageCreationEnd(
          imageId,
          endTime,
          true,
      )

      return closeableAnimatedImage
    } finally {
      CloseableReference.closeSafely(previewBitmap)
      CloseableReference.closeSafely(decodedFrames)
    }
  }

  protected fun createPreviewBitmap(
      image: AnimatedImage,
      bitmapConfig: Bitmap.Config,
      frameForPreview: Int,
  ): CloseableReference<Bitmap> {
    val bitmap = createBitmap(image.width, image.height, bitmapConfig)
    val tempResult = AnimatedImageResult.forAnimatedImage(image)
    val drawableBackend = animatedDrawableBackendProvider.get(tempResult, null)
    val animatedImageCompositor =
        AnimatedImageCompositor(
            drawableBackend,
            isNewRenderImplementation,
            object : AnimatedImageCompositor.Callback {
              override fun onIntermediateResult(frameNumber: Int, bitmap: Bitmap) {
                // Don't care.
              }

              override fun getCachedBitmap(frameNumber: Int): CloseableReference<Bitmap>? = null
            },
        )
    animatedImageCompositor.renderFrame(frameForPreview, bitmap.get())
    return bitmap
  }

  protected fun decodeAllFrames(
      image: AnimatedImage,
      bitmapConfig: Bitmap.Config,
  ): List<CloseableReference<Bitmap>?> {
    val tempResult = AnimatedImageResult.forAnimatedImage(image)
    val drawableBackend = animatedDrawableBackendProvider.get(tempResult, null)
    val bitmaps: MutableList<CloseableReference<Bitmap>?> = ArrayList(drawableBackend.frameCount)
    val animatedImageCompositor =
        AnimatedImageCompositor(
            drawableBackend,
            isNewRenderImplementation,
            object : AnimatedImageCompositor.Callback {
              override fun onIntermediateResult(frameNumber: Int, bitmap: Bitmap) {
                // Don't care.
              }

              override fun getCachedBitmap(frameNumber: Int): CloseableReference<Bitmap>? =
                  CloseableReference.cloneOrNull(bitmaps[frameNumber])
            },
        )
    for (i in 0..<drawableBackend.frameCount) {
      val bitmap = createBitmap(drawableBackend.width, drawableBackend.height, bitmapConfig)
      animatedImageCompositor.renderFrame(i, bitmap.get())
      bitmaps.add(bitmap)
    }
    return bitmaps
  }

  @SuppressLint("NewApi")
  protected fun createBitmap(
      width: Int,
      height: Int,
      bitmapConfig: Bitmap.Config,
  ): CloseableReference<Bitmap> {
    val bitmap = platformBitmapFactory.createBitmapInternal(width, height, bitmapConfig)
    bitmap.get().eraseColor(Color.TRANSPARENT)
    bitmap.get().setHasAlpha(true)
    return bitmap
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageFactory.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.factory

import android.graphics.Bitmap
import com.facebook.imagepipeline.common.ImageDecodeOptions
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.EncodedImage

/** Decoder for animated images. */
interface AnimatedImageFactory {

  /**
   * Decodes a GIF into a CloseableImage.
   *
   * @param encodedImage encoded image (native byte array holding the encoded bytes and meta data)
   * @param options the options for the decode
   * @param bitmapConfig the Bitmap.Config used to generate the output bitmaps
   * @return a [CloseableImage] for the GIF image
   */
  fun decodeGif(
      encodedImage: EncodedImage,
      options: ImageDecodeOptions,
      bitmapConfig: Bitmap.Config,
  ): CloseableImage

  /**
   * Decode a WebP into a CloseableImage.
   *
   * @param encodedImage encoded image (native byte array holding the encoded bytes and meta data)
   * @param options the options for the decode
   * @param bitmapConfig the Bitmap.Config used to generate the output bitmaps
   * @return a [CloseableImage] for the WebP image
   */
  fun decodeWebP(
      encodedImage: EncodedImage,
      options: ImageDecodeOptions,
      bitmapConfig: Bitmap.Config,
  ): CloseableImage
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendImpl.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import com.facebook.common.internal.Preconditions;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo.BlendOperation;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo.DisposalMethod;
import com.facebook.imagepipeline.animated.base.AnimatedImage;
import com.facebook.imagepipeline.animated.base.AnimatedImageFrame;
import com.facebook.imagepipeline.animated.base.AnimatedImageResult;
import com.facebook.imagepipeline.animated.util.AnimatedDrawableUtil;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

/** An {@link AnimatedDrawableBackend} that renders {@link AnimatedImage}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedDrawableBackendImpl implements AnimatedDrawableBackend {

  private final AnimatedDrawableUtil mAnimatedDrawableUtil;

  private final AnimatedImageResult mAnimatedImageResult;
  private final AnimatedImage mAnimatedImage;
  private final Rect mRenderedBounds;
  private final int[] mFrameDurationsMs;
  private final int[] mFrameTimestampsMs;
  private final int mDurationMs;
  private final AnimatedDrawableFrameInfo[] mFrameInfos;
  private final Rect mRenderSrcRect = new Rect();
  private final Rect mRenderDstRect = new Rect();
  private final boolean mDownscaleFrameToDrawableDimensions;
  private final Paint mTransparentPaint;

  @GuardedBy("this")
  private @Nullable Bitmap mTempBitmap;

  public AnimatedDrawableBackendImpl(
      AnimatedDrawableUtil animatedDrawableUtil,
      AnimatedImageResult animatedImageResult,
      @Nullable Rect bounds,
      boolean downscaleFrameToDrawableDimensions) {
    mAnimatedDrawableUtil = animatedDrawableUtil;
    mAnimatedImageResult = animatedImageResult;
    mAnimatedImage = animatedImageResult.getImage();
    mFrameDurationsMs = mAnimatedImage.getFrameDurations();
    mAnimatedDrawableUtil.fixFrameDurations(mFrameDurationsMs);
    mDurationMs = mAnimatedDrawableUtil.getTotalDurationFromFrameDurations(mFrameDurationsMs);
    mFrameTimestampsMs = mAnimatedDrawableUtil.getFrameTimeStampsFromDurations(mFrameDurationsMs);
    mRenderedBounds = getBoundsToUse(mAnimatedImage, bounds);
    mDownscaleFrameToDrawableDimensions = downscaleFrameToDrawableDimensions;
    mFrameInfos = new AnimatedDrawableFrameInfo[mAnimatedImage.getFrameCount()];
    for (int i = 0; i < mAnimatedImage.getFrameCount(); i++) {
      mFrameInfos[i] = mAnimatedImage.getFrameInfo(i);
    }
    mTransparentPaint = new Paint();
    mTransparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
  }

  private static Rect getBoundsToUse(AnimatedImage image, @Nullable Rect targetBounds) {
    if (targetBounds == null) {
      return new Rect(0, 0, image.getWidth(), image.getHeight());
    }
    return new Rect(
        0,
        0,
        Math.min(targetBounds.width(), image.getWidth()),
        Math.min(targetBounds.height(), image.getHeight()));
  }

  @Override
  public AnimatedImageResult getAnimatedImageResult() {
    return mAnimatedImageResult;
  }

  @Override
  public int getDurationMs() {
    return mDurationMs;
  }

  @Override
  public int getFrameCount() {
    return mAnimatedImage.getFrameCount();
  }

  @Override
  public int getLoopCount() {
    return mAnimatedImage.getLoopCount();
  }

  @Override
  public int getWidth() {
    return mAnimatedImage.getWidth();
  }

  @Override
  public int getHeight() {
    return mAnimatedImage.getHeight();
  }

  @Override
  public int getRenderedWidth() {
    return mRenderedBounds.width();
  }

  @Override
  public int getRenderedHeight() {
    return mRenderedBounds.height();
  }

  @Override
  public AnimatedDrawableFrameInfo getFrameInfo(int frameNumber) {
    return mFrameInfos[frameNumber];
  }

  @Override
  public int getFrameForTimestampMs(int timestampMs) {
    return mAnimatedDrawableUtil.getFrameForTimestampMs(mFrameTimestampsMs, timestampMs);
  }

  @Override
  public int getTimestampMsForFrame(int frameNumber) {
    Preconditions.checkElementIndex(frameNumber, mFrameTimestampsMs.length);
    return mFrameTimestampsMs[frameNumber];
  }

  @Override
  public int getDurationMsForFrame(int frameNumber) {
    return mFrameDurationsMs[frameNumber];
  }

  @Override
  public int getFrameForPreview() {
    return mAnimatedImageResult.getFrameForPreview();
  }

  @Override
  public AnimatedDrawableBackend forNewBounds(@Nullable Rect bounds) {
    Rect boundsToUse = getBoundsToUse(mAnimatedImage, bounds);
    if (boundsToUse.equals(mRenderedBounds)) {
      // Actual bounds aren't changed.
      return this;
    }
    return new AnimatedDrawableBackendImpl(
        mAnimatedDrawableUtil, mAnimatedImageResult, bounds, mDownscaleFrameToDrawableDimensions);
  }

  @Override
  public synchronized int getMemoryUsage() {
    int bytes = 0;
    if (mTempBitmap != null) {
      bytes += mAnimatedDrawableUtil.getSizeOfBitmap(mTempBitmap);
    }
    bytes += mAnimatedImage.getSizeInBytes();
    return bytes;
  }

  @Override
  public @Nullable CloseableReference<Bitmap> getPreDecodedFrame(int frameNumber) {
    return mAnimatedImageResult.getDecodedFrame(frameNumber);
  }

  @Override
  public boolean hasPreDecodedFrame(int index) {
    return mAnimatedImageResult.hasDecodedFrame(index);
  }

  @Override
  public void renderFrame(int frameNumber, Canvas canvas) {
    AnimatedImageFrame frame = mAnimatedImage.getFrame(frameNumber);
    try {
      if (frame.getWidth() <= 0 || frame.getHeight() <= 0) {
        return; // Frame not visible -> skipping
      }

      if (mAnimatedImage.doesRenderSupportScaling()) {
        renderImageSupportsScaling(canvas, frame);
      } else {
        renderImageDoesNotSupportScaling(canvas, frame);
      }
    } finally {
      frame.dispose();
    }
  }

  @Override
  public void renderDeltas(int frameNumber, Canvas canvas) {
    AnimatedImageFrame frame = mAnimatedImage.getFrame(frameNumber);
    AnimatedDrawableFrameInfo frameInfo = mAnimatedImage.getFrameInfo(frameNumber);
    AnimatedDrawableFrameInfo previousFrameInfo =
        frameNumber == 0 ? null : mAnimatedImage.getFrameInfo(frameNumber - 1);
    try {
      if (frame.getWidth() <= 0 || frame.getHeight() <= 0) {
        return; // Frame not visible -> skipping
      }

      if (mAnimatedImage.doesRenderSupportScaling()) {
        renderScalingFrames(canvas, frame, frameInfo, previousFrameInfo);
      } else {
        renderNonScalingFrames(canvas, frame, frameInfo, previousFrameInfo);
      }

    } finally {
      frame.dispose();
    }
  }

  private synchronized Bitmap prepareTempBitmapForThisSize(int width, int height) {
    // Different gif frames can be different size,
    // So we need to ensure we can fit next frame to temporary bitmap
    if (mTempBitmap != null
        && (mTempBitmap.getWidth() < width || mTempBitmap.getHeight() < height)) {
      clearTempBitmap();
    }
    if (mTempBitmap == null) {
      mTempBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    }
    mTempBitmap.eraseColor(Color.TRANSPARENT);
    return mTempBitmap;
  }

  private void renderImageSupportsScaling(Canvas canvas, AnimatedImageFrame frame) {
    double xScale = (double) mRenderedBounds.width() / (double) mAnimatedImage.getWidth();
    double yScale = (double) mRenderedBounds.height() / (double) mAnimatedImage.getHeight();

    int frameWidth = (int) Math.round(frame.getWidth() * xScale);
    int frameHeight = (int) Math.round(frame.getHeight() * yScale);
    int xOffset = (int) (frame.getXOffset() * xScale);
    int yOffset = (int) (frame.getYOffset() * yScale);

    synchronized (this) {
      int renderedWidth = mRenderedBounds.width();
      int renderedHeight = mRenderedBounds.height();
      // Update the temp bitmap to be >= rendered dimensions
      prepareTempBitmapForThisSize(renderedWidth, renderedHeight);
      if (mTempBitmap != null) {
        frame.renderFrame(frameWidth, frameHeight, mTempBitmap);
      }
      // Temporary bitmap can be bigger than frame, so we should draw only rendered area of bitmap
      mRenderSrcRect.set(0, 0, renderedWidth, renderedHeight);
      mRenderDstRect.set(xOffset, yOffset, xOffset + renderedWidth, yOffset + renderedHeight);

      if (mTempBitmap != null) {
        canvas.drawBitmap(mTempBitmap, mRenderSrcRect, mRenderDstRect, null);
      }
    }
  }

  private void renderScalingFrames(
      Canvas canvas,
      AnimatedImageFrame frame,
      AnimatedDrawableFrameInfo frameInfo,
      @Nullable AnimatedDrawableFrameInfo previousFrameInfo) {
    int assetWidth = mAnimatedImage.getWidth();
    int assetHeight = mAnimatedImage.getHeight();

    // Find the best scale asset size. Maximum scaleSize would be the assetSize.
    float scaledWidth = assetWidth;
    float scaledHeight = assetHeight;

    // Apply the scale to the frame
    float xScale = 1f;
    float yScale = 1f;

    int frameWidth = frame.getWidth();
    int frameHeight = frame.getHeight();
    int xOffset = frame.getXOffset();
    int yOffset = frame.getYOffset();

    // Check if we need to down scale the asset to the canvas size
    if (scaledWidth > canvas.getWidth() || scaledHeight > canvas.getHeight()) {
      // Canvas could have wrong sizes as 314573336x200. Then we limit the frame sizes
      int maxCanvasWidth = Math.min(canvas.getWidth(), assetWidth);
      int maxCanvasHeight = Math.min(canvas.getHeight(), assetHeight);

      float assetRatio = assetWidth / (float) assetHeight;
      if (maxCanvasWidth > maxCanvasHeight) {
        scaledWidth = maxCanvasWidth;
        scaledHeight = maxCanvasWidth / assetRatio;
      } else {
        scaledWidth = maxCanvasHeight * assetRatio;
        scaledHeight = maxCanvasHeight;
      }

      xScale = scaledWidth / (float) assetWidth;
      yScale = scaledHeight / (float) assetHeight;

      frameWidth = (int) Math.ceil(frame.getWidth() * xScale);
      frameHeight = (int) Math.ceil(frame.getHeight() * yScale);
      xOffset = (int) Math.ceil(frame.getXOffset() * xScale);
      yOffset = (int) Math.ceil(frame.getYOffset() * yScale);
    }

    Rect renderSrcRect = new Rect(0, 0, frameWidth, frameHeight);
    Rect renderDstRect = new Rect(xOffset, yOffset, xOffset + frameWidth, yOffset + frameHeight);

    // Clean previous frame surface if that frame was disposable
    if (previousFrameInfo != null) {
      maybeDisposeBackground(canvas, xScale, yScale, previousFrameInfo);
    }

    // If current frame is no_blend, then we have to clean their surface before rendering
    if (frameInfo.blendOperation == BlendOperation.NO_BLEND) {
      canvas.drawRect(renderDstRect, mTransparentPaint);
    }

    synchronized (this) {
      // Impress the frame in the bitmap
      Bitmap frameBitmap = prepareTempBitmapForThisSize(frameWidth, frameHeight);
      frame.renderFrame(frameWidth, frameHeight, frameBitmap);
      canvas.drawBitmap(frameBitmap, renderSrcRect, renderDstRect, null);
    }
  }

  private void maybeDisposeBackground(
      Canvas canvas, float xScale, float yScale, AnimatedDrawableFrameInfo previousFrameInfo) {
    if (previousFrameInfo.disposalMethod == DisposalMethod.DISPOSE_TO_BACKGROUND) {
      int prevFrameWidth = (int) Math.ceil(previousFrameInfo.width * xScale);
      int prevFrameHeight = (int) Math.ceil(previousFrameInfo.height * yScale);
      int prevXOffset = (int) Math.ceil(previousFrameInfo.xOffset * xScale);
      int prevYOffset = (int) Math.ceil(previousFrameInfo.yOffset * yScale);
      Rect prevFrameSurface =
          new Rect(
              prevXOffset,
              prevYOffset,
              prevXOffset + prevFrameWidth,
              prevYOffset + prevFrameHeight);
      canvas.drawRect(prevFrameSurface, mTransparentPaint);
    }
  }

  private void renderImageDoesNotSupportScaling(Canvas canvas, AnimatedImageFrame frame) {
    int frameWidth, frameHeight, xOffset, yOffset;
    if (mDownscaleFrameToDrawableDimensions) {
      final int fittedWidth = Math.min(frame.getWidth(), canvas.getWidth());
      final int fittedHeight = Math.min(frame.getHeight(), canvas.getHeight());

      final float scaleX = (float) frame.getWidth() / (float) fittedWidth;
      final float scaleY = (float) frame.getHeight() / (float) fittedHeight;
      final float scale = Math.max(scaleX, scaleY);

      frameWidth = (int) (frame.getWidth() / scale);
      frameHeight = (int) (frame.getHeight() / scale);
      xOffset = (int) (frame.getXOffset() / scale);
      yOffset = (int) (frame.getYOffset() / scale);
    } else {
      frameWidth = frame.getWidth();
      frameHeight = frame.getHeight();
      xOffset = frame.getXOffset();
      yOffset = frame.getYOffset();
    }

    synchronized (this) {
      mTempBitmap = prepareTempBitmapForThisSize(frameWidth, frameHeight);
      frame.renderFrame(frameWidth, frameHeight, mTempBitmap);

      canvas.save();
      canvas.translate(xOffset, yOffset);
      canvas.drawBitmap(mTempBitmap, 0, 0, null);
      canvas.restore();
    }
  }

  private void renderNonScalingFrames(
      Canvas canvas,
      AnimatedImageFrame frame,
      AnimatedDrawableFrameInfo frameInfo,
      @Nullable AnimatedDrawableFrameInfo previousFrameInfo) {
    if (mRenderedBounds == null || mRenderedBounds.width() <= 0 || mRenderedBounds.height() <= 0) {
      return;
    }

    float scale = (float) canvas.getWidth() / mRenderedBounds.width();

    // Clean previous frame surface if that frame was disposable
    if (previousFrameInfo != null) {
      maybeDisposeBackground(canvas, scale, scale, previousFrameInfo);
    }

    // Prepare the new frame
    int frameWidth = frame.getWidth();
    int frameHeight = frame.getHeight();
    Rect src = new Rect(0, 0, frameWidth, frameHeight);

    int resizedWidth = (int) (frameWidth * scale);
    int resizedHeight = (int) (frameHeight * scale);

    int xOffset = (int) (frame.getXOffset() * scale);
    int yOffset = (int) (frame.getYOffset() * scale);

    // Clear the canvas if this frame doesnt blend
    Rect renderDstRect =
        new Rect(xOffset, yOffset, xOffset + resizedWidth, yOffset + resizedHeight);
    if (frameInfo.blendOperation == BlendOperation.NO_BLEND) {
      canvas.drawRect(renderDstRect, mTransparentPaint);
    }
    synchronized (this) {
      // Draw canvas frame
      Bitmap bitmap = prepareTempBitmapForThisSize(frameWidth, frameHeight);
      frame.renderFrame(frameWidth, frameHeight, bitmap);
      canvas.drawBitmap(bitmap, src, renderDstRect, null);
    }
  }

  @Override
  public synchronized void dropCaches() {
    clearTempBitmap();
  }

  private synchronized void clearTempBitmap() {
    if (mTempBitmap != null) {
      mTempBitmap.recycle();
      mTempBitmap = null;
    }
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendProvider.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl;

import android.graphics.Rect;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend;
import com.facebook.imagepipeline.animated.base.AnimatedImageResult;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/** Assisted provider for {@link AnimatedDrawableBackend}. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public interface AnimatedDrawableBackendProvider {

  /**
   * Creates a new {@link AnimatedDrawableBackend}.
   *
   * @param animatedImageResult the image result.
   * @param bounds the initial bounds for the drawable
   * @return a new {@link AnimatedDrawableBackend}
   */
  AnimatedDrawableBackend get(AnimatedImageResult animatedImageResult, @Nullable Rect bounds);
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedFrameCache.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl;

import android.net.Uri;
import androidx.annotation.VisibleForTesting;
import com.facebook.cache.common.CacheKey;
import com.facebook.common.internal.Objects;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.cache.CountingMemoryCache;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.infer.annotation.Nullsafe;
import java.util.Iterator;
import java.util.LinkedHashSet;
import javax.annotation.Nullable;
import javax.annotation.concurrent.GuardedBy;

/**
 * Facade to the image memory cache for frames of an animated image.
 *
 * <p>Each animated image should have its own instance of this class.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedFrameCache {

  @VisibleForTesting
  static class FrameKey implements CacheKey {

    private final CacheKey mImageCacheKey;
    private final int mFrameIndex;

    public FrameKey(CacheKey imageCacheKey, int frameIndex) {
      mImageCacheKey = imageCacheKey;
      mFrameIndex = frameIndex;
    }

    @Override
    public String toString() {
      return Objects.toStringHelper(this)
          .add("imageCacheKey", mImageCacheKey)
          .add("frameIndex", mFrameIndex)
          .toString();
    }

    @Override
    public boolean equals(@Nullable Object o) {
      if (o == this) {
        return true;
      }
      if (o instanceof FrameKey) {
        FrameKey that = (FrameKey) o;
        return this.mFrameIndex == that.mFrameIndex
            && this.mImageCacheKey.equals(that.mImageCacheKey);
      }
      return false;
    }

    @Override
    public int hashCode() {
      return mImageCacheKey.hashCode() * 1013 + mFrameIndex;
    }

    @Override
    public boolean containsUri(Uri uri) {
      return mImageCacheKey.containsUri(uri);
    }

    @Override
    // NULLSAFE_FIXME[Inconsistent Subclass Return Annotation]
    public @Nullable String getUriString() {
      return null;
    }

    @Override
    public boolean isResourceIdForDebugging() {
      return false;
    }
  }

  private final CacheKey mImageCacheKey;
  private final CountingMemoryCache<CacheKey, CloseableImage> mBackingCache;
  private final CountingMemoryCache.EntryStateObserver<CacheKey> mEntryStateObserver;

  @GuardedBy("this")
  private final LinkedHashSet<CacheKey> mFreeItemsPool;

  public AnimatedFrameCache(
      CacheKey imageCacheKey, final CountingMemoryCache<CacheKey, CloseableImage> backingCache) {
    mImageCacheKey = imageCacheKey;
    mBackingCache = backingCache;
    mFreeItemsPool = new LinkedHashSet<>();
    mEntryStateObserver =
        new CountingMemoryCache.EntryStateObserver<CacheKey>() {
          @Override
          public void onExclusivityChanged(CacheKey key, boolean isExclusive) {
            AnimatedFrameCache.this.onReusabilityChange(key, isExclusive);
          }
        };
  }

  public synchronized void onReusabilityChange(CacheKey key, boolean isReusable) {
    if (isReusable) {
      mFreeItemsPool.add(key);
    } else {
      mFreeItemsPool.remove(key);
    }
  }

  /**
   * Caches the image for the given frame index.
   *
   * <p>Important: the client should use the returned reference instead of the original one. It is
   * the caller's responsibility to close the returned reference once not needed anymore.
   *
   * @return the new reference to be used, null if the value cannot be cached
   */
  @Nullable
  public CloseableReference<CloseableImage> cache(
      int frameIndex, CloseableReference<CloseableImage> imageRef) {
    return mBackingCache.cache(keyFor(frameIndex), imageRef, mEntryStateObserver);
  }

  /**
   * Gets the image for the given frame index.
   *
   * <p>It is the caller's responsibility to close the returned reference once not needed anymore.
   */
  @Nullable
  public CloseableReference<CloseableImage> get(int frameIndex) {
    return mBackingCache.get(keyFor(frameIndex));
  }

  /** Check whether the cache contains an image for the given frame index. */
  public boolean contains(int frameIndex) {
    return mBackingCache.contains(keyFor(frameIndex));
  }

  /**
   * Gets the image to be reused, or null if there is no such image.
   *
   * <p>The returned image is the least recently used image that has no more clients referencing it,
   * and it has not yet been evicted from the cache.
   *
   * <p>The client can freely modify the bitmap of the returned image and can cache it again without
   * any restrictions.
   */
  @Nullable
  public CloseableReference<CloseableImage> getForReuse() {
    while (true) {
      CacheKey key = popFirstFreeItemKey();
      if (key == null) {
        return null;
      }
      CloseableReference<CloseableImage> imageRef = mBackingCache.reuse(key);
      if (imageRef != null) {
        return imageRef;
      }
    }
  }

  @Nullable
  private synchronized CacheKey popFirstFreeItemKey() {
    CacheKey cacheKey = null;
    Iterator<CacheKey> iterator = mFreeItemsPool.iterator();
    if (iterator.hasNext()) {
      cacheKey = iterator.next();
      iterator.remove();
    }
    return cacheKey;
  }

  private FrameKey keyFor(int frameIndex) {
    return new FrameKey(mImageCacheKey, frameIndex);
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedImageCompositor.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo.BlendOperation;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo.DisposalMethod;
import com.facebook.imagepipeline.animated.base.AnimatedImage;
import com.facebook.imagepipeline.animated.base.AnimatedImageResult;
import com.facebook.imagepipeline.transformation.BitmapTransformation;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/**
 * Contains the logic for compositing the frames of an {@link AnimatedImage}. Animated image formats
 * like GIF and WebP support inter-frame compression where a subsequent frame may require being
 * blended on a previous frame in order to render the full frame. This class encapsulates the
 * behavior to be able to render any frame of the image. Designed to work with a cache via a
 * Callback.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimatedImageCompositor {

  /** Callback for caching. */
  public interface Callback {

    /**
     * Called from within {@link #renderFrame} to let the caller know that while trying generate the
     * requested frame, an earlier frame was generated. This allows the caller to optionally cache
     * the intermediate result. The caller must copy the Bitmap if it wishes to cache it as {@link
     * #renderFrame} will continue using it generate the requested frame.
     *
     * @param frameNumber the frame number of the intermediate result
     * @param bitmap the bitmap which must not be modified or directly cached
     */
    void onIntermediateResult(int frameNumber, Bitmap bitmap);

    /**
     * Called from within {@link #renderFrame} to ask the caller for a cached bitmap for the
     * specified frame number. If the caller has the bitmap cached, it can greatly reduce the work
     * required to render the requested frame.
     *
     * @param frameNumber the frame number to get
     * @return a reference to the bitmap. The ownership of the reference is passed to the caller who
     *     must close it.
     */
    @Nullable
    CloseableReference<Bitmap> getCachedBitmap(int frameNumber);
  }

  private final AnimatedDrawableBackend mAnimatedDrawableBackend;
  private final Callback mCallback;
  private final Paint mTransparentFillPaint;
  private final boolean mIsNewRenderImplementation;

  public AnimatedImageCompositor(
      AnimatedDrawableBackend animatedDrawableBackend,
      boolean isNewRenderImplementation,
      Callback callback) {
    mAnimatedDrawableBackend = animatedDrawableBackend;
    mCallback = callback;
    mIsNewRenderImplementation = isNewRenderImplementation;
    mTransparentFillPaint = new Paint();
    mTransparentFillPaint.setColor(Color.TRANSPARENT);
    mTransparentFillPaint.setStyle(Paint.Style.FILL);
    mTransparentFillPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
  }

  public void renderDeltas(int frameNumber, Bitmap baseBitmap) {
    Canvas canvas = new Canvas(baseBitmap);
    mAnimatedDrawableBackend.renderDeltas(frameNumber, canvas);
  }

  /**
   * Renders the specified frame. Only should be called on the rendering thread.
   *
   * @param frameNumber the frame to render
   * @param bitmap the bitmap to render into
   */
  public void renderFrame(int frameNumber, Bitmap bitmap) {
    if (mIsNewRenderImplementation) {
      renderDeltas(frameNumber, bitmap);
      return;
    }

    Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.SRC);

    // If blending is required, prepare the canvas with the nearest cached frame.
    int nextIndex;
    if (!isKeyFrame(frameNumber)) {
      // Blending is required. nextIndex points to the next index to render onto the canvas.
      nextIndex = prepareCanvasWithClosestCachedFrame(frameNumber - 1, canvas);
    } else {
      // Blending isn't required. Start at the frame we're trying to render.
      nextIndex = frameNumber;
    }

    // Iterate from nextIndex to the frame number just preceding the one we're trying to render
    // and composite them in order according to the Disposal Method.
    for (int index = nextIndex; index < frameNumber; index++) {
      AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend.getFrameInfo(index);
      DisposalMethod disposalMethod = frameInfo.disposalMethod;
      if (disposalMethod == DisposalMethod.DISPOSE_TO_PREVIOUS) {
        continue;
      }
      if (frameInfo.blendOperation == BlendOperation.NO_BLEND) {
        disposeToBackground(canvas, frameInfo);
      }
      mAnimatedDrawableBackend.renderFrame(index, canvas);
      mCallback.onIntermediateResult(index, bitmap);
      if (disposalMethod == DisposalMethod.DISPOSE_TO_BACKGROUND) {
        disposeToBackground(canvas, frameInfo);
      }
    }

    AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend.getFrameInfo(frameNumber);
    if (frameInfo.blendOperation == BlendOperation.NO_BLEND) {
      disposeToBackground(canvas, frameInfo);
    }
    // Finally, we render the current frame. We don't dispose it.
    mAnimatedDrawableBackend.renderFrame(frameNumber, canvas);
    maybeApplyTransformation(bitmap);
  }

  /** Return value for {@link #isFrameNeededForRendering} used in the compositing logic. */
  private enum FrameNeededResult {
    /** The frame is required to render the next frame */
    REQUIRED,

    /** The frame is not required to render the next frame. */
    NOT_REQUIRED,

    /** Skip this frame and keep going. Used for GIF's DISPOSE_TO_PREVIOUS */
    SKIP,

    /** Stop processing at this frame. This means the image didn't specify the disposal method */
    ABORT
  }

  /**
   * Given a frame number, prepares the canvas to render based on the nearest cached frame at or
   * before the frame. On return the canvas will be prepared as if the nearest cached frame had been
   * rendered and disposed. The returned index is the next frame that needs to be composited onto
   * the canvas.
   *
   * @param previousFrameNumber the frame number that is ones less than the one we're rendering
   * @param canvas the canvas to prepare
   * @return the index of the the next frame to process
   */
  private int prepareCanvasWithClosestCachedFrame(int previousFrameNumber, Canvas canvas) {
    for (int index = previousFrameNumber; index >= 0; index--) {
      FrameNeededResult neededResult = isFrameNeededForRendering(index);
      switch (neededResult) {
        case REQUIRED:
          AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend.getFrameInfo(index);
          CloseableReference<Bitmap> startBitmap = mCallback.getCachedBitmap(index);
          if (startBitmap != null) {
            try {
              canvas.drawBitmap(startBitmap.get(), 0, 0, null);
              if (frameInfo.disposalMethod == DisposalMethod.DISPOSE_TO_BACKGROUND) {
                disposeToBackground(canvas, frameInfo);
              }
              return index + 1;
            } finally {
              if (!mIsNewRenderImplementation) {
                startBitmap.close();
              }
            }
          } else {
            if (isKeyFrame(index)) {
              return index;
            } else {
              // Keep going.
              break;
            }
          }
        case NOT_REQUIRED:
          return index + 1;
        case ABORT:
          return index;
        case SKIP:
        default:
          // Keep going.
      }
    }
    return 0;
  }

  private void disposeToBackground(Canvas canvas, AnimatedDrawableFrameInfo frameInfo) {
    canvas.drawRect(
        frameInfo.xOffset,
        frameInfo.yOffset,
        frameInfo.xOffset + frameInfo.width,
        frameInfo.yOffset + frameInfo.height,
        mTransparentFillPaint);
  }

  /**
   * Returns whether the specified frame is needed for rendering the next frame. This is part of the
   * compositing logic. See {@link FrameNeededResult} for more info about the results.
   *
   * @param index the frame to check
   * @return whether the frame is required taking into account special conditions
   */
  private FrameNeededResult isFrameNeededForRendering(int index) {
    AnimatedDrawableFrameInfo frameInfo = mAnimatedDrawableBackend.getFrameInfo(index);
    DisposalMethod disposalMethod = frameInfo.disposalMethod;
    if (disposalMethod == DisposalMethod.DISPOSE_DO_NOT) {
      // Need this frame so keep going.
      return FrameNeededResult.REQUIRED;
    } else if (disposalMethod == DisposalMethod.DISPOSE_TO_BACKGROUND) {
      if (isFullFrame(frameInfo)) {
        // The frame covered the whole image and we're disposing to background,
        // so we don't even need to draw this frame.
        return FrameNeededResult.NOT_REQUIRED;
      } else {
        // We need to draw the image. Then erase the part the previous frame covered.
        // So keep going.
        return FrameNeededResult.REQUIRED;
      }
    } else if (disposalMethod == DisposalMethod.DISPOSE_TO_PREVIOUS) {
      return FrameNeededResult.SKIP;
    } else {
      return FrameNeededResult.ABORT;
    }
  }

  private boolean isKeyFrame(int index) {
    if (index == 0) {
      return true;
    }
    AnimatedDrawableFrameInfo currFrameInfo = mAnimatedDrawableBackend.getFrameInfo(index);
    AnimatedDrawableFrameInfo prevFrameInfo = mAnimatedDrawableBackend.getFrameInfo(index - 1);
    if (currFrameInfo.blendOperation == BlendOperation.NO_BLEND && isFullFrame(currFrameInfo)) {
      return true;
    } else
      return prevFrameInfo.disposalMethod == DisposalMethod.DISPOSE_TO_BACKGROUND
          && isFullFrame(prevFrameInfo);
  }

  private boolean isFullFrame(AnimatedDrawableFrameInfo frameInfo) {
    return frameInfo.xOffset == 0
        && frameInfo.yOffset == 0
        && frameInfo.width == mAnimatedDrawableBackend.getRenderedWidth()
        && frameInfo.height == mAnimatedDrawableBackend.getRenderedHeight();
  }

  private void maybeApplyTransformation(Bitmap bitmap) {
    AnimatedImageResult animatedImageResult = mAnimatedDrawableBackend.getAnimatedImageResult();

    if (animatedImageResult == null) {
      return;
    }

    BitmapTransformation tr = animatedImageResult.getBitmapTransformation();

    if (tr == null) {
      return;
    }

    tr.transform(bitmap);
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/package-info.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** Base implementations for the animation framework abstractions. */
package com.facebook.imagepipeline.animated.impl;


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/util/AnimatedDrawableUtil.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.util

import android.graphics.Bitmap
import java.util.Arrays

/** Utility methods for AnimatedDrawable. */
class AnimatedDrawableUtil {

  /**
   * Adjusts the frame duration array to respect logic for minimum frame duration time.
   *
   * @param frameDurationMs the frame duration array
   */
  fun fixFrameDurations(frameDurationMs: IntArray) {
    // We follow Chrome's behavior which comes from Firefox.
    // Comment from Chrome's ImageSource.cpp follows:
    // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
    // a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
    // for more information.
    for (i in frameDurationMs.indices) {
      if (frameDurationMs[i] < MIN_FRAME_DURATION_MS) {
        frameDurationMs[i] = FRAME_DURATION_MS_FOR_MIN
      }
    }
  }

  /**
   * Gets the total duration of an image by summing up the duration of the frames.
   *
   * @param frameDurationMs the frame duration array
   * @return the total duration in milliseconds
   */
  fun getTotalDurationFromFrameDurations(frameDurationMs: IntArray): Int {
    var totalMs = 0
    for (i in frameDurationMs.indices) {
      totalMs += frameDurationMs[i]
    }
    return totalMs
  }

  /**
   * Given an array of frame durations, generate an array of timestamps corresponding to when each
   * frame beings.
   *
   * @param frameDurationsMs an array of frame durations
   * @return an array of timestamps
   */
  fun getFrameTimeStampsFromDurations(frameDurationsMs: IntArray): IntArray {
    val frameTimestampsMs = IntArray(frameDurationsMs.size)
    var accumulatedDurationMs = 0
    for (i in frameDurationsMs.indices) {
      frameTimestampsMs[i] = accumulatedDurationMs
      accumulatedDurationMs += frameDurationsMs[i]
    }
    return frameTimestampsMs
  }

  /**
   * Gets the frame index for specified timestamp.
   *
   * @param frameTimestampsMs an array of timestamps generated by [getFrameForTimestampMs)]
   * @param timestampMs the timestamp
   * @return the frame index for the timestamp or the last frame number if the timestamp is outside
   *   the duration of the entire animation
   */
  fun getFrameForTimestampMs(frameTimestampsMs: IntArray?, timestampMs: Int): Int {
    val index = Arrays.binarySearch(frameTimestampsMs, timestampMs)
    return if (index < 0) {
      -index - 1 - 1
    } else {
      index
    }
  }

  fun getSizeOfBitmap(bitmap: Bitmap): Int = bitmap.allocationByteCount

  companion object {
    // See comment in fixFrameDurations below.
    private const val MIN_FRAME_DURATION_MS = 11
    private const val FRAME_DURATION_MS_FOR_MIN = 100

    /**
     * Checks whether the specified frame number is outside the range inclusive of both start and
     * end. If start <= end, start is within, end is within, and everything in between is within. If
     * start
     * > end, start is within, end is within, everything less than start is within and everything
     * > greater than end is within. This behavior is useful for handling the wrapping case.
     *
     * @param startFrame the start frame
     * @param endFrame the end frame
     * @param frameNumber the frame number
     * @return whether the frame is outside the range of [start, end]
     */
    @JvmStatic
    fun isOutsideRange(startFrame: Int, endFrame: Int, frameNumber: Int): Boolean {
      if (startFrame == -1 || endFrame == -1) {
        // This means nothing should pass.
        return true
      }
      val outsideRange =
          if (startFrame <= endFrame) {
            frameNumber < startFrame || frameNumber > endFrame
          } else {
            // Wrapping
            frameNumber < startFrame && frameNumber > endFrame
          }
      return outsideRange
    }
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/util/package-info.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** Utility classes for the animation framework */
package com.facebook.imagepipeline.animated.util


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/image/CloseableAnimatedImage.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.image;

import com.facebook.imagepipeline.animated.base.AnimatedImage;
import com.facebook.imagepipeline.animated.base.AnimatedImageResult;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/**
 * Encapsulates the data needed in order for {@code AnimatedDrawable} to render a {@code
 * AnimatedImage}.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class CloseableAnimatedImage extends DefaultCloseableImage {

  private @Nullable AnimatedImageResult mImageResult;

  private boolean mIsStateful;

  public CloseableAnimatedImage(AnimatedImageResult imageResult) {
    this(imageResult, true);
  }

  public CloseableAnimatedImage(AnimatedImageResult imageResult, boolean isStateful) {
    mImageResult = imageResult;
    mIsStateful = isStateful;
  }

  @Override
  public synchronized int getWidth() {
    return mImageResult == null ? 0 : mImageResult.getImage().getWidth();
  }

  @Override
  public synchronized int getHeight() {
    return mImageResult == null ? 0 : mImageResult.getImage().getHeight();
  }

  @Override
  public void close() {
    AnimatedImageResult imageResult;
    synchronized (this) {
      if (mImageResult == null) {
        return;
      }
      imageResult = mImageResult;
      mImageResult = null;
    }
    imageResult.dispose();
  }

  @Override
  public synchronized boolean isClosed() {
    return mImageResult == null;
  }

  @Override
  public synchronized int getSizeInBytes() {
    return mImageResult == null ? 0 : mImageResult.getImage().getSizeInBytes();
  }

  @Override
  public boolean isStateful() {
    return mIsStateful;
  }

  public synchronized @Nullable AnimatedImageResult getImageResult() {
    return mImageResult;
  }

  public synchronized @Nullable AnimatedImage getImage() {
    return mImageResult == null ? null : mImageResult.getImage();
  }
}


================================================
FILE: animated-base/src/main/java/com/facebook/imagepipeline/image/package-info.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

/** CloseableReference implementation for objects used into the animation framework. */
package com.facebook.imagepipeline.image;


================================================
FILE: animated-base/src/test/java/android/net/http/AndroidHttpClient.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package android.net.http;

public class AndroidHttpClient {}


================================================
FILE: animated-base/src/test/java/com/facebook/fresco/animation/bitmap/cache/FrescoFrameCacheTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.cache

import android.graphics.Bitmap
import com.facebook.common.references.CloseableReference
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.CloseableStaticBitmap
import org.assertj.core.api.Assertions
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner

/** Tests [FrescoFrameCache]. */
@RunWith(RobolectricTestRunner::class)
class FrescoFrameCacheTest {
  private lateinit var imageReference: CloseableReference<CloseableImage>
  private lateinit var closeableStaticBitmap: CloseableStaticBitmap
  private lateinit var bitmapReference: CloseableReference<Bitmap>
  private lateinit var bitmapReferenceClone: CloseableReference<Bitmap>
  private lateinit var underlyingBitmap: Bitmap

  @Before
  fun setup() {
    imageReference = mock()
    closeableStaticBitmap = mock()
    bitmapReference = mock()
    bitmapReferenceClone = mock()
    underlyingBitmap = mock()

    whenever(bitmapReference.isValid).thenReturn(true)
    whenever(bitmapReference.get()).thenReturn(underlyingBitmap)

    whenever(bitmapReferenceClone.isValid).thenReturn(true)
    whenever(bitmapReferenceClone.get()).thenReturn(underlyingBitmap)

    whenever(closeableStaticBitmap.isClosed()).thenReturn(false)
    whenever(closeableStaticBitmap.getUnderlyingBitmap()).thenReturn(underlyingBitmap)
    whenever(closeableStaticBitmap.convertToBitmapReference()).thenReturn(bitmapReference)
    whenever(closeableStaticBitmap.cloneUnderlyingBitmapReference())
        .thenReturn(bitmapReferenceClone)

    whenever(imageReference.isValid).thenReturn(true)
    whenever(imageReference.get()).thenReturn(closeableStaticBitmap)
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose() {
    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    Assertions.assertThat(extractedReference).isNotNull()
    extractedReference?.let { ref ->
      Assertions.assertThat(ref.get()).isEqualTo(underlyingBitmap)
      ref.close()
    }
    verify(imageReference).close()
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenBitmapRecycled_thenReturnReference() {
    whenever(underlyingBitmap.isRecycled).thenReturn(true)

    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    // We only detach the reference and do not care if the bitmap is valid
    Assertions.assertThat(extractedReference).isNotNull()
    extractedReference?.let { ref ->
      Assertions.assertThat(ref.get()).isEqualTo(underlyingBitmap)
      ref.close()
    }
    verify(imageReference).close()
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenBitmapReferenceInvalid_thenReturnReference() {
    whenever(bitmapReference.isValid).thenReturn(false)

    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    // We only detach the reference and do not care if the bitmap reference is valid
    Assertions.assertThat(extractedReference).isNotNull()
    extractedReference?.let { ref ->
      Assertions.assertThat(ref.get()).isEqualTo(underlyingBitmap)
      ref.close()
    }
    verify(imageReference).close()
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenCloseableStaticBitmapClosed_thenReturnNull() {
    whenever(closeableStaticBitmap.isClosed()).thenReturn(true)
    whenever(closeableStaticBitmap.cloneUnderlyingBitmapReference()).thenReturn(null)

    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    // We only detach the reference and do not care if the bitmap is valid
    Assertions.assertThat(extractedReference).isNull()
    verify(imageReference).close()
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenImageReferenceInvalid_thenReturnNull() {
    whenever(imageReference.isValid).thenReturn(false)

    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    // We only detach the reference and do not care if the bitmap is valid
    Assertions.assertThat(extractedReference).isNull()
    verify(imageReference).close()
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenInputNull_thenReturnNull() {
    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(null)

    Assertions.assertThat(extractedReference).isNull()
    verifyNoMoreInteractions(imageReference)
  }

  @Test
  @Throws(Exception::class)
  fun testExtractAndClose_whenCloseableStaticBitmapNull_thenReturnNull() {
    whenever(imageReference.get()).thenReturn(null)

    val extractedReference: CloseableReference<Bitmap>? =
        FrescoFrameCache.convertToBitmapReferenceAndClose(imageReference)

    Assertions.assertThat(extractedReference).isNull()
    verify(imageReference).close()
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendAnimationInformationTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.wrapper

import com.facebook.fresco.animation.backend.AnimationBackend
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import org.assertj.core.api.Assertions
import org.junit.Before
import org.junit.Test
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever

/** Tests [AnimatedDrawableBackendAnimationInformation]. */
class AnimatedDrawableBackendAnimationInformationTest {
  private lateinit var animatedDrawableBackend: AnimatedDrawableBackend
  private lateinit var animatedDrawableBackendAnimationInformation:
      AnimatedDrawableBackendAnimationInformation

  @Before
  fun setup() {
    animatedDrawableBackend = mock()
    animatedDrawableBackendAnimationInformation =
        AnimatedDrawableBackendAnimationInformation(animatedDrawableBackend)
  }

  @Test
  @Throws(Exception::class)
  fun testGetFrameCount() {
    whenever(animatedDrawableBackend.getFrameCount()).thenReturn(123)

    Assertions.assertThat(animatedDrawableBackendAnimationInformation.getFrameCount())
        .isEqualTo(123)
  }

  @Test
  @Throws(Exception::class)
  fun testGetFrameDurationMs() {
    whenever(animatedDrawableBackend.getDurationMsForFrame(1)).thenReturn(123)
    whenever(animatedDrawableBackend.getDurationMsForFrame(2)).thenReturn(200)

    Assertions.assertThat(animatedDrawableBackendAnimationInformation.getFrameDurationMs(1))
        .isEqualTo(123)
    Assertions.assertThat(animatedDrawableBackendAnimationInformation.getFrameDurationMs(2))
        .isEqualTo(200)
  }

  @Test
  @Throws(Exception::class)
  fun testGetLoopCount() {
    whenever(animatedDrawableBackend.getLoopCount()).thenReturn(123)
    Assertions.assertThat(animatedDrawableBackendAnimationInformation.getLoopCount()).isEqualTo(123)
  }

  @Test
  @Throws(Exception::class)
  fun testGetLoopCountInfinite() {
    whenever(animatedDrawableBackend.getLoopCount())
        .thenReturn(AnimationBackend.LOOP_COUNT_INFINITE)

    Assertions.assertThat(animatedDrawableBackendAnimationInformation.getLoopCount())
        .isEqualTo(AnimationBackend.LOOP_COUNT_INFINITE)
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendFrameRendererTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.bitmap.wrapper

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Rect
import com.facebook.fresco.animation.bitmap.BitmapFrameCache
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo
import org.assertj.core.api.Assertions
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner

/** Tests [AnimatedDrawableBackendFrameRenderer] */
@RunWith(RobolectricTestRunner::class)
class AnimatedDrawableBackendFrameRendererTest {
  private lateinit var animatedDrawableBackendFrameRenderer: AnimatedDrawableBackendFrameRenderer
  private lateinit var animatedDrawableBackend: AnimatedDrawableBackend
  private lateinit var bitmapFrameCache: BitmapFrameCache

  @Before
  fun setup() {
    animatedDrawableBackend = mock()
    bitmapFrameCache = mock()
    animatedDrawableBackendFrameRenderer =
        AnimatedDrawableBackendFrameRenderer(bitmapFrameCache, animatedDrawableBackend, false)
  }

  @Test
  fun testSetBounds() {
    whenever(animatedDrawableBackend.forNewBounds(any<Rect>())).thenReturn(animatedDrawableBackend)

    val bounds: Rect = mock()
    animatedDrawableBackendFrameRenderer.setBounds(bounds)

    verify(animatedDrawableBackend).forNewBounds(bounds)
  }

  @Test
  fun testGetIntrinsicWidth() {
    whenever(animatedDrawableBackend.getWidth()).thenReturn(123)

    Assertions.assertThat(animatedDrawableBackendFrameRenderer.intrinsicWidth).isEqualTo(123)
    Assertions.assertThat(animatedDrawableBackendFrameRenderer.intrinsicHeight).isNotEqualTo(123)
  }

  @Test
  fun testGetIntrinsicHeight() {
    whenever(animatedDrawableBackend.getHeight()).thenReturn(1200)

    Assertions.assertThat(animatedDrawableBackendFrameRenderer.intrinsicHeight).isEqualTo(1200)
    Assertions.assertThat(animatedDrawableBackendFrameRenderer.intrinsicWidth).isNotEqualTo(1200)
  }

  @Test
  fun testRenderFrame() {
    whenever(animatedDrawableBackend.getHeight()).thenReturn(1200)
    val bitmap: Bitmap = mockBitmap()
    val animatedDrawableFrameInfo: AnimatedDrawableFrameInfo = mock()
    whenever(animatedDrawableBackend.getFrameInfo(any<Int>())).thenReturn(animatedDrawableFrameInfo)

    val rendered = animatedDrawableBackendFrameRenderer.renderFrame(0, bitmap)

    Assertions.assertThat(rendered).isTrue()
  }

  @Test
  fun testRenderFrameUnsuccessful() {
    val frameNumber = 0

    whenever(animatedDrawableBackend.getHeight()).thenReturn(1200)
    val bitmap: Bitmap = mockBitmap()
    val animatedDrawableFrameInfo: AnimatedDrawableFrameInfo = mock()
    whenever(animatedDrawableBackend.getFrameInfo(any<Int>())).thenReturn(animatedDrawableFrameInfo)
    doThrow(IllegalStateException())
        .whenever(animatedDrawableBackend)
        .renderFrame(eq(frameNumber), any<Canvas>())

    val rendered = animatedDrawableBackendFrameRenderer.renderFrame(frameNumber, bitmap)

    Assertions.assertThat(rendered).isFalse()
  }

  companion object {
    private fun mockBitmap(): Bitmap {
      val mock: Bitmap = mock()
      whenever(mock.isMutable).thenReturn(true)
      return mock
    }
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendImplTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Rect
import com.facebook.imagepipeline.animated.base.AnimatedImage
import com.facebook.imagepipeline.animated.base.AnimatedImageFrame
import com.facebook.imagepipeline.animated.base.AnimatedImageResult
import com.facebook.imagepipeline.animated.util.AnimatedDrawableUtil
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockedStatic
import org.mockito.Mockito
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class AnimatedDrawableBackendImplTest {
  private lateinit var animatedDrawableUtil: AnimatedDrawableUtil
  private lateinit var animatedImageResult: AnimatedImageResult
  private lateinit var canvas: Canvas
  private lateinit var image: AnimatedImage
  private lateinit var frame: AnimatedImageFrame
  private lateinit var bitmap: Bitmap
  private lateinit var rect: Rect
  private lateinit var mockedBitmap: MockedStatic<Bitmap>

  @Before
  @Throws(Exception::class)
  fun setUp() {
    animatedDrawableUtil = mock()
    animatedImageResult = mock()
    canvas = mock()
    image = mock()
    frame = mock()
    bitmap = mock()
    rect = mock()

    mockedBitmap = Mockito.mockStatic(Bitmap::class.java)

    whenever(animatedImageResult.image).thenReturn(image)
    whenever(image.doesRenderSupportScaling()).thenReturn(false)
    whenever(image.getFrame(any<Int>())).thenReturn(frame)

    mockedBitmap
        .`when`<Bitmap> {
          Bitmap.createBitmap(
              Mockito.anyInt(),
              Mockito.anyInt(),
              Mockito.any(Bitmap.Config::class.java),
          )
        }
        .thenReturn(bitmap)
  }

  private fun verifyBasic(
      canvasWidth: Int,
      canvasHeight: Int,
      frameOriginalWidth: Int,
      frameOriginalHeight: Int,
      frameExpectedRenderedWidth: Int,
      frameExpectedRenderedHeight: Int,
  ) {
    whenever(canvas.width).thenReturn(canvasWidth)
    whenever(canvas.height).thenReturn(canvasHeight)
    whenever(frame.width).thenReturn(frameOriginalWidth)
    whenever(frame.height).thenReturn(frameOriginalHeight)

    val animatedDrawableBackendImpl =
        AnimatedDrawableBackendImpl(animatedDrawableUtil, animatedImageResult, rect, true)

    animatedDrawableBackendImpl.renderFrame(0, canvas)

    verify(frame).renderFrame(frameExpectedRenderedWidth, frameExpectedRenderedHeight, bitmap)
  }

  @After
  fun tearDownStaticMocks() {
    mockedBitmap.close()
  }

  @Test
  fun testSimple() {
    verifyBasic(128, 128, 512, 512, 128, 128)
  }

  @Test
  fun testNoUpscaling() {
    verifyBasic(128, 128, 16, 16, 16, 16)
  }

  @Test
  fun testNarrow() {
    verifyBasic(64, 128, 256, 256, 64, 64)
  }

  @Test
  fun testOffsets() {
    val frameSide = 1024
    val canvasSide = 256
    val scale = frameSide / canvasSide

    val frameOffset = 512
    whenever(frame.xOffset).thenReturn(frameOffset)
    whenever(frame.yOffset).thenReturn(frameOffset)

    verifyBasic(canvasSide, canvasSide, frameSide, frameSide, frameSide / scale, frameSide / scale)
    verify(canvas).translate((frameOffset / scale).toFloat(), (frameOffset / scale).toFloat())
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/animated/impl/AnimatedFrameCacheTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.impl

import com.facebook.cache.common.CacheKey
import com.facebook.cache.common.SimpleCacheKey
import com.facebook.common.internal.Supplier
import com.facebook.common.memory.MemoryTrimmableRegistry
import com.facebook.common.references.CloseableReference
import com.facebook.common.util.ByteConstants
import com.facebook.imagepipeline.cache.BitmapMemoryCacheTrimStrategy
import com.facebook.imagepipeline.cache.CountingLruBitmapMemoryCacheFactory
import com.facebook.imagepipeline.cache.CountingMemoryCache
import com.facebook.imagepipeline.cache.MemoryCacheParams
import com.facebook.imagepipeline.image.CloseableImage
import java.util.concurrent.TimeUnit
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner

@RunWith(RobolectricTestRunner::class)
class AnimatedFrameCacheTest {
  private lateinit var memoryTrimmableRegistry: MemoryTrimmableRegistry
  private lateinit var memoryCacheParamsSupplier: Supplier<MemoryCacheParams>

  private lateinit var cacheKey: CacheKey
  private lateinit var animatedFrameCache: AnimatedFrameCache
  private lateinit var frame1: CloseableReference<CloseableImage>
  private lateinit var frame2: CloseableReference<CloseableImage>

  @Before
  fun setUp() {
    memoryTrimmableRegistry = mock()
    memoryCacheParamsSupplier = mock()

    val params: MemoryCacheParams =
        MemoryCacheParams(
            4 * ByteConstants.MB,
            256,
            Int.Companion.MAX_VALUE,
            Int.Companion.MAX_VALUE,
            Int.Companion.MAX_VALUE,
            TimeUnit.MINUTES.toMillis(5),
        )
    whenever(memoryCacheParamsSupplier.get()).thenReturn(params)
    val countingMemoryCache: CountingMemoryCache<CacheKey, CloseableImage> =
        CountingLruBitmapMemoryCacheFactory()
            .create(
                memoryCacheParamsSupplier,
                memoryTrimmableRegistry,
                BitmapMemoryCacheTrimStrategy(),
                false,
                false,
                null,
            )
    cacheKey = SimpleCacheKey("key")
    animatedFrameCache = AnimatedFrameCache(cacheKey, countingMemoryCache)
    frame1 = CloseableReference.of(mock<CloseableImage>())
    frame2 = CloseableReference.of(mock<CloseableImage>())
  }

  @Test
  fun testBasic() {
    val ret = animatedFrameCache.cache(1, frame1)
    assertThat(ret?.get()).isSameAs(frame1.get())
  }

  @Test
  fun testMultipleFrames() {
    animatedFrameCache.cache(1, frame1)
    animatedFrameCache.cache(2, frame2)
    assertThat(animatedFrameCache.get(1)?.get()).isSameAs(frame1.get())
    assertThat(animatedFrameCache.get(2)?.get()).isSameAs(frame2.get())
  }

  @Test
  fun testReplace() {
    animatedFrameCache.cache(1, frame1)
    animatedFrameCache.cache(1, frame2)
    assertThat(animatedFrameCache.get(1)?.get()).isNotSameAs(frame1.get())
    assertThat(animatedFrameCache.get(1)?.get()).isSameAs(frame2.get())
  }

  @Test
  fun testReuse() {
    val ret = animatedFrameCache.cache(1, frame1)
    ret?.close()
    val free = animatedFrameCache.getForReuse()
    assertThat(free).isNotNull()
  }

  @Test
  fun testCantReuseIfNotClosed() {
    val ret = animatedFrameCache.cache(1, frame1)
    val free = animatedFrameCache.getForReuse()
    assertThat(free).isNull()
  }

  @Test
  fun testStillThereIfClosed() {
    val ret = animatedFrameCache.cache(1, frame1)
    ret?.close()
    assertThat(animatedFrameCache.get(1)).isNotNull()
  }

  @Test
  fun testContains() {
    assertThat(animatedFrameCache.contains(1)).isFalse()

    val ret = animatedFrameCache.cache(1, frame1)

    assertThat(animatedFrameCache.contains(1)).isTrue()
    assertThat(animatedFrameCache.contains(2)).isFalse()

    ret?.close()

    assertThat(animatedFrameCache.contains(1)).isTrue()
    assertThat(animatedFrameCache.contains(2)).isFalse()
  }

  @Test
  fun testContainsWhenReused() {
    val ret = animatedFrameCache.cache(1, frame1)
    ret?.close()

    assertThat(animatedFrameCache.contains(1)).isTrue()
    assertThat(animatedFrameCache.contains(2)).isFalse()

    val free = animatedFrameCache.getForReuse()
    free?.close()

    assertThat(animatedFrameCache.contains(1)).isFalse()
    assertThat(animatedFrameCache.contains(2)).isFalse()
  }

  @Test
  fun testContainsFullReuseFlowWithMultipleItems() {
    assertThat(animatedFrameCache.contains(1)).isFalse()
    assertThat(animatedFrameCache.contains(2)).isFalse()

    val ret = animatedFrameCache.cache(1, frame1)
    val ret2 = animatedFrameCache.cache(2, frame2)

    assertThat(animatedFrameCache.contains(1)).isTrue()
    assertThat(animatedFrameCache.contains(2)).isTrue()

    ret?.close()
    ret2?.close()

    assertThat(animatedFrameCache.contains(1)).isTrue()
    assertThat(animatedFrameCache.contains(2)).isTrue()

    var free = animatedFrameCache.getForReuse()
    free?.close()

    assertThat(animatedFrameCache.contains(1)).isFalse()
    assertThat(animatedFrameCache.contains(2)).isTrue()

    free = animatedFrameCache.getForReuse()
    free?.close()

    assertThat(animatedFrameCache.contains(1)).isFalse()
    assertThat(animatedFrameCache.contains(2)).isFalse()
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/animated/testing/TestAnimatedDrawableBackend.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.testing;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import com.facebook.common.references.CloseableReference;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableBackend;
import com.facebook.imagepipeline.animated.base.AnimatedDrawableFrameInfo;
import com.facebook.imagepipeline.animated.base.AnimatedImageResult;
import com.facebook.infer.annotation.Nullsafe;
import javax.annotation.Nullable;

/** Implementation of {@link AnimatedDrawableBackend} for unit tests. */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class TestAnimatedDrawableBackend implements AnimatedDrawableBackend {

  private final int mWidth;
  private final int mHeight;
  private final int[] mFrameDurations;
  private final int[] mAccumulatedDurationsMs;

  private int mDropCachesCallCount;

  public TestAnimatedDrawableBackend(int width, int height, int[] frameDurations) {
    mWidth = width;
    mHeight = height;
    mFrameDurations = frameDurations;
    mAccumulatedDurationsMs = new int[mFrameDurations.length];
    int accumulatedDurationMs = 0;
    for (int i = 0; i < mAccumulatedDurationsMs.length; i++) {
      mAccumulatedDurationsMs[i] = accumulatedDurationMs + mFrameDurations[i];
      accumulatedDurationMs = mAccumulatedDurationsMs[i];
    }
  }

  public static int pixelValue(int frameNumber, int x, int y) {
    return ((frameNumber & 0xff) << 16) | ((x & 0xff) << 8) | ((y & 0xff));
  }

  @Nullable
  @Override
  // NULLSAFE_FIXME[Inconsistent Subclass Return Annotation]
  public AnimatedImageResult getAnimatedImageResult() {
    return null;
  }

  @Override
  public int getDurationMs() {
    return mAccumulatedDurationsMs[mAccumulatedDurationsMs.length - 1];
  }

  @Override
  public int getFrameCount() {
    return mFrameDurations.length;
  }

  @Override
  public int getLoopCount() {
    return 0;
  }

  @Override
  public int getWidth() {
    return mWidth;
  }

  @Override
  public int getHeight() {
    return mHeight;
  }

  @Override
  public int getRenderedWidth() {
    return mWidth;
  }

  @Override
  public int getRenderedHeight() {
    return mHeight;
  }

  @Override
  public AnimatedDrawableFrameInfo getFrameInfo(int frameNumber) {
    return new AnimatedDrawableFrameInfo(
        frameNumber,
        0,
        0,
        mWidth,
        mHeight,
        AnimatedDrawableFrameInfo.BlendOperation.NO_BLEND,
        AnimatedDrawableFrameInfo.DisposalMethod.DISPOSE_DO_NOT);
  }

  @Override
  public void renderFrame(int frameNumber, Canvas canvas) {
    int[] pixels = new int[mWidth * mHeight];
    for (int i = 0; i < pixels.length; i++) {
      // We store the frame number in the R, the x in the G, and the y in the B.
      int x = i % mWidth;
      int y = i / mWidth;
      pixels[i] = pixelValue(frameNumber, x, y);
    }
    Bitmap bitmap = Bitmap.createBitmap(pixels, mWidth, mHeight, Bitmap.Config.ARGB_8888);
    canvas.drawBitmap(bitmap, 0, 0, null);
  }

  @Override
  public void renderDeltas(int frameNumber, Canvas canvas) {
    renderFrame(frameNumber, canvas);
  }

  @Override
  public int getFrameForTimestampMs(int timestampMs) {
    int accumulator = 0;
    for (int i = 0; i < mFrameDurations.length; i++) {
      if (timestampMs < accumulator + mFrameDurations[i]) {
        return i;
      }
      accumulator += mFrameDurations[i];
    }
    return mFrameDurations.length - 1;
  }

  @Override
  public int getTimestampMsForFrame(int frameNumber) {
    return frameNumber == 0 ? 0 : mAccumulatedDurationsMs[frameNumber - 1];
  }

  @Override
  public int getDurationMsForFrame(int frameNumber) {
    return mFrameDurations[frameNumber];
  }

  @Override
  public int getFrameForPreview() {
    return 0;
  }

  @Override
  public AnimatedDrawableBackend forNewBounds(@Nullable Rect bounds) {
    return this;
  }

  @Override
  public int getMemoryUsage() {
    return 0;
  }

  @Nullable
  @Override
  public CloseableReference<Bitmap> getPreDecodedFrame(int frameNumber) {
    return null;
  }

  @Override
  public boolean hasPreDecodedFrame(int frameNumber) {
    return false;
  }

  public int getDropCachesCallCount() {
    return mDropCachesCallCount;
  }

  @Override
  public void dropCaches() {
    mDropCachesCallCount++;
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/animated/util/AnimatedDrawableUtilTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.animated.util

import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner

/** Tests for [AnimatedDrawableUtil]. */
@RunWith(RobolectricTestRunner::class)
class AnimatedDrawableUtilTest {
  @Test
  fun testGetFrameTimeStampsFromDurations() {
    val frameDurationsMs = intArrayOf(30, 30, 60, 30, 30)
    val util = AnimatedDrawableUtil()
    val frameTimestampsMs = util.getFrameTimeStampsFromDurations(frameDurationsMs)
    val expected = intArrayOf(0, 30, 60, 120, 150)
    assertThat(frameTimestampsMs).isEqualTo(expected)
  }

  @Test
  fun testGetFrameTimeStampsFromDurationsWithEmptyArray() {
    val frameDurationsMs = IntArray(0)
    val util = AnimatedDrawableUtil()
    val frameTimestampsMs = util.getFrameTimeStampsFromDurations(frameDurationsMs)
    assertThat(frameTimestampsMs.size.toLong()).isEqualTo(0)
  }

  @Test
  fun testGetFrameForTimestampMs() {
    val frameTimestampsMs = intArrayOf(0, 50, 75, 100, 200)
    val util = AnimatedDrawableUtil()
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 0).toLong()).isEqualTo(0)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 1).toLong()).isEqualTo(0)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 49).toLong()).isEqualTo(0)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 50).toLong()).isEqualTo(1)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 74).toLong()).isEqualTo(1)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 75).toLong()).isEqualTo(2)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 76).toLong()).isEqualTo(2)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 99).toLong()).isEqualTo(2)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 100).toLong()).isEqualTo(3)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 101).toLong()).isEqualTo(3)
    assertThat(util.getFrameForTimestampMs(frameTimestampsMs, 200).toLong()).isEqualTo(4)
  }

  @Test
  fun testIsOutsideRange() {
    assertThat(AnimatedDrawableUtil.isOutsideRange(-1, -1, 1)).isTrue() // Always outside range

    // Test before, within, and after 2 through 5.
    var start = 2
    var end = 5
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 1)).isTrue()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 2)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 3)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 4)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 5)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 6)).isTrue()

    // Test wrapping case when start is greater than end
    // Test before, within, and after 4 through 1
    start = 4
    end = 1
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 0)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 1)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 2)).isTrue()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 3)).isTrue()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 4)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 5)).isFalse()

    // Test cases where start == end
    start = 2
    end = 2
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 1)).isTrue()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 2)).isFalse()
    assertThat(AnimatedDrawableUtil.isOutsideRange(start, end, 3)).isTrue()
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/producers/AnimatedRepeatedPostprocessorProducerTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.producers

import android.graphics.Bitmap
import com.facebook.common.internal.ImmutableMap
import com.facebook.common.references.CloseableReference
import com.facebook.common.references.ResourceReleaser
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
import com.facebook.imagepipeline.common.Priority
import com.facebook.imagepipeline.core.ImagePipelineConfig
import com.facebook.imagepipeline.image.CloseableAnimatedImage
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.CloseableStaticBitmap
import com.facebook.imagepipeline.producers.PostprocessorProducer.RepeatedPostprocessorConsumer
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.RepeatedPostprocessor
import com.facebook.imagepipeline.request.RepeatedPostprocessorRunner
import com.facebook.imagepipeline.testing.FakeClock
import com.facebook.imagepipeline.testing.TestExecutorService
import java.util.ArrayList
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.InOrder
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doThrow
import org.mockito.kotlin.eq
import org.mockito.kotlin.inOrder
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE)
class AnimatedRepeatedPostprocessorProducerTest {

  companion object {
    private const val POSTPROCESSOR_NAME = "postprocessor_name"
    private val extraMap = ImmutableMap.of(PostprocessorProducer.POSTPROCESSOR, POSTPROCESSOR_NAME)
  }

  @Mock lateinit var platformBitmapFactory: PlatformBitmapFactory
  @Mock lateinit var producerListener: ProducerListener2
  @Mock lateinit var inputProducer: Producer<CloseableReference<CloseableImage>>
  @Mock lateinit var consumer: Consumer<CloseableReference<CloseableImage>>
  @Mock lateinit var postprocessor: RepeatedPostprocessor
  @Mock lateinit var bitmapResourceReleaser: ResourceReleaser<Bitmap>

  @Mock lateinit var imageRequest: ImageRequest

  @Mock lateinit var config: ImagePipelineConfig

  private lateinit var producerContext: SettableProducerContext
  private val requestId = "requestId"
  private lateinit var sourceBitmap: Bitmap
  private lateinit var sourceCloseableStaticBitmap: CloseableStaticBitmap
  private lateinit var sourceCloseableImageRef: CloseableReference<CloseableImage>
  private lateinit var destinationBitmap: Bitmap
  private lateinit var destinationCloseableBitmapRef: CloseableReference<Bitmap>
  private lateinit var testExecutorService: TestExecutorService
  private lateinit var postprocessorProducer: PostprocessorProducer
  private lateinit var results: MutableList<CloseableReference<CloseableImage>>

  private lateinit var inOrder: InOrder

  @Before
  fun setUp() {
    MockitoAnnotations.initMocks(this)
    testExecutorService = TestExecutorService(FakeClock())
    postprocessorProducer =
        PostprocessorProducer(inputProducer, platformBitmapFactory, testExecutorService)
    producerContext =
        SettableProducerContext(
            imageRequest,
            requestId,
            producerListener,
            mock<Object>(),
            ImageRequest.RequestLevel.FULL_FETCH,
            false /* isPrefetch */,
            false /* isIntermediateResultExpected */,
            Priority.MEDIUM,
            config,
        )
    whenever(imageRequest.postprocessor).thenReturn(postprocessor)
    results = ArrayList()
    whenever(postprocessor.name).thenReturn(POSTPROCESSOR_NAME)
    whenever(producerListener.requiresExtraMap(producerContext, POSTPROCESSOR_NAME))
        .thenReturn(true)
    doAnswer { invocation ->
          results.add((invocation.arguments[0] as CloseableReference<CloseableImage>).clone())
          null
        }
        .whenever(consumer)
        .onNewResult(any(), any<Int>())
    inOrder = inOrder(postprocessor, producerListener, consumer)
  }

  @Test
  fun testNonStaticBitmapIsPassedOn() {
    val postprocessorConsumer = produceResults()
    val repeatedPostprocessorRunner = getRunner()

    val sourceCloseableAnimatedImage = mock<CloseableAnimatedImage>()
    val sourceCloseableImageRef =
        CloseableReference.of<CloseableImage>(sourceCloseableAnimatedImage)
    postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST)
    sourceCloseableImageRef.close()
    testExecutorService.runUntilIdle()

    inOrder
        .verify(consumer)
        .onNewResult(any<CloseableReference<CloseableImage>>(), eq(Consumer.NO_FLAGS))
    inOrder.verifyNoMoreInteractions()

    assertThat(results).hasSize(1)
    val res0 = results[0]
    assertThat(CloseableReference.isValid(res0)).isTrue()
    assertThat(res0.get()).isSameAs(sourceCloseableAnimatedImage)
    res0.close()

    performCancelAndVerifyOnCancellation()
    verify(sourceCloseableAnimatedImage).close()
  }

  private fun setupNewSourceImage() {
    sourceBitmap = mock<Bitmap>()
    sourceCloseableStaticBitmap = mock<CloseableStaticBitmap>()
    whenever(sourceCloseableStaticBitmap.underlyingBitmap).thenReturn(sourceBitmap)
    sourceCloseableImageRef = CloseableReference.of<CloseableImage>(sourceCloseableStaticBitmap)
  }

  private fun setupNewDestinationImage() {
    destinationBitmap = mock<Bitmap>()
    destinationCloseableBitmapRef = CloseableReference.of(destinationBitmap, bitmapResourceReleaser)
    doReturn(destinationCloseableBitmapRef)
        .whenever(postprocessor)
        .process(sourceBitmap, platformBitmapFactory)
  }

  private fun produceResults(): RepeatedPostprocessorConsumer {
    postprocessorProducer.produceResults(consumer, producerContext)

    // Use argumentCaptor from Mockito Kotlin
    val consumerCaptor = argumentCaptor<Consumer<CloseableReference<CloseableImage>>>()
    verify(inputProducer).produceResults(consumerCaptor.capture(), eq(producerContext))
    return consumerCaptor.firstValue as RepeatedPostprocessorConsumer
  }

  private fun getRunner(): RepeatedPostprocessorRunner {
    val captor = argumentCaptor<RepeatedPostprocessorRunner>()
    inOrder.verify(postprocessor).setCallback(captor.capture())
    return captor.firstValue
  }

  private fun performNewResult(postprocessorConsumer: RepeatedPostprocessorConsumer, run: Boolean) {
    setupNewSourceImage()
    setupNewDestinationImage()
    postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST)
    sourceCloseableImageRef.close()
    if (run) {
      testExecutorService.runUntilIdle()
    }
  }

  private fun performUpdate(
      repeatedPostprocessorRunner: RepeatedPostprocessorRunner,
      run: Boolean,
  ) {
    setupNewDestinationImage()
    repeatedPostprocessorRunner.update()
    if (run) {
      testExecutorService.runUntilIdle()
    }
  }

  private fun performUpdateDuringTheNextPostprocessing(
      repeatedPostprocessorRunner: RepeatedPostprocessorRunner
  ) {
    doAnswer {
          val destBitmapRef = destinationCloseableBitmapRef
          performUpdate(repeatedPostprocessorRunner, false)
          // the following call should be ignored
          performUpdate(repeatedPostprocessorRunner, false)
          destBitmapRef
        }
        .whenever(postprocessor)
        .process(sourceBitmap, platformBitmapFactory)
  }

  private fun performFailure(repeatedPostprocessorRunner: RepeatedPostprocessorRunner) {
    setupNewDestinationImage()
    doThrow(RuntimeException()).whenever(postprocessor).process(sourceBitmap, platformBitmapFactory)
    repeatedPostprocessorRunner.update()
    testExecutorService.runUntilIdle()
  }

  private fun performCancelAndVerifyOnCancellation() {
    performCancel()
    inOrder.verify(consumer).onCancellation()
  }

  private fun performCancelAfterFinished() {
    performCancel()
    inOrder.verify(consumer, never()).onCancellation()
  }

  private fun performCancel() {
    producerContext.cancel()
    testExecutorService.runUntilIdle()
  }

  private fun verifyNewResultProcessed(index: Int) {
    verifyNewResultProcessed(index, destinationBitmap)
  }

  private fun verifyNewResultProcessed(index: Int, destBitmap: Bitmap) {
    inOrder.verify(producerListener).onProducerStart(producerContext, PostprocessorProducer.NAME)
    inOrder.verify(postprocessor).process(sourceBitmap, platformBitmapFactory)
    inOrder.verify(producerListener).requiresExtraMap(producerContext, PostprocessorProducer.NAME)
    inOrder
        .verify(producerListener)
        .onProducerFinishWithSuccess(producerContext, PostprocessorProducer.NAME, extraMap)
    inOrder
        .verify(consumer)
        .onNewResult(any<CloseableReference<CloseableImage>>(), eq(Consumer.NO_FLAGS))
    inOrder.verifyNoMoreInteractions()

    assertThat(results).hasSize(index + 1)
    val res0 = results[index]
    assertThat(CloseableReference.isValid(res0)).isTrue()
    assertThat((res0.get() as CloseableStaticBitmap).underlyingBitmap).isSameAs(destBitmap)
    res0.close()
    verify(bitmapResourceReleaser).release(destBitmap)
  }
}


================================================
FILE: animated-base/src/test/java/com/facebook/imagepipeline/producers/AnimatedSingleUsePostprocessorProducerTest.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.imagepipeline.producers

import android.graphics.Bitmap
import com.facebook.common.internal.ImmutableMap
import com.facebook.common.references.CloseableReference
import com.facebook.common.references.ResourceReleaser
import com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory
import com.facebook.imagepipeline.image.CloseableAnimatedImage
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.CloseableStaticBitmap
import com.facebook.imagepipeline.producers.PostprocessorProducer.SingleUsePostprocessorConsumer
import com.facebook.imagepipeline.request.ImageRequest
import com.facebook.imagepipeline.request.Postprocessor
import com.facebook.imagepipeline.testing.FakeClock
import com.facebook.imagepipeline.testing.TestExecutorService
import java.util.ArrayList
import org.assertj.core.api.Assertions.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.InOrder
import org.mockito.Mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doAnswer
import org.mockito.kotlin.eq
import org.mockito.kotlin.inOrder
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(manifest = Config.NONE)
class AnimatedSingleUsePostprocessorProducerTest {

  companion object {
    private const val POSTPROCESSOR_NAME = "postprocessor_name"
    private val extraMap = ImmutableMap.of(PostprocessorProducer.POSTPROCESSOR, POSTPROCESSOR_NAME)
  }

  @Mock lateinit var platformBitmapFactory: PlatformBitmapFactory
  @Mock lateinit var producerContext: ProducerContext
  @Mock lateinit var producerListener: ProducerListener2
  @Mock lateinit var inputProducer: Producer<CloseableReference<CloseableImage>>
  @Mock lateinit var consumer: Consumer<CloseableReference<CloseableImage>>
  @Mock lateinit var postprocessor: Postprocessor
  @Mock lateinit var bitmapResourceReleaser: ResourceReleaser<Bitmap>

  @Mock lateinit var imageRequest: ImageRequest

  private val requestId = "mRequestId"
  private lateinit var sourceBitmap: Bitmap
  private lateinit var sourceCloseableStaticBitmap: CloseableStaticBitmap
  private lateinit var sourceCloseableImageRef: CloseableReference<CloseableImage>
  private lateinit var destinationBitmap: Bitmap
  private lateinit var destinationCloseableBitmapRef: CloseableReference<Bitmap>
  private lateinit var testExecutorService: TestExecutorService
  private lateinit var postprocessorProducer: PostprocessorProducer
  private lateinit var results: MutableList<CloseableReference<CloseableImage>>

  private lateinit var inOrder: InOrder

  @Before
  fun setUp() {
    MockitoAnnotations.initMocks(this)
    testExecutorService = TestExecutorService(FakeClock())
    postprocessorProducer =
        PostprocessorProducer(inputProducer, platformBitmapFactory, testExecutorService)

    whenever(imageRequest.postprocessor).thenReturn(postprocessor)
    whenever(producerContext.id).thenReturn(requestId)
    whenever(producerContext.producerListener).thenReturn(producerListener)
    whenever(producerContext.imageRequest).thenReturn(imageRequest)

    results = ArrayList()
    whenever(postprocessor.name).thenReturn(POSTPROCESSOR_NAME)
    whenever(producerListener.requiresExtraMap(eq(producerContext), eq(POSTPROCESSOR_NAME)))
        .thenReturn(true)
    doAnswer { invocation ->
          results.add((invocation.arguments[0] as CloseableReference<CloseableImage>).clone())
          null
        }
        .whenever(consumer)
        .onNewResult(any(), any())
    inOrder = inOrder(postprocessor, producerListener, consumer)

    sourceBitmap = mock<Bitmap>()
    sourceCloseableStaticBitmap = mock<CloseableStaticBitmap>()
    whenever(sourceCloseableStaticBitmap.underlyingBitmap).thenReturn(sourceBitmap)
    sourceCloseableImageRef = CloseableReference.of<CloseableImage>(sourceCloseableStaticBitmap)
    destinationBitmap = mock<Bitmap>()
    destinationCloseableBitmapRef = CloseableReference.of(destinationBitmap, bitmapResourceReleaser)
  }

  @Test
  fun testNonStaticBitmapIsPassedOn() {
    val postprocessorConsumer = produceResults()
    val sourceCloseableAnimatedImage = mock<CloseableAnimatedImage>()
    val sourceCloseableImageRef =
        CloseableReference.of<CloseableImage>(sourceCloseableAnimatedImage)
    postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST)
    sourceCloseableImageRef.close()
    testExecutorService.runUntilIdle()

    inOrder
        .verify(consumer)
        .onNewResult(any<CloseableReference<CloseableImage>>(), eq(Consumer.IS_LAST))
    inOrder.verifyNoMoreInteractions()

    assertThat(results).hasSize(1)
    val res0 = results[0]
    assertThat(CloseableReference.isValid(res0)).isTrue()
    assertThat(res0.get()).isSameAs(sourceCloseableAnimatedImage)
    res0.close()

    verify(sourceCloseableAnimatedImage).close()
  }

  private fun produceResults(): SingleUsePostprocessorConsumer {
    postprocessorProducer.produceResults(consumer, producerContext)

    val consumerCaptor = argumentCaptor<Consumer<CloseableReference<CloseableImage>>>()
    verify(inputProducer).produceResults(consumerCaptor.capture(), eq(producerContext))
    return consumerCaptor.firstValue as SingleUsePostprocessorConsumer
  }
}


================================================
FILE: animated-drawable/.gitignore
================================================
/build
nativedeps/


================================================
FILE: animated-drawable/README.md
================================================
# Experimental Implementation for Animated Images

This is an experimental new animation implementation that is still work in progress.
The APIs & design might change significantly in the future.


================================================
FILE: animated-drawable/build.gradle
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import com.facebook.fresco.buildsrc.Deps
import com.facebook.fresco.buildsrc.GradleDeps
import com.facebook.fresco.buildsrc.TestDeps

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

kotlin {
    jvmToolchain(11)
}

android {
    ndkVersion GradleDeps.Native.version

    buildToolsVersion FrescoConfig.buildToolsVersion
    compileSdkVersion FrescoConfig.compileSdkVersion

    namespace "com.facebook.animated.drawable"

    defaultConfig {
        minSdkVersion FrescoConfig.minSdkVersion
        targetSdkVersion FrescoConfig.targetSdkVersion
    }

    lintOptions {
        abortOnError false
    }
    testOptions {
        unitTests.returnDefaultValues = true
    }
}

dependencies {
    compileOnly Deps.AndroidX.androidxAnnotation
    compileOnly Deps.inferAnnotation
    compileOnly Deps.jsr305
    compileOnly Deps.javaxAnnotation

    testCompileOnly Deps.inferAnnotation
    testImplementation Deps.AndroidX.androidxAnnotation
    testImplementation Deps.jsr305
    testImplementation TestDeps.assertjCore
    testImplementation TestDeps.junit
    testImplementation TestDeps.festAssertCore
    testImplementation TestDeps.mockitoCore3
    testImplementation TestDeps.mockitoInline3
    testImplementation TestDeps.mockitoKotlin3
    testImplementation(TestDeps.robolectric) {
        exclude group: 'commons-logging', module: 'commons-logging'
        exclude group: 'org.apache.httpcomponents', module: 'httpclient'
    }
    testImplementation project(':imagepipeline-test')
    testImplementation project(':imagepipeline-base-test')


    implementation project(':imagepipeline-base')
    implementation project(':drawee')
    implementation project(':fbcore')
    implementation project(':urimod')
    implementation project(':vito:core')
    implementation project(':vito:options')
    implementation project(':vito:provider')
    implementation project(':vito:renderer')
    implementation project(':vito:source')
}

apply plugin: "com.vanniktech.maven.publish"


================================================
FILE: animated-drawable/gradle.properties
================================================
POM_NAME=AnimatedDrawable
POM_DESCRIPTION=Animated drawable that renders GIFs, WebPs and other Animations
POM_ARTIFACT_ID=animated-drawable
POM_PACKAGING=aar



================================================
FILE: animated-drawable/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.facebook.animated.drawable"
    >
</manifest>


================================================
FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackend.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.backend;

import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import androidx.annotation.IntRange;
import javax.annotation.Nullable;

/** Animation backend interface that is used to draw frames. */
public interface AnimationBackend extends AnimationInformation {

  interface Listener {

    /** Trigger when full animation is loaded and ready to play */
    void onAnimationLoaded();
  }

  /**
   * Default value if the intrinsic dimensions are not set.
   *
   * @see #getIntrinsicWidth()
   * @see #getIntrinsicHeight()
   */
  int INTRINSIC_DIMENSION_UNSET = -1;

  /**
   * Draw the frame for the given frame number on the canvas.
   *
   * @param parent the parent that draws the frame
   * @param canvas the canvas to draw an
   * @param frameNumber the frame number of the frame to draw
   * @return true if successful, false if the frame could not be rendered
   */
  boolean drawFrame(Drawable parent, Canvas canvas, int frameNumber);

  /**
   * Set the alpha value to be used for drawing frames in {@link #drawFrame(Drawable, Canvas, int)}
   * if supported.
   *
   * @param alpha the alpha value between 0 and 255
   */
  void setAlpha(@IntRange(from = 0, to = 255) int alpha);

  /**
   * The color filter to be used for drawing frames in {@link #drawFrame(Drawable, Canvas, int)} if
   * supported.
   *
   * @param colorFilter the color filter to use
   */
  void setColorFilter(@Nullable ColorFilter colorFilter);

  /**
   * Called when the bounds of the parent drawable are updated. This can be used to perform some
   * ahead-of-time computations if needed.
   *
   * <p>The supplied bounds do not have to be stored. It is possible to just use {@link
   * Drawable#getBounds()} of the parent drawable of {@link #drawFrame(Drawable, Canvas, int)}
   * instead.
   *
   * @param bounds the bounds to be used for drawing frames
   */
  void setBounds(Rect bounds);

  /**
   * Get the intrinsic width of the underlying animation or {@link #INTRINSIC_DIMENSION_UNSET} if
   * not available.
   *
   * <p>This value is used by the underlying drawable for aspect ratio computations, similar to
   * {@link Drawable#getIntrinsicWidth()}.
   *
   * @return the width or {@link #INTRINSIC_DIMENSION_UNSET} if unset
   */
  int getIntrinsicWidth();

  /**
   * Get the intrinsic height of the underlying animation or {@link #INTRINSIC_DIMENSION_UNSET} if
   * not available.
   *
   * <p>This value is used by the underlying drawable for aspect ratio computations, similar to
   * {@link Drawable#getIntrinsicHeight()}.
   *
   * @return the height or {@link #INTRINSIC_DIMENSION_UNSET} if unset
   */
  int getIntrinsicHeight();

  /**
   * Get the size of the animation backend.
   *
   * @return the size in bytes
   */
  int getSizeInBytes();

  /**
   * Clean up animation data. This will be called when the backing drawable is cleared as well. For
   * example, drop all cached frames.
   */
  void clear();

  /** Load animation bitmaps using the animation frame as canvas size. */
  void preloadAnimation();

  /** Set listener for animation events */
  void setAnimationListener(@Nullable Listener listener);
}


================================================
FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackendDelegate.kt
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.backend

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Rect
import android.graphics.drawable.Drawable
import androidx.annotation.IntRange

/** Animation backend delegate that forwards all calls to a given [AnimationBackend] */
open class AnimationBackendDelegate<T : AnimationBackend?>(
    /** Current animation backend in use */
    private var _animationBackend: T?
) : AnimationBackend {

  // Animation backend parameters
  @IntRange(from = -1, to = 255) private var alpha = ALPHA_UNSET

  private var colorFilter: ColorFilter? = null
  private var bounds: Rect? = null

  override fun getFrameCount(): Int =
      if (_animationBackend == null) 0 else _animationBackend!!.frameCount

  override fun getFrameDurationMs(frameNumber: Int): Int =
      if (_animationBackend == null) 0 else _animationBackend!!.getFrameDurationMs(frameNumber)

  override fun getLoopDurationMs(): Int =
      if (_animationBackend == null) 0 else _animationBackend!!.loopDurationMs

  override fun width(): Int = if (_animationBackend == null) 0 else _animationBackend!!.width()

  override fun height(): Int = if (_animationBackend == null) 0 else _animationBackend!!.height()

  override fun getLoopCount(): Int =
      if (_animationBackend == null) AnimationInformation.LOOP_COUNT_INFINITE
      else _animationBackend!!.loopCount

  override fun drawFrame(parent: Drawable, canvas: Canvas, frameNumber: Int): Boolean =
      _animationBackend?.drawFrame(parent, canvas, frameNumber) == true

  override fun setAlpha(@IntRange(from = 0, to = 255) alpha: Int) {
    _animationBackend?.setAlpha(alpha)
    this.alpha = alpha
  }

  override fun setColorFilter(colorFilter: ColorFilter?) {
    _animationBackend?.setColorFilter(colorFilter)
    this.colorFilter = colorFilter
  }

  override fun setBounds(bounds: Rect) {
    _animationBackend?.setBounds(bounds)
    this.bounds = bounds
  }

  override fun getSizeInBytes(): Int =
      if (_animationBackend == null) 0 else _animationBackend!!.sizeInBytes

  override fun clear() {
    _animationBackend?.clear()
  }

  override fun preloadAnimation() {
    _animationBackend?.preloadAnimation()
  }

  override fun setAnimationListener(listener: AnimationBackend.Listener?) {
    _animationBackend?.setAnimationListener(listener)
  }

  override fun getIntrinsicWidth(): Int =
      if (_animationBackend == null) AnimationBackend.INTRINSIC_DIMENSION_UNSET
      else _animationBackend!!.intrinsicWidth

  override fun getIntrinsicHeight(): Int =
      if (_animationBackend == null) AnimationBackend.INTRINSIC_DIMENSION_UNSET
      else _animationBackend!!.intrinsicHeight

  var animationBackend: T?
    /**
     * Get the current animation backend.
     *
     * @return the current animation backend in use or null if not set
     */
    get() = _animationBackend
    /**
     * Set the animation backend to forward calls to. If called with null, the current backend will
     * be removed.
     *
     * @param animationBackend the backend to use or null to remove the current backend
     */
    set(animationBackend) {
      this._animationBackend = animationBackend
      if (this._animationBackend != null) {
        applyBackendProperties(_animationBackend!!)
      }
    }

  @SuppressLint("Range")
  private fun applyBackendProperties(backend: AnimationBackend) {
    if (bounds != null) {
      backend.setBounds(bounds)
    }
    if (alpha >= 0 && alpha <= 255) {
      backend.setAlpha(alpha)
    }
    if (colorFilter != null) {
      backend.setColorFilter(colorFilter)
    }
  }

  companion object {
    private const val ALPHA_UNSET = -1
  }
}


================================================
FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackendDelegateWithInactivityCheck.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.backend;

import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import androidx.annotation.VisibleForTesting;
import com.facebook.common.time.MonotonicClock;
import com.facebook.infer.annotation.Nullsafe;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;

/**
 * Animation backend delegate for animation backends that implement {@link InactivityListener}.
 * After a certain inactivity period (default = {@link #INACTIVITY_THRESHOLD_MS}, {@link
 * InactivityListener#onInactive()} will be called.
 *
 * <p>This can for example be used to drop caches if needed.
 *
 * <p>New instances can be created with {@link #createForBackend(AnimationBackend, MonotonicClock,
 * ScheduledExecutorService)}.
 */
@Nullsafe(Nullsafe.Mode.LOCAL)
public class AnimationBackendDelegateWithInactivityCheck<T extends AnimationBackend>
    extends AnimationBackendDelegate<T> {

  public interface InactivityListener {

    /**
     * Called when the animation backend has not been used to draw frames within the given
     * threshold.
     */
    void onInactive();
  }

  public static <
          T extends
              AnimationBackend & AnimationBackendDelegateWithInactivityCheck.InactivityListener>
      AnimationBackendDelegate<T> createForBackend(
          T backend,
          MonotonicClock monotonicClock,
          ScheduledExecutorService scheduledExecutorServiceForUiThread) {
    return createForBackend(backend, backend, monotonicClock, scheduledExecutorServiceForUiThread);
  }

  public static <T extends AnimationBackend> AnimationBackendDelegate<T> createForBackend(
      T backend,
      InactivityListener inactivityListener,
      MonotonicClock monotonicClock,
      ScheduledExecutorService scheduledExecutorServiceForUiThread) {
    return new AnimationBackendDelegateWithInactivityCheck<>(
        backend, inactivityListener, monotonicClock, scheduledExecutorServiceForUiThread);
  }

  @VisibleForTesting static final long INACTIVITY_THRESHOLD_MS = 2000;
  @VisibleForTesting static final long INACTIVITY_CHECK_POLLING_TIME_MS = 1000;

  private final MonotonicClock mMonotonicClock;
  private final ScheduledExecutorService mScheduledExecutorServiceForUiThread;
  private boolean mInactivityCheckScheduled = false;
  private long mLastDrawnTimeMs;
  private long mInactivityThresholdMs = INACTIVITY_THRESHOLD_MS;
  private long mInactivityCheckPollingTimeMs = INACTIVITY_CHECK_POLLING_TIME_MS;
  @Nullable private InactivityListener mInactivityListener;

  /**
   * Watchdog runnable that calls {@link InactivityListener#onInactive()} if necessary or schedules
   * a new watchdog task otherwise.
   */
  private final Runnable mIsInactiveCheck =
      new Runnable() {
        @Override
        public void run() {
          synchronized (AnimationBackendDelegateWithInactivityCheck.this) {
            mInactivityCheckScheduled = false;
            if (isInactive()) {
              if (mInactivityListener != null) {
                mInactivityListener.onInactive();
              }
            } else {
              maybeScheduleInactivityCheck();
            }
          }
        }
      };

  private AnimationBackendDelegateWithInactivityCheck(
      @Nullable T animationBackend,
      @Nullable InactivityListener inactivityListener,
      MonotonicClock monotonicClock,
      ScheduledExecutorService scheduledExecutorServiceForUiThread) {
    super(animationBackend);
    mInactivityListener = inactivityListener;
    mMonotonicClock = monotonicClock;
    mScheduledExecutorServiceForUiThread = scheduledExecutorServiceForUiThread;
  }

  @Override
  public boolean drawFrame(Drawable parent, Canvas canvas, int frameNumber) {
    mLastDrawnTimeMs = mMonotonicClock.now();
    boolean result = super.drawFrame(parent, canvas, frameNumber);
    maybeScheduleInactivityCheck();
    return result;
  }

  public void setInactivityListener(@Nullable InactivityListener inactivityListener) {
    mInactivityListener = inactivityListener;
  }

  public long getInactivityCheckPollingTimeMs() {
    return mInactivityCheckPollingTimeMs;
  }

  public void setInactivityCheckPollingTimeMs(long inactivityCheckPollingTimeMs) {
    mInactivityCheckPollingTimeMs = inactivityCheckPollingTimeMs;
  }

  public long getInactivityThresholdMs() {
    return mInactivityThresholdMs;
  }

  public void setInactivityThresholdMs(long inactivityThresholdMs) {
    mInactivityThresholdMs = inactivityThresholdMs;
  }

  private boolean isInactive() {
    return mMonotonicClock.now() - mLastDrawnTimeMs > mInactivityThresholdMs;
  }

  private synchronized void maybeScheduleInactivityCheck() {
    if (!mInactivityCheckScheduled) {
      mInactivityCheckScheduled = true;
      mScheduledExecutorServiceForUiThread.schedule(
          mIsInactiveCheck, mInactivityCheckPollingTimeMs, TimeUnit.MILLISECONDS);
    }
  }
}


================================================
FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationInformation.java
================================================
/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.fresco.animation.backend;

import com.facebook.infer.annotation.Nullsafe;

/** Basic animation metadata: Frame and loop count & duration */
@Nullsafe(Nullsafe.Mode.LOCAL
Download .txt
gitextract_dq5d7atw/

├── .github/
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   ├── stale.yml
│   └── workflows/
│       ├── build.yml
│       ├── gradle-wrapper-validation.yml
│       └── release.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── animated-base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               ├── fresco/
│       │               │   └── animation/
│       │               │       ├── bitmap/
│       │               │       │   ├── cache/
│       │               │       │   │   ├── AnimationFrameCacheKey.kt
│       │               │       │   │   └── FrescoFrameCache.kt
│       │               │       │   └── wrapper/
│       │               │       │       ├── AnimatedDrawableBackendAnimationInformation.kt
│       │               │       │       └── AnimatedDrawableBackendFrameRenderer.kt
│       │               │       ├── drawable/
│       │               │       │   └── animator/
│       │               │       │       └── AnimatedDrawableValueAnimatorHelper.kt
│       │               │       └── factory/
│       │               │           ├── AnimatedFactoryV2Impl.kt
│       │               │           └── DefaultBitmapAnimationDrawableFactory.kt
│       │               └── imagepipeline/
│       │                   ├── animated/
│       │                   │   ├── base/
│       │                   │   │   ├── AnimatedDrawableBackend.java
│       │                   │   │   ├── AnimatedDrawableFrameInfo.java
│       │                   │   │   ├── AnimatedDrawableOptions.java
│       │                   │   │   ├── AnimatedDrawableOptionsBuilder.java
│       │                   │   │   ├── AnimatedImage.java
│       │                   │   │   ├── AnimatedImageFrame.java
│       │                   │   │   ├── AnimatedImageResult.java
│       │                   │   │   ├── AnimatedImageResultBuilder.java
│       │                   │   │   ├── AnimatedImageValidator.kt
│       │                   │   │   └── package-info.java
│       │                   │   ├── factory/
│       │                   │   │   ├── AnimatedImageDecoder.kt
│       │                   │   │   ├── AnimatedImageDecoderBase.kt
│       │                   │   │   └── AnimatedImageFactory.kt
│       │                   │   ├── impl/
│       │                   │   │   ├── AnimatedDrawableBackendImpl.java
│       │                   │   │   ├── AnimatedDrawableBackendProvider.java
│       │                   │   │   ├── AnimatedFrameCache.java
│       │                   │   │   ├── AnimatedImageCompositor.java
│       │                   │   │   └── package-info.java
│       │                   │   └── util/
│       │                   │       ├── AnimatedDrawableUtil.kt
│       │                   │       └── package-info.kt
│       │                   └── image/
│       │                       ├── CloseableAnimatedImage.java
│       │                       └── package-info.java
│       └── test/
│           └── java/
│               ├── android/
│               │   └── net/
│               │       └── http/
│               │           └── AndroidHttpClient.java
│               └── com/
│                   └── facebook/
│                       ├── fresco/
│                       │   └── animation/
│                       │       └── bitmap/
│                       │           ├── cache/
│                       │           │   └── FrescoFrameCacheTest.kt
│                       │           └── wrapper/
│                       │               ├── AnimatedDrawableBackendAnimationInformationTest.kt
│                       │               └── AnimatedDrawableBackendFrameRendererTest.kt
│                       └── imagepipeline/
│                           ├── animated/
│                           │   ├── impl/
│                           │   │   ├── AnimatedDrawableBackendImplTest.kt
│                           │   │   └── AnimatedFrameCacheTest.kt
│                           │   ├── testing/
│                           │   │   └── TestAnimatedDrawableBackend.java
│                           │   └── util/
│                           │       └── AnimatedDrawableUtilTest.kt
│                           └── producers/
│                               ├── AnimatedRepeatedPostprocessorProducerTest.kt
│                               └── AnimatedSingleUsePostprocessorProducerTest.kt
├── animated-drawable/
│   ├── .gitignore
│   ├── README.md
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── fresco/
│       │                   └── animation/
│       │                       ├── backend/
│       │                       │   ├── AnimationBackend.java
│       │                       │   ├── AnimationBackendDelegate.kt
│       │                       │   ├── AnimationBackendDelegateWithInactivityCheck.java
│       │                       │   └── AnimationInformation.java
│       │                       ├── bitmap/
│       │                       │   ├── BitmapAnimationBackend.kt
│       │                       │   ├── BitmapFrameCache.kt
│       │                       │   ├── BitmapFrameRenderer.kt
│       │                       │   ├── cache/
│       │                       │   │   ├── KeepLastFrameCache.kt
│       │                       │   │   └── NoOpCache.kt
│       │                       │   └── preparation/
│       │                       │       ├── BitmapFramePreparationStrategy.kt
│       │                       │       ├── BitmapFramePreparer.kt
│       │                       │       ├── DefaultBitmapFramePreparer.kt
│       │                       │       ├── FixedNumberBitmapFramePreparationStrategy.kt
│       │                       │       ├── FrameLoaderStrategy.kt
│       │                       │       ├── loadframe/
│       │                       │       │   ├── AnimationLoaderExecutor.kt
│       │                       │       │   └── FpsCompressorInfo.kt
│       │                       │       └── ondemandanimation/
│       │                       │           ├── AnimationBitmapFrame.kt
│       │                       │           ├── AnimationCoordinator.kt
│       │                       │           ├── AnimationLoaderFactory.kt
│       │                       │           ├── BufferFrameLoader.kt
│       │                       │           ├── CircularList.kt
│       │                       │           └── FrameLoader.kt
│       │                       ├── drawable/
│       │                       │   ├── AnimatedDrawable2.kt
│       │                       │   ├── AnimatedDrawable2DebugDrawListener.kt
│       │                       │   ├── AnimationFrameScheduler.kt
│       │                       │   ├── AnimationListener.kt
│       │                       │   ├── BaseAnimationListener.kt
│       │                       │   ├── KAnimatedDrawable2.kt
│       │                       │   └── animator/
│       │                       │       └── AnimatedDrawable2ValueAnimatorHelper.kt
│       │                       └── frame/
│       │                           ├── DropFramesFrameScheduler.kt
│       │                           └── FrameScheduler.java
│       └── test/
│           └── java/
│               ├── com/
│               │   └── facebook/
│               │       └── fresco/
│               │           └── animation/
│               │               ├── backend/
│               │               │   ├── AnimationBackendDelegateTest.kt
│               │               │   └── AnimationBackendDelegateWithInactivityCheckTest.kt
│               │               ├── bitmap/
│               │               │   ├── BitmapAnimationBackendTest.kt
│               │               │   └── preparation/
│               │               │       ├── DefaultBitmapFramePreparerTest.kt
│               │               │       └── FixedNumberBitmapFramePreparationStrategyTest.kt
│               │               └── frame/
│               │                   └── DropFramesFrameSchedulerTest.kt
│               └── javax/
│                   └── microedition/
│                       └── khronos/
│                           └── opengles/
│                               └── GL.java
├── animated-gif/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── facebook/
│       │   │           └── animated/
│       │   │               └── gif/
│       │   │                   ├── AnimatedImageGifValidator.kt
│       │   │                   ├── GifFrame.java
│       │   │                   ├── GifImage.java
│       │   │                   └── GifImageDecoder.kt
│       │   └── jni/
│       │       ├── Application.mk
│       │       ├── gifimage/
│       │       │   ├── Android.mk
│       │       │   ├── OnLoad.cpp
│       │       │   ├── gif.cpp
│       │       │   ├── jni_helpers.cpp
│       │       │   ├── jni_helpers.h
│       │       │   ├── locks.h
│       │       │   └── secure_memcpy.h
│       │       └── third-party/
│       │           └── giflib/
│       │               └── Android.mk
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── gif/
│                               └── GifImageDecoderTest.kt
├── animated-gif-lite/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── giflite/
│                               ├── GifDecoder.java
│                               ├── decoder/
│                               │   └── GifMetadataDecoder.java
│                               ├── draw/
│                               │   ├── MovieAnimatedImage.kt
│                               │   ├── MovieDrawer.kt
│                               │   ├── MovieFrame.kt
│                               │   └── MovieScaleHolder.kt
│                               └── drawable/
│                                   └── GifAnimationBackend.kt
├── animated-webp/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── animated/
│       │                   ├── webp/
│       │                   │   ├── WebPFrame.java
│       │                   │   ├── WebPImage.java
│       │                   │   └── WebPImageDecoder.kt
│       │                   └── webpdrawable/
│       │                       └── WebpAnimationBackend.kt
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── animated/
│                           └── webp/
│                               └── WebPImageDecoderTest.kt
├── bots/
│   └── IssueCommands.txt
├── build.gradle
├── buildSrc/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── buildsrc/
│                               ├── FrescoConfig.kt
│                               ├── GradleDeps.kt
│                               ├── TestDeps.kt
│                               ├── dependencies-samples.kt
│                               └── dependencies.kt
├── ci/
│   ├── build-and-test.sh
│   └── print-debug-info.sh
├── docs/
│   ├── .gitignore
│   ├── CNAME
│   ├── Gemfile
│   ├── NOGREP
│   ├── README.md
│   ├── _config.yml
│   ├── _data/
│   │   ├── authors.yml
│   │   ├── nav.yml
│   │   ├── nav_docs.yml
│   │   ├── powered_by.yml
│   │   ├── powered_by_highlight.yml
│   │   └── promo.yml
│   ├── _docs/
│   │   ├── 03-customizing-image-formats.md
│   │   ├── animations.md
│   │   ├── building-from-source.md
│   │   ├── caching.md
│   │   ├── closeable-references.md
│   │   ├── concepts.md
│   │   ├── configure-image-pipeline.md
│   │   ├── datasources-datasubscribers.md
│   │   ├── drawee-branches.md
│   │   ├── faq.md
│   │   ├── gotchas.md
│   │   ├── image-requests.md
│   │   ├── images-in-notifications.md
│   │   ├── index.md
│   │   ├── intro-image-pipeline.md
│   │   ├── listening-to-events.md
│   │   ├── media-variations.md
│   │   ├── placeholder-failure-retry.md
│   │   ├── post-processor.md
│   │   ├── prefetching.md
│   │   ├── progress-bars.md
│   │   ├── progressive-jpegs.md
│   │   ├── proguard.md
│   │   ├── requesting-multiple-images.md
│   │   ├── resizing.md
│   │   ├── rotation.md
│   │   ├── rounded-corners-and-circles.md
│   │   ├── sample-apps.md
│   │   ├── scaletypes.md
│   │   ├── shared-transitions.md
│   │   ├── supported-uris.md
│   │   ├── troubleshooting.md
│   │   ├── using-controllerbuilder.md
│   │   ├── using-image-pipeline.md
│   │   ├── using-other-network-layers.md
│   │   ├── using-simpledraweeview.md
│   │   ├── webp-support.md
│   │   └── writing-custom-views.md
│   ├── _includes/
│   │   ├── blog_pagination.html
│   │   ├── content/
│   │   │   ├── gridblocks.html
│   │   │   └── items/
│   │   │       └── gridblock.html
│   │   ├── doc.html
│   │   ├── doc_paging.html
│   │   ├── footer.html
│   │   ├── head.html
│   │   ├── hero.html
│   │   ├── home_header.html
│   │   ├── nav.html
│   │   ├── nav_search.html
│   │   ├── plugins/
│   │   │   ├── all_share.html
│   │   │   ├── button.html
│   │   │   ├── fb_pagelike.html
│   │   │   ├── github_star.html
│   │   │   ├── github_watch.html
│   │   │   ├── google_share.html
│   │   │   ├── group_join.html
│   │   │   ├── like_button.html
│   │   │   ├── plugin_row.html
│   │   │   ├── post_social_plugins.html
│   │   │   ├── slideshow.html
│   │   │   └── twitter_share.html
│   │   ├── post.html
│   │   ├── powered_by.html
│   │   ├── react/
│   │   │   ├── collection_nav.html
│   │   │   ├── header_nav.html
│   │   │   ├── nav_blog.html
│   │   │   └── nav_docs.html
│   │   ├── social_plugins.html
│   │   └── ui/
│   │       └── button.html
│   ├── _layouts/
│   │   ├── basic.html
│   │   ├── blog.html
│   │   ├── blog_default.html
│   │   ├── default.html
│   │   ├── doc_default.html
│   │   ├── doc_page.html
│   │   ├── docs.html
│   │   ├── home.html
│   │   ├── page.html
│   │   ├── plain.html
│   │   ├── post.html
│   │   └── redirect.html
│   ├── _sass/
│   │   ├── _base.scss
│   │   ├── _blog.scss
│   │   ├── _buttons.scss
│   │   ├── _footer.scss
│   │   ├── _gridBlock.scss
│   │   ├── _header.scss
│   │   ├── _poweredby.scss
│   │   ├── _promo.scss
│   │   ├── _react_docs_nav.scss
│   │   ├── _react_header_nav.scss
│   │   ├── _reset.scss
│   │   ├── _search.scss
│   │   ├── _slideshow.scss
│   │   ├── _syntax-highlighting.scss
│   │   └── _tables.scss
│   ├── css/
│   │   └── main.scss
│   ├── docs/
│   │   └── index.html
│   ├── index.md
│   ├── javadoc/
│   │   ├── assets/
│   │   │   ├── customizations.css
│   │   │   ├── customizations.js
│   │   │   ├── doclava-developer-core.css
│   │   │   ├── doclava-developer-docs.css
│   │   │   ├── doclava-developer-docs.js
│   │   │   ├── doclava-developer-reference.js
│   │   │   ├── jquery-history.js
│   │   │   ├── navtree_data.js
│   │   │   ├── prettify.js
│   │   │   ├── search_autocomplete.js
│   │   │   └── style.css
│   │   ├── index.html
│   │   └── reference/
│   │       ├── classes.html
│   │       ├── com/
│   │       │   └── facebook/
│   │       │       ├── animated/
│   │       │       │   ├── gif/
│   │       │       │   │   ├── GifFrame.html
│   │       │       │   │   ├── GifImage.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── giflite/
│   │       │       │   │   ├── GifDecoder.html
│   │       │       │   │   ├── decoder/
│   │       │       │   │   │   ├── GifMetadataDecoder.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── draw/
│   │       │       │   │   │   ├── MovieAnimatedImage.html
│   │       │       │   │   │   ├── MovieDrawer.html
│   │       │       │   │   │   ├── MovieFrame.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── drawable/
│   │       │       │   │   │   ├── GifAnimationBackend.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── webp/
│   │       │       │   │   ├── WebPFrame.html
│   │       │       │   │   ├── WebPImage.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── webpdrawable/
│   │       │       │       ├── WebpAnimationBackend.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── binaryresource/
│   │       │       │   ├── BinaryResource.html
│   │       │       │   ├── ByteArrayBinaryResource.html
│   │       │       │   ├── FileBinaryResource.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── cache/
│   │       │       │   ├── common/
│   │       │       │   │   ├── BaseCacheEventListener.html
│   │       │       │   │   ├── CacheErrorLogger.CacheErrorCategory.html
│   │       │       │   │   ├── CacheErrorLogger.html
│   │       │       │   │   ├── CacheEvent.html
│   │       │       │   │   ├── CacheEventListener.EvictionReason.html
│   │       │       │   │   ├── CacheEventListener.html
│   │       │       │   │   ├── CacheKey.html
│   │       │       │   │   ├── CacheKeyUtil.html
│   │       │       │   │   ├── DebuggingCacheKey.html
│   │       │       │   │   ├── HasDebugData.html
│   │       │       │   │   ├── MultiCacheKey.html
│   │       │       │   │   ├── NoOpCacheErrorLogger.html
│   │       │       │   │   ├── NoOpCacheEventListener.html
│   │       │       │   │   ├── SimpleCacheKey.html
│   │       │       │   │   ├── WriterCallback.html
│   │       │       │   │   ├── WriterCallbacks.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── disk/
│   │       │       │       ├── DefaultDiskStorage.FileType.html
│   │       │       │       ├── DefaultDiskStorage.html
│   │       │       │       ├── DefaultEntryEvictionComparatorSupplier.html
│   │       │       │       ├── DiskCacheConfig.Builder.html
│   │       │       │       ├── DiskCacheConfig.html
│   │       │       │       ├── DiskStorage.DiskDumpInfo.html
│   │       │       │       ├── DiskStorage.DiskDumpInfoEntry.html
│   │       │       │       ├── DiskStorage.Entry.html
│   │       │       │       ├── DiskStorage.Inserter.html
│   │       │       │       ├── DiskStorage.html
│   │       │       │       ├── DiskStorageCache.Params.html
│   │       │       │       ├── DiskStorageCache.html
│   │       │       │       ├── DynamicDefaultDiskStorage.html
│   │       │       │       ├── EntryEvictionComparator.html
│   │       │       │       ├── EntryEvictionComparatorSupplier.html
│   │       │       │       ├── FileCache.html
│   │       │       │       ├── ScoreBasedEvictionComparatorSupplier.html
│   │       │       │       ├── SettableCacheEvent.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── callercontext/
│   │       │       │   ├── CallerContextVerifier.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── common/
│   │       │       │   ├── activitylistener/
│   │       │       │   │   ├── ActivityListener.html
│   │       │       │   │   ├── ActivityListenerManager.html
│   │       │       │   │   ├── BaseActivityListener.html
│   │       │       │   │   ├── ListenableActivity.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── disk/
│   │       │       │   │   ├── DiskTrimmable.html
│   │       │       │   │   ├── DiskTrimmableRegistry.html
│   │       │       │   │   ├── NoOpDiskTrimmableRegistry.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── executors/
│   │       │       │   │   ├── CallerThreadExecutor.html
│   │       │       │   │   ├── ConstrainedExecutorService.html
│   │       │       │   │   ├── DefaultSerialExecutorService.html
│   │       │       │   │   ├── HandlerExecutorService.html
│   │       │       │   │   ├── HandlerExecutorServiceImpl.html
│   │       │       │   │   ├── ScheduledFutureImpl.html
│   │       │       │   │   ├── SerialExecutorService.html
│   │       │       │   │   ├── StatefulRunnable.html
│   │       │       │   │   ├── UiThreadImmediateExecutorService.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── file/
│   │       │       │   │   ├── FileTree.html
│   │       │       │   │   ├── FileTreeVisitor.html
│   │       │       │   │   ├── FileUtils.CreateDirectoryException.html
│   │       │       │   │   ├── FileUtils.FileDeleteException.html
│   │       │       │   │   ├── FileUtils.ParentDirNotFoundException.html
│   │       │       │   │   ├── FileUtils.RenameException.html
│   │       │       │   │   ├── FileUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── internal/
│   │       │       │   │   ├── AndroidPredicates.html
│   │       │       │   │   ├── ByteStreams.html
│   │       │       │   │   ├── Closeables.html
│   │       │       │   │   ├── CountingOutputStream.html
│   │       │       │   │   ├── DoNotStrip.html
│   │       │       │   │   ├── Files.html
│   │       │       │   │   ├── Fn.html
│   │       │       │   │   ├── ImmutableList.html
│   │       │       │   │   ├── ImmutableMap.html
│   │       │       │   │   ├── ImmutableSet.html
│   │       │       │   │   ├── Ints.html
│   │       │       │   │   ├── Objects.ToStringHelper.html
│   │       │       │   │   ├── Objects.html
│   │       │       │   │   ├── Preconditions.html
│   │       │       │   │   ├── Predicate.html
│   │       │       │   │   ├── Sets.html
│   │       │       │   │   ├── Supplier.html
│   │       │       │   │   ├── Suppliers.html
│   │       │       │   │   ├── Throwables.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── lifecycle/
│   │       │       │   │   ├── AttachDetachListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── logging/
│   │       │       │   │   ├── FLog.html
│   │       │       │   │   ├── FLogDefaultLoggingDelegate.html
│   │       │       │   │   ├── LoggingDelegate.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── media/
│   │       │       │   │   ├── MediaUtils.html
│   │       │       │   │   ├── MimeTypeMapWrapper.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── memory/
│   │       │       │   │   ├── ByteArrayPool.html
│   │       │       │   │   ├── MemoryTrimType.html
│   │       │       │   │   ├── MemoryTrimmable.html
│   │       │       │   │   ├── MemoryTrimmableRegistry.html
│   │       │       │   │   ├── NoOpMemoryTrimmableRegistry.html
│   │       │       │   │   ├── Pool.html
│   │       │       │   │   ├── PooledByteArrayBufferedInputStream.html
│   │       │       │   │   ├── PooledByteBuffer.ClosedException.html
│   │       │       │   │   ├── PooledByteBuffer.html
│   │       │       │   │   ├── PooledByteBufferFactory.html
│   │       │       │   │   ├── PooledByteBufferInputStream.html
│   │       │       │   │   ├── PooledByteBufferOutputStream.html
│   │       │       │   │   ├── PooledByteStreams.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── references/
│   │       │       │   │   ├── CloseableReference.CloseableRefType.html
│   │       │       │   │   ├── CloseableReference.LeakHandler.html
│   │       │       │   │   ├── CloseableReference.html
│   │       │       │   │   ├── DefaultCloseableReference.html
│   │       │       │   │   ├── FinalizerCloseableReference.html
│   │       │       │   │   ├── HasBitmap.html
│   │       │       │   │   ├── NoOpCloseableReference.html
│   │       │       │   │   ├── OOMSoftReference.html
│   │       │       │   │   ├── RefCountCloseableReference.html
│   │       │       │   │   ├── ResourceReleaser.html
│   │       │       │   │   ├── SharedReference.NullReferenceException.html
│   │       │       │   │   ├── SharedReference.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── statfs/
│   │       │       │   │   ├── StatFsHelper.StorageType.html
│   │       │       │   │   ├── StatFsHelper.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── streams/
│   │       │       │   │   ├── LimitedInputStream.html
│   │       │       │   │   ├── TailAppendingInputStream.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── time/
│   │       │       │   │   ├── AwakeTimeSinceBootClock.html
│   │       │       │   │   ├── Clock.html
│   │       │       │   │   ├── CurrentThreadTimeClock.html
│   │       │       │   │   ├── MonotonicClock.html
│   │       │       │   │   ├── MonotonicNanoClock.html
│   │       │       │   │   ├── RealtimeSinceBootClock.html
│   │       │       │   │   ├── SystemClock.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── util/
│   │       │       │   │   ├── ByteConstants.html
│   │       │       │   │   ├── ExceptionWithNoStacktrace.html
│   │       │       │   │   ├── HashCodeUtil.html
│   │       │       │   │   ├── Hex.html
│   │       │       │   │   ├── SecureHashUtil.html
│   │       │       │   │   ├── StreamUtil.html
│   │       │       │   │   ├── TriState.html
│   │       │       │   │   ├── UriUtil.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── webp/
│   │       │       │       ├── BitmapCreator.html
│   │       │       │       ├── WebpBitmapFactory.WebpErrorLogger.html
│   │       │       │       ├── WebpBitmapFactory.html
│   │       │       │       ├── WebpSupportStatus.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── datasource/
│   │       │       │   ├── AbstractDataSource.DataSourceInstrumenter.html
│   │       │       │   ├── AbstractDataSource.html
│   │       │       │   ├── BaseBooleanSubscriber.html
│   │       │       │   ├── BaseDataSubscriber.html
│   │       │       │   ├── DataSource.html
│   │       │       │   ├── DataSources.html
│   │       │       │   ├── DataSubscriber.html
│   │       │       │   ├── FirstAvailableDataSourceSupplier.html
│   │       │       │   ├── IncreasingQualityDataSourceSupplier.html
│   │       │       │   ├── RetainingDataSourceSupplier.html
│   │       │       │   ├── SimpleDataSource.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── drawable/
│   │       │       │   └── base/
│   │       │       │       ├── DrawableWithCaches.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── drawee/
│   │       │       │   ├── backends/
│   │       │       │   │   └── pipeline/
│   │       │       │   │       ├── DefaultDrawableFactory.html
│   │       │       │   │       ├── DraweeConfig.Builder.html
│   │       │       │   │       ├── DraweeConfig.html
│   │       │       │   │       ├── Fresco.html
│   │       │       │   │       ├── PipelineDraweeController.html
│   │       │       │   │       ├── PipelineDraweeControllerBuilder.html
│   │       │       │   │       ├── PipelineDraweeControllerBuilderSupplier.html
│   │       │       │   │       ├── PipelineDraweeControllerFactory.html
│   │       │       │   │       ├── debug/
│   │       │       │   │       │   ├── DebugOverlayImageOriginColor.html
│   │       │       │   │       │   ├── DebugOverlayImageOriginListener.html
│   │       │       │   │       │   ├── package-descr.html
│   │       │       │   │       │   └── package-summary.html
│   │       │       │   │       ├── info/
│   │       │       │   │       │   ├── ForwardingImageOriginListener.html
│   │       │       │   │       │   ├── ForwardingImagePerfDataListener.html
│   │       │       │   │       │   ├── ImageLoadStatus.html
│   │       │       │   │       │   ├── ImageOrigin.html
│   │       │       │   │       │   ├── ImageOriginListener.html
│   │       │       │   │       │   ├── ImageOriginRequestListener.html
│   │       │       │   │       │   ├── ImageOriginUtils.html
│   │       │       │   │       │   ├── ImagePerfData.html
│   │       │       │   │       │   ├── ImagePerfDataListener.html
│   │       │       │   │       │   ├── ImagePerfMonitor.html
│   │       │       │   │       │   ├── ImagePerfNotifier.html
│   │       │       │   │       │   ├── ImagePerfState.html
│   │       │       │   │       │   ├── ImagePerfUtils.html
│   │       │       │   │       │   ├── VisibilityState.html
│   │       │       │   │       │   ├── internal/
│   │       │       │   │       │   │   ├── ImagePerfControllerListener.html
│   │       │       │   │       │   │   ├── ImagePerfControllerListener2.html
│   │       │       │   │       │   │   ├── ImagePerfImageOriginListener.html
│   │       │       │   │       │   │   ├── ImagePerfRequestListener.html
│   │       │       │   │       │   │   ├── package-descr.html
│   │       │       │   │       │   │   └── package-summary.html
│   │       │       │   │       │   ├── package-descr.html
│   │       │       │   │       │   └── package-summary.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── components/
│   │       │       │   │   ├── DeferredReleaser.Releasable.html
│   │       │       │   │   ├── DeferredReleaser.html
│   │       │       │   │   ├── DraweeEventTracker.Event.html
│   │       │       │   │   ├── DraweeEventTracker.html
│   │       │       │   │   ├── RetryManager.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── controller/
│   │       │       │   │   ├── AbstractDraweeController.html
│   │       │       │   │   ├── AbstractDraweeControllerBuilder.CacheLevel.html
│   │       │       │   │   ├── AbstractDraweeControllerBuilder.html
│   │       │       │   │   ├── BaseControllerListener.html
│   │       │       │   │   ├── ControllerListener.html
│   │       │       │   │   ├── ControllerViewportVisibilityListener.html
│   │       │       │   │   ├── ForwardingControllerListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── debug/
│   │       │       │   │   ├── DebugControllerOverlayDrawable.html
│   │       │       │   │   ├── listener/
│   │       │       │   │   │   ├── ImageLoadingTimeControllerListener.html
│   │       │       │   │   │   ├── ImageLoadingTimeListener.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── drawable/
│   │       │       │   │   ├── ArrayDrawable.html
│   │       │       │   │   ├── AutoRotateDrawable.html
│   │       │       │   │   ├── CloneableDrawable.html
│   │       │       │   │   ├── DrawableParent.html
│   │       │       │   │   ├── DrawableProperties.html
│   │       │       │   │   ├── DrawableUtils.html
│   │       │       │   │   ├── FadeDrawable.OnFadeListener.html
│   │       │       │   │   ├── FadeDrawable.html
│   │       │       │   │   ├── ForwardingDrawable.html
│   │       │       │   │   ├── InstrumentedDrawable.Listener.html
│   │       │       │   │   ├── InstrumentedDrawable.html
│   │       │       │   │   ├── MatrixDrawable.html
│   │       │       │   │   ├── OrientedDrawable.html
│   │       │       │   │   ├── ProgressBarDrawable.html
│   │       │       │   │   ├── Rounded.html
│   │       │       │   │   ├── RoundedBitmapDrawable.html
│   │       │       │   │   ├── RoundedColorDrawable.html
│   │       │       │   │   ├── RoundedCornersDrawable.Type.html
│   │       │       │   │   ├── RoundedCornersDrawable.html
│   │       │       │   │   ├── RoundedDrawable.html
│   │       │       │   │   ├── RoundedNinePatchDrawable.html
│   │       │       │   │   ├── ScaleTypeDrawable.html
│   │       │       │   │   ├── ScalingUtils.AbstractScaleType.html
│   │       │       │   │   ├── ScalingUtils.InterpolatingScaleType.html
│   │       │       │   │   ├── ScalingUtils.ScaleType.html
│   │       │       │   │   ├── ScalingUtils.StatefulScaleType.html
│   │       │       │   │   ├── ScalingUtils.html
│   │       │       │   │   ├── TransformAwareDrawable.html
│   │       │       │   │   ├── TransformCallback.html
│   │       │       │   │   ├── VisibilityAwareDrawable.html
│   │       │       │   │   ├── VisibilityCallback.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── generic/
│   │       │       │   │   ├── GenericDraweeHierarchy.html
│   │       │       │   │   ├── GenericDraweeHierarchyBuilder.html
│   │       │       │   │   ├── GenericDraweeHierarchyInflater.html
│   │       │       │   │   ├── RootDrawable.html
│   │       │       │   │   ├── RoundingParams.RoundingMethod.html
│   │       │       │   │   ├── RoundingParams.html
│   │       │       │   │   ├── WrappingUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── gestures/
│   │       │       │   │   ├── GestureDetector.ClickListener.html
│   │       │       │   │   ├── GestureDetector.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── interfaces/
│   │       │       │   │   ├── DraweeController.html
│   │       │       │   │   ├── DraweeHierarchy.html
│   │       │       │   │   ├── SettableDraweeHierarchy.html
│   │       │       │   │   ├── SimpleDraweeControllerBuilder.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── span/
│   │       │       │   │   ├── DraweeSpan.html
│   │       │       │   │   ├── DraweeSpanStringBuilder.DraweeSpanChangedListener.html
│   │       │       │   │   ├── DraweeSpanStringBuilder.html
│   │       │       │   │   ├── SimpleDraweeSpanTextView.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── view/
│   │       │       │       ├── AspectRatioMeasure.Spec.html
│   │       │       │       ├── AspectRatioMeasure.html
│   │       │       │       ├── DraweeHolder.html
│   │       │       │       ├── DraweeTransition.html
│   │       │       │       ├── DraweeView.html
│   │       │       │       ├── GenericDraweeView.html
│   │       │       │       ├── MultiDraweeHolder.html
│   │       │       │       ├── SimpleDraweeView.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── fresco/
│   │       │       │   ├── animation/
│   │       │       │   │   ├── backend/
│   │       │       │   │   │   ├── AnimationBackend.html
│   │       │       │   │   │   ├── AnimationBackendDelegate.html
│   │       │       │   │   │   ├── AnimationBackendDelegateWithInactivityCheck.InactivityListener.html
│   │       │       │   │   │   ├── AnimationBackendDelegateWithInactivityCheck.html
│   │       │       │   │   │   ├── AnimationInformation.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── bitmap/
│   │       │       │   │   │   ├── BitmapAnimationBackend.FrameListener.html
│   │       │       │   │   │   ├── BitmapAnimationBackend.FrameType.html
│   │       │       │   │   │   ├── BitmapAnimationBackend.html
│   │       │       │   │   │   ├── BitmapFrameCache.FrameCacheListener.html
│   │       │       │   │   │   ├── BitmapFrameCache.html
│   │       │       │   │   │   ├── BitmapFrameRenderer.html
│   │       │       │   │   │   ├── cache/
│   │       │       │   │   │   │   ├── AnimationFrameCacheKey.html
│   │       │       │   │   │   │   ├── FrescoFrameCache.html
│   │       │       │   │   │   │   ├── KeepLastFrameCache.html
│   │       │       │   │   │   │   ├── NoOpCache.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   ├── package-summary.html
│   │       │       │   │   │   ├── preparation/
│   │       │       │   │   │   │   ├── BitmapFramePreparationStrategy.html
│   │       │       │   │   │   │   ├── BitmapFramePreparer.html
│   │       │       │   │   │   │   ├── DefaultBitmapFramePreparer.html
│   │       │       │   │   │   │   ├── FixedNumberBitmapFramePreparationStrategy.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   └── wrapper/
│   │       │       │   │   │       ├── AnimatedDrawableBackendAnimationInformation.html
│   │       │       │   │   │       ├── AnimatedDrawableBackendFrameRenderer.html
│   │       │       │   │   │       ├── package-descr.html
│   │       │       │   │   │       └── package-summary.html
│   │       │       │   │   ├── drawable/
│   │       │       │   │   │   ├── AnimatedDrawable2.DrawListener.html
│   │       │       │   │   │   ├── AnimatedDrawable2.html
│   │       │       │   │   │   ├── AnimatedDrawable2DebugDrawListener.html
│   │       │       │   │   │   ├── AnimationListener.html
│   │       │       │   │   │   ├── BaseAnimationListener.html
│   │       │       │   │   │   ├── animator/
│   │       │       │   │   │   │   ├── AnimatedDrawable2ValueAnimatorHelper.html
│   │       │       │   │   │   │   ├── AnimatedDrawableValueAnimatorHelper.html
│   │       │       │   │   │   │   ├── package-descr.html
│   │       │       │   │   │   │   └── package-summary.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── factory/
│   │       │       │   │   │   ├── AnimatedFactoryV2Impl.html
│   │       │       │   │   │   ├── ExperimentalBitmapAnimationDrawableFactory.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── frame/
│   │       │       │   │       ├── DropFramesFrameScheduler.html
│   │       │       │   │       ├── FrameScheduler.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── middleware/
│   │       │       │   │   ├── MiddlewareUtils.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── ui/
│   │       │       │       └── common/
│   │       │       │           ├── BaseControllerListener2.html
│   │       │       │           ├── ControllerListener2.Extras.html
│   │       │       │           ├── ControllerListener2.html
│   │       │       │           ├── DimensionsInfo.html
│   │       │       │           ├── ForwardingControllerListener2.html
│   │       │       │           ├── LoggingListener.html
│   │       │       │           ├── MultiUriHelper.html
│   │       │       │           ├── OnDrawControllerListener.html
│   │       │       │           ├── package-descr.html
│   │       │       │           └── package-summary.html
│   │       │       ├── imageformat/
│   │       │       │   ├── DefaultImageFormatChecker.html
│   │       │       │   ├── DefaultImageFormats.html
│   │       │       │   ├── ImageFormat.FormatChecker.html
│   │       │       │   ├── ImageFormat.html
│   │       │       │   ├── ImageFormatChecker.html
│   │       │       │   ├── ImageFormatCheckerUtils.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── imagepipeline/
│   │       │       │   ├── animated/
│   │       │       │   │   ├── base/
│   │       │       │   │   │   ├── AnimatedDrawableBackend.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.BlendOperation.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.DisposalMethod.html
│   │       │       │   │   │   ├── AnimatedDrawableFrameInfo.html
│   │       │       │   │   │   ├── AnimatedDrawableOptions.html
│   │       │       │   │   │   ├── AnimatedDrawableOptionsBuilder.html
│   │       │       │   │   │   ├── AnimatedImage.html
│   │       │       │   │   │   ├── AnimatedImageFrame.html
│   │       │       │   │   │   ├── AnimatedImageResult.html
│   │       │       │   │   │   ├── AnimatedImageResultBuilder.html
│   │       │       │   │   │   ├── DelegatingAnimatedDrawableBackend.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── factory/
│   │       │       │   │   │   ├── AnimatedFactory.html
│   │       │       │   │   │   ├── AnimatedFactoryProvider.html
│   │       │       │   │   │   ├── AnimatedImageDecoder.html
│   │       │       │   │   │   ├── AnimatedImageFactory.html
│   │       │       │   │   │   ├── AnimatedImageFactoryImpl.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   ├── impl/
│   │       │       │   │   │   ├── AnimatedDrawableBackendImpl.html
│   │       │       │   │   │   ├── AnimatedDrawableBackendProvider.html
│   │       │       │   │   │   ├── AnimatedFrameCache.html
│   │       │       │   │   │   ├── AnimatedImageCompositor.Callback.html
│   │       │       │   │   │   ├── AnimatedImageCompositor.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── util/
│   │       │       │   │       ├── AnimatedDrawableUtil.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── backends/
│   │       │       │   │   ├── okhttp3/
│   │       │       │   │   │   ├── OkHttpImagePipelineConfigFactory.html
│   │       │       │   │   │   ├── OkHttpNetworkFetcher.OkHttpNetworkFetchState.html
│   │       │       │   │   │   ├── OkHttpNetworkFetcher.html
│   │       │       │   │   │   ├── package-descr.html
│   │       │       │   │   │   └── package-summary.html
│   │       │       │   │   └── volley/
│   │       │       │   │       ├── RawRequest.html
│   │       │       │   │       ├── VolleyImagePipelineConfigFactory.html
│   │       │       │   │       ├── VolleyNetworkFetcher.VolleyNetworkFetchState.html
│   │       │       │   │       ├── VolleyNetworkFetcher.html
│   │       │       │   │       ├── package-descr.html
│   │       │       │   │       └── package-summary.html
│   │       │       │   ├── bitmaps/
│   │       │       │   │   ├── ArtBitmapFactory.html
│   │       │       │   │   ├── EmptyJpegGenerator.html
│   │       │       │   │   ├── GingerbreadBitmapFactory.html
│   │       │       │   │   ├── HoneycombBitmapCreator.html
│   │       │       │   │   ├── HoneycombBitmapFactory.html
│   │       │       │   │   ├── PlatformBitmapFactory.html
│   │       │       │   │   ├── PlatformBitmapFactoryProvider.html
│   │       │       │   │   ├── SimpleBitmapReleaser.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── cache/
│   │       │       │   │   ├── AbstractAdaptiveCountingMemoryCache.html
│   │       │       │   │   ├── BitmapMemoryCacheFactory.html
│   │       │       │   │   ├── BitmapMemoryCacheKey.html
│   │       │       │   │   ├── BitmapMemoryCacheTrimStrategy.html
│   │       │       │   │   ├── BoundedLinkedHashSet.html
│   │       │       │   │   ├── BufferedDiskCache.html
│   │       │       │   │   ├── CacheKeyFactory.html
│   │       │       │   │   ├── CountingLruBitmapMemoryCacheFactory.html
│   │       │       │   │   ├── CountingLruMap.html
│   │       │       │   │   ├── CountingMemoryCache.Entry.html
│   │       │       │   │   ├── CountingMemoryCache.EntryStateObserver.html
│   │       │       │   │   ├── CountingMemoryCache.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.DumpInfo.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.DumpInfoEntry.html
│   │       │       │   │   ├── CountingMemoryCacheInspector.html
│   │       │       │   │   ├── DefaultBitmapMemoryCacheParamsSupplier.html
│   │       │       │   │   ├── DefaultCacheKeyFactory.html
│   │       │       │   │   ├── DefaultEncodedMemoryCacheParamsSupplier.html
│   │       │       │   │   ├── EncodedCountingMemoryCacheFactory.html
│   │       │       │   │   ├── EncodedMemoryCacheFactory.html
│   │       │       │   │   ├── ImageCacheStatsTracker.html
│   │       │       │   │   ├── InstrumentedMemoryCache.html
│   │       │       │   │   ├── InstrumentedMemoryCacheBitmapMemoryCacheFactory.html
│   │       │       │   │   ├── LruCountingMemoryCache.html
│   │       │       │   │   ├── MemoryCache.CacheTrimStrategy.html
│   │       │       │   │   ├── MemoryCache.html
│   │       │       │   │   ├── MemoryCacheParams.html
│   │       │       │   │   ├── MemoryCacheTracker.html
│   │       │       │   │   ├── NativeMemoryCacheTrimStrategy.html
│   │       │       │   │   ├── NoOpImageCacheStatsTracker.html
│   │       │       │   │   ├── StagingArea.html
│   │       │       │   │   ├── ValueDescriptor.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── common/
│   │       │       │   │   ├── BytesRange.html
│   │       │       │   │   ├── ImageDecodeOptions.html
│   │       │       │   │   ├── ImageDecodeOptionsBuilder.html
│   │       │       │   │   ├── Priority.html
│   │       │       │   │   ├── ResizeOptions.html
│   │       │       │   │   ├── RotationOptions.RotationAngle.html
│   │       │       │   │   ├── RotationOptions.html
│   │       │       │   │   ├── SourceUriType.html
│   │       │       │   │   ├── TooManyBitmapsException.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── core/
│   │       │       │   │   ├── CloseableReferenceFactory.html
│   │       │       │   │   ├── DefaultExecutorSupplier.html
│   │       │       │   │   ├── DiskStorageCacheFactory.html
│   │       │       │   │   ├── DiskStorageFactory.html
│   │       │       │   │   ├── DynamicDefaultDiskStorageFactory.html
│   │       │       │   │   ├── ExecutorSupplier.html
│   │       │       │   │   ├── FileCacheFactory.html
│   │       │       │   │   ├── ImagePipeline.html
│   │       │       │   │   ├── ImagePipelineConfig.Builder.html
│   │       │       │   │   ├── ImagePipelineConfig.DefaultImageRequestConfig.html
│   │       │       │   │   ├── ImagePipelineConfig.html
│   │       │       │   │   ├── ImagePipelineExperiments.Builder.html
│   │       │       │   │   ├── ImagePipelineExperiments.DefaultProducerFactoryMethod.html
│   │       │       │   │   ├── ImagePipelineExperiments.ProducerFactoryMethod.html
│   │       │       │   │   ├── ImagePipelineExperiments.html
│   │       │       │   │   ├── ImagePipelineFactory.html
│   │       │       │   │   ├── ImageTranscoderType.html
│   │       │       │   │   ├── MemoryChunkType.html
│   │       │       │   │   ├── NativeCodeSetup.html
│   │       │       │   │   ├── PriorityThreadFactory.html
│   │       │       │   │   ├── ProducerFactory.html
│   │       │       │   │   ├── ProducerSequenceFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── datasource/
│   │       │       │   │   ├── AbstractProducerToDataSourceAdapter.html
│   │       │       │   │   ├── BaseBitmapDataSubscriber.html
│   │       │       │   │   ├── BaseBitmapReferenceDataSubscriber.html
│   │       │       │   │   ├── BaseListBitmapDataSubscriber.html
│   │       │       │   │   ├── CloseableProducerToDataSourceAdapter.html
│   │       │       │   │   ├── ListDataSource.html
│   │       │       │   │   ├── ProducerToDataSourceAdapter.html
│   │       │       │   │   ├── SettableDataSource.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── debug/
│   │       │       │   │   ├── CloseableReferenceLeakTracker.Listener.html
│   │       │       │   │   ├── CloseableReferenceLeakTracker.html
│   │       │       │   │   ├── DebugImageTracker.html
│   │       │       │   │   ├── FlipperCacheKeyFactory.html
│   │       │       │   │   ├── FlipperCloseableReferenceLeakTracker.html
│   │       │       │   │   ├── FlipperImageTracker.ImageDebugData.html
│   │       │       │   │   ├── FlipperImageTracker.html
│   │       │       │   │   ├── LruMap.html
│   │       │       │   │   ├── NoOpCloseableReferenceLeakTracker.html
│   │       │       │   │   ├── NoOpDebugImageTracker.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── decoder/
│   │       │       │   │   ├── DecodeException.html
│   │       │       │   │   ├── DefaultImageDecoder.html
│   │       │       │   │   ├── ImageDecoder.html
│   │       │       │   │   ├── ImageDecoderConfig.Builder.html
│   │       │       │   │   ├── ImageDecoderConfig.html
│   │       │       │   │   ├── ProgressiveJpegConfig.html
│   │       │       │   │   ├── ProgressiveJpegParser.html
│   │       │       │   │   ├── SimpleProgressiveJpegConfig.DynamicValueConfig.html
│   │       │       │   │   ├── SimpleProgressiveJpegConfig.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── drawable/
│   │       │       │   │   ├── DrawableFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── filter/
│   │       │       │   │   ├── InPlaceRoundFilter.html
│   │       │       │   │   ├── IterativeBoxBlurFilter.html
│   │       │       │   │   ├── RenderScriptBlurFilter.html
│   │       │       │   │   ├── XferRoundFilter.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── image/
│   │       │       │   │   ├── CloseableAnimatedImage.html
│   │       │       │   │   ├── CloseableBitmap.html
│   │       │       │   │   ├── CloseableImage.html
│   │       │       │   │   ├── CloseableStaticBitmap.html
│   │       │       │   │   ├── EncodedImage.html
│   │       │       │   │   ├── EncodedImageOrigin.html
│   │       │       │   │   ├── HasImageMetadata.html
│   │       │       │   │   ├── ImageInfo.html
│   │       │       │   │   ├── ImmutableQualityInfo.html
│   │       │       │   │   ├── OriginalEncodedImageInfo.html
│   │       │       │   │   ├── QualityInfo.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── instrumentation/
│   │       │       │   │   ├── FrescoInstrumenter.Instrumenter.html
│   │       │       │   │   ├── FrescoInstrumenter.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── listener/
│   │       │       │   │   ├── BaseRequestListener.html
│   │       │       │   │   ├── BaseRequestListener2.html
│   │       │       │   │   ├── ForwardingRequestListener.html
│   │       │       │   │   ├── ForwardingRequestListener2.html
│   │       │       │   │   ├── RequestListener.html
│   │       │       │   │   ├── RequestListener2.html
│   │       │       │   │   ├── RequestLoggingListener.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── memory/
│   │       │       │   │   ├── AshmemMemoryChunk.html
│   │       │       │   │   ├── AshmemMemoryChunkPool.html
│   │       │       │   │   ├── BasePool.InvalidSizeException.html
│   │       │       │   │   ├── BasePool.InvalidValueException.html
│   │       │       │   │   ├── BasePool.PoolSizeViolationException.html
│   │       │       │   │   ├── BasePool.SizeTooLargeException.html
│   │       │       │   │   ├── BasePool.html
│   │       │       │   │   ├── BitmapCounter.html
│   │       │       │   │   ├── BitmapCounterConfig.Builder.html
│   │       │       │   │   ├── BitmapCounterConfig.html
│   │       │       │   │   ├── BitmapCounterProvider.html
│   │       │       │   │   ├── BitmapPool.html
│   │       │       │   │   ├── BitmapPoolBackend.html
│   │       │       │   │   ├── BitmapPoolType.html
│   │       │       │   │   ├── BucketMap.html
│   │       │       │   │   ├── BucketsBitmapPool.html
│   │       │       │   │   ├── BufferMemoryChunk.html
│   │       │       │   │   ├── BufferMemoryChunkPool.html
│   │       │       │   │   ├── DefaultBitmapPoolParams.html
│   │       │       │   │   ├── DefaultByteArrayPoolParams.html
│   │       │       │   │   ├── DefaultFlexByteArrayPoolParams.html
│   │       │       │   │   ├── DefaultNativeMemoryChunkPoolParams.html
│   │       │       │   │   ├── DummyBitmapPool.html
│   │       │       │   │   ├── DummyTrackingInUseBitmapPool.html
│   │       │       │   │   ├── FlexByteArrayPool.html
│   │       │       │   │   ├── GenericByteArrayPool.html
│   │       │       │   │   ├── LruBitmapPool.html
│   │       │       │   │   ├── LruBucketsPoolBackend.html
│   │       │       │   │   ├── MemoryChunk.html
│   │       │       │   │   ├── MemoryChunkPool.html
│   │       │       │   │   ├── MemoryChunkUtil.html
│   │       │       │   │   ├── MemoryPooledByteBuffer.html
│   │       │       │   │   ├── MemoryPooledByteBufferFactory.html
│   │       │       │   │   ├── MemoryPooledByteBufferOutputStream.InvalidStreamException.html
│   │       │       │   │   ├── MemoryPooledByteBufferOutputStream.html
│   │       │       │   │   ├── NativeMemoryChunk.html
│   │       │       │   │   ├── NativeMemoryChunkPool.html
│   │       │       │   │   ├── NoOpPoolStatsTracker.html
│   │       │       │   │   ├── PoolConfig.Builder.html
│   │       │       │   │   ├── PoolConfig.html
│   │       │       │   │   ├── PoolFactory.html
│   │       │       │   │   ├── PoolParams.html
│   │       │       │   │   ├── PoolStatsTracker.html
│   │       │       │   │   ├── SharedByteArray.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── multiuri/
│   │       │       │   │   ├── MultiUri.Builder.html
│   │       │       │   │   ├── MultiUri.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── nativecode/
│   │       │       │   │   ├── Bitmaps.html
│   │       │       │   │   ├── DalvikPurgeableDecoder.html
│   │       │       │   │   ├── ImagePipelineNativeLoader.html
│   │       │       │   │   ├── NativeBlurFilter.html
│   │       │       │   │   ├── NativeCodeInitializer.html
│   │       │       │   │   ├── NativeFiltersLoader.html
│   │       │       │   │   ├── NativeImageTranscoderFactory.html
│   │       │       │   │   ├── NativeJpegTranscoder.html
│   │       │       │   │   ├── NativeJpegTranscoderFactory.html
│   │       │       │   │   ├── NativeJpegTranscoderSoLoader.html
│   │       │       │   │   ├── NativeRoundingFilter.html
│   │       │       │   │   ├── StaticWebpNativeLoader.html
│   │       │       │   │   ├── WebpTranscoder.html
│   │       │       │   │   ├── WebpTranscoderFactory.html
│   │       │       │   │   ├── WebpTranscoderImpl.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── platform/
│   │       │       │   │   ├── ArtDecoder.html
│   │       │       │   │   ├── DefaultDecoder.html
│   │       │       │   │   ├── GingerbreadPurgeableDecoder.html
│   │       │       │   │   ├── KitKatPurgeableDecoder.html
│   │       │       │   │   ├── OreoDecoder.html
│   │       │       │   │   ├── PlatformDecoder.html
│   │       │       │   │   ├── PlatformDecoderFactory.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── postprocessors/
│   │       │       │   │   ├── BlurPostProcessor.html
│   │       │       │   │   ├── IterativeBoxBlurPostProcessor.html
│   │       │       │   │   ├── RoundAsCirclePostprocessor.html
│   │       │       │   │   ├── RoundPostprocessor.html
│   │       │       │   │   ├── RoundedCornersPostprocessor.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── producers/
│   │       │       │   │   ├── AddImageTransformMetaDataProducer.html
│   │       │       │   │   ├── BaseConsumer.html
│   │       │       │   │   ├── BaseNetworkFetcher.html
│   │       │       │   │   ├── BaseProducerContext.html
│   │       │       │   │   ├── BaseProducerContextCallbacks.html
│   │       │       │   │   ├── BitmapMemoryCacheGetProducer.html
│   │       │       │   │   ├── BitmapMemoryCacheKeyMultiplexProducer.html
│   │       │       │   │   ├── BitmapMemoryCacheProducer.html
│   │       │       │   │   ├── BitmapPrepareProducer.html
│   │       │       │   │   ├── BitmapProbeProducer.html
│   │       │       │   │   ├── BranchOnSeparateImagesProducer.html
│   │       │       │   │   ├── Consumer.Status.html
│   │       │       │   │   ├── Consumer.html
│   │       │       │   │   ├── DataFetchProducer.html
│   │       │       │   │   ├── DecodeProducer.html
│   │       │       │   │   ├── DelayProducer.html
│   │       │       │   │   ├── DelegatingConsumer.html
│   │       │       │   │   ├── DiskCacheReadProducer.html
│   │       │       │   │   ├── DiskCacheWriteProducer.html
│   │       │       │   │   ├── EncodedCacheKeyMultiplexProducer.html
│   │       │       │   │   ├── EncodedMemoryCacheProducer.html
│   │       │       │   │   ├── EncodedProbeProducer.html
│   │       │       │   │   ├── ExperimentalThreadHandoffProducerQueueImpl.html
│   │       │       │   │   ├── FetchState.html
│   │       │       │   │   ├── HttpUrlConnectionNetworkFetcher.HttpUrlConnectionNetworkFetchState.html
│   │       │       │   │   ├── HttpUrlConnectionNetworkFetcher.html
│   │       │       │   │   ├── InternalProducerListener.html
│   │       │       │   │   ├── InternalRequestListener.html
│   │       │       │   │   ├── JobScheduler.JobRunnable.html
│   │       │       │   │   ├── JobScheduler.html
│   │       │       │   │   ├── LocalAssetFetchProducer.html
│   │       │       │   │   ├── LocalContentUriFetchProducer.html
│   │       │       │   │   ├── LocalContentUriThumbnailFetchProducer.html
│   │       │       │   │   ├── LocalExifThumbnailProducer.html
│   │       │       │   │   ├── LocalFetchProducer.html
│   │       │       │   │   ├── LocalFileFetchProducer.html
│   │       │       │   │   ├── LocalResourceFetchProducer.html
│   │       │       │   │   ├── LocalVideoThumbnailProducer.html
│   │       │       │   │   ├── MultiplexProducer.html
│   │       │       │   │   ├── NetworkFetchProducer.html
│   │       │       │   │   ├── NetworkFetcher.Callback.html
│   │       │       │   │   ├── NetworkFetcher.html
│   │       │       │   │   ├── NullProducer.html
│   │       │       │   │   ├── PartialDiskCacheProducer.html
│   │       │       │   │   ├── PostprocessedBitmapMemoryCacheProducer.CachedPostprocessorConsumer.html
│   │       │       │   │   ├── PostprocessedBitmapMemoryCacheProducer.html
│   │       │       │   │   ├── PostprocessorProducer.html
│   │       │       │   │   ├── PriorityNetworkFetcher.NonrecoverableException.html
│   │       │       │   │   ├── PriorityNetworkFetcher.PriorityFetchState.html
│   │       │       │   │   ├── PriorityNetworkFetcher.html
│   │       │       │   │   ├── PriorityStarvingThrottlingProducer.html
│   │       │       │   │   ├── Producer.html
│   │       │       │   │   ├── ProducerContext.ExtraKeys.html
│   │       │       │   │   ├── ProducerContext.html
│   │       │       │   │   ├── ProducerContextCallbacks.html
│   │       │       │   │   ├── ProducerListener.html
│   │       │       │   │   ├── ProducerListener2.html
│   │       │       │   │   ├── QualifiedResourceFetchProducer.html
│   │       │       │   │   ├── RemoveImageTransformMetaDataProducer.html
│   │       │       │   │   ├── ResizeAndRotateProducer.html
│   │       │       │   │   ├── SettableProducerContext.html
│   │       │       │   │   ├── StatefulProducerRunnable.html
│   │       │       │   │   ├── SwallowResultProducer.html
│   │       │       │   │   ├── ThreadHandoffProducer.html
│   │       │       │   │   ├── ThreadHandoffProducerQueue.html
│   │       │       │   │   ├── ThreadHandoffProducerQueueImpl.html
│   │       │       │   │   ├── ThrottlingProducer.html
│   │       │       │   │   ├── ThumbnailBranchProducer.html
│   │       │       │   │   ├── ThumbnailProducer.html
│   │       │       │   │   ├── ThumbnailSizeChecker.html
│   │       │       │   │   ├── WebpTranscodeProducer.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── request/
│   │       │       │   │   ├── BasePostprocessor.html
│   │       │       │   │   ├── BaseRepeatedPostProcessor.html
│   │       │       │   │   ├── HasImageRequest.html
│   │       │       │   │   ├── ImageRequest.CacheChoice.html
│   │       │       │   │   ├── ImageRequest.RequestLevel.html
│   │       │       │   │   ├── ImageRequest.html
│   │       │       │   │   ├── ImageRequestBuilder.BuilderException.html
│   │       │       │   │   ├── ImageRequestBuilder.html
│   │       │       │   │   ├── Postprocessor.html
│   │       │       │   │   ├── RepeatedPostprocessor.html
│   │       │       │   │   ├── RepeatedPostprocessorRunner.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── systrace/
│   │       │       │   │   ├── DefaultFrescoSystrace.html
│   │       │       │   │   ├── FrescoSystrace.ArgsBuilder.html
│   │       │       │   │   ├── FrescoSystrace.Systrace.html
│   │       │       │   │   ├── FrescoSystrace.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   ├── transcoder/
│   │       │       │   │   ├── DownsampleUtil.html
│   │       │       │   │   ├── ImageTranscodeResult.html
│   │       │       │   │   ├── ImageTranscoder.html
│   │       │       │   │   ├── ImageTranscoderFactory.html
│   │       │       │   │   ├── JpegTranscoderUtils.html
│   │       │       │   │   ├── MultiImageTranscoderFactory.html
│   │       │       │   │   ├── SimpleImageTranscoder.html
│   │       │       │   │   ├── SimpleImageTranscoderFactory.html
│   │       │       │   │   ├── TranscodeStatus.html
│   │       │       │   │   ├── package-descr.html
│   │       │       │   │   └── package-summary.html
│   │       │       │   └── transformation/
│   │       │       │       ├── BitmapTransformation.html
│   │       │       │       ├── package-descr.html
│   │       │       │       └── package-summary.html
│   │       │       ├── imageutils/
│   │       │       │   ├── BitmapUtil.html
│   │       │       │   ├── HeifExifUtil.html
│   │       │       │   ├── ImageMetaData.html
│   │       │       │   ├── JfifUtil.html
│   │       │       │   ├── WebpUtil.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       ├── webpsupport/
│   │       │       │   ├── WebpBitmapFactoryImpl.html
│   │       │       │   ├── package-descr.html
│   │       │       │   └── package-summary.html
│   │       │       └── widget/
│   │       │           └── text/
│   │       │               └── span/
│   │       │                   ├── BetterImageSpan.BetterImageSpanAlignment.html
│   │       │                   ├── BetterImageSpan.html
│   │       │                   ├── package-descr.html
│   │       │                   └── package-summary.html
│   │       ├── current.xml
│   │       ├── hierarchy.html
│   │       ├── index.html
│   │       ├── lists.js
│   │       ├── package-list
│   │       └── packages.html
│   ├── sample-license.md
│   ├── static/
│   │   ├── JSXTransformer.js
│   │   ├── js/
│   │   │   └── docsearch.js
│   │   ├── linkify.js
│   │   ├── pygments.css
│   │   ├── sample-images/
│   │   │   └── animation.keyframes
│   │   ├── site.css
│   │   └── transformer.js
│   └── support.md
├── drawee/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── facebook/
│       │   │           └── drawee/
│       │   │               ├── components/
│       │   │               │   ├── DeferredReleaser.java
│       │   │               │   ├── DeferredReleaserConcurrentImpl.java
│       │   │               │   ├── DraweeEventTracker.java
│       │   │               │   └── RetryManager.java
│       │   │               ├── controller/
│       │   │               │   ├── AbstractDraweeController.java
│       │   │               │   ├── AbstractDraweeControllerBuilder.java
│       │   │               │   ├── BaseControllerListener.java
│       │   │               │   ├── ControllerListener.java
│       │   │               │   ├── ControllerViewportVisibilityListener.java
│       │   │               │   ├── ForwardingControllerListener.java
│       │   │               │   └── package-info.java
│       │   │               ├── debug/
│       │   │               │   ├── DebugControllerOverlayDrawable.java
│       │   │               │   └── listener/
│       │   │               │       ├── ImageLoadingTimeControllerListener.kt
│       │   │               │       └── ImageLoadingTimeListener.kt
│       │   │               ├── drawable/
│       │   │               │   ├── ArrayDrawable.java
│       │   │               │   ├── AutoRotateDrawable.java
│       │   │               │   ├── CloneableDrawable.kt
│       │   │               │   ├── DrawableParent.kt
│       │   │               │   ├── DrawableProperties.kt
│       │   │               │   ├── DrawableUtils.kt
│       │   │               │   ├── FadeDrawable.java
│       │   │               │   ├── ForwardingDrawable.java
│       │   │               │   ├── InstrumentedDrawable.kt
│       │   │               │   ├── MatrixDrawable.java
│       │   │               │   ├── OrientedDrawable.kt
│       │   │               │   ├── ProgressBarDrawable.kt
│       │   │               │   ├── Rounded.kt
│       │   │               │   ├── RoundedBitmapDrawable.java
│       │   │               │   ├── RoundedColorDrawable.java
│       │   │               │   ├── RoundedCornersDrawable.java
│       │   │               │   ├── RoundedDrawable.java
│       │   │               │   ├── RoundedNinePatchDrawable.kt
│       │   │               │   ├── ScaleTypeDrawable.kt
│       │   │               │   ├── TransformAwareDrawable.kt
│       │   │               │   ├── TransformCallback.kt
│       │   │               │   ├── VisibilityAwareDrawable.kt
│       │   │               │   ├── VisibilityCallback.kt
│       │   │               │   └── package-info.kt
│       │   │               ├── generic/
│       │   │               │   ├── GenericDraweeHierarchy.java
│       │   │               │   ├── GenericDraweeHierarchyBuilder.java
│       │   │               │   ├── GenericDraweeHierarchyInflater.java
│       │   │               │   ├── RootDrawable.java
│       │   │               │   ├── RoundingParams.java
│       │   │               │   ├── WrappingUtils.java
│       │   │               │   └── package-info.java
│       │   │               ├── gestures/
│       │   │               │   └── GestureDetector.java
│       │   │               ├── interfaces/
│       │   │               │   ├── DraweeController.java
│       │   │               │   ├── DraweeHierarchy.java
│       │   │               │   ├── SettableDraweeHierarchy.java
│       │   │               │   ├── SimpleDraweeControllerBuilder.java
│       │   │               │   └── package-info.java
│       │   │               └── view/
│       │   │                   ├── AspectRatioMeasure.java
│       │   │                   ├── DraweeHolder.java
│       │   │                   ├── DraweeTransition.java
│       │   │                   ├── DraweeView.java
│       │   │                   ├── GenericDraweeView.java
│       │   │                   ├── MultiDraweeHolder.java
│       │   │                   ├── SimpleDraweeView.java
│       │   │                   └── package-info.java
│       │   └── res/
│       │       └── values/
│       │           └── attrs.xml
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       └── drawee/
│           │   │           ├── components/
│           │   │           │   └── DeferredReleaserStressTest.java
│           │   │           ├── controller/
│           │   │           │   └── AbstractDraweeControllerTest.java
│           │   │           ├── debug/
│           │   │           │   ├── DebugControllerOverlayDrawableInternalTest.java
│           │   │           │   ├── DebugControllerOverlayDrawableTest.java
│           │   │           │   └── DebugControllerOverlayDrawableTestHelper.java
│           │   │           ├── drawable/
│           │   │           │   ├── AndroidGraphicsTestUtils.java
│           │   │           │   ├── ArrayDrawableTest.java
│           │   │           │   ├── DrawableTestUtils.java
│           │   │           │   ├── DrawableUtilsTest.java
│           │   │           │   ├── FadeDrawableAllOnTest.java
│           │   │           │   ├── FadeDrawableOnFadeListenerTest.java
│           │   │           │   ├── FadeDrawableTest.java
│           │   │           │   ├── ForwardingDrawableTest.java
│           │   │           │   ├── MatrixDrawableTest.java
│           │   │           │   ├── OrientedDrawableTest.java
│           │   │           │   ├── RoundedBitmapDrawableTest.java
│           │   │           │   ├── RoundedColorDrawableTest.java
│           │   │           │   ├── RoundedCornersDrawableTest.java
│           │   │           │   ├── ScaleTypeDrawableTest.java
│           │   │           │   ├── ScalingUtilsTest.java
│           │   │           │   └── SettableDrawableTest.java
│           │   │           ├── generic/
│           │   │           │   ├── GenericDraweeHierarchyBuilderTest.java
│           │   │           │   └── RoundingParamsTest.java
│           │   │           ├── testing/
│           │   │           │   ├── DraweeMocks.java
│           │   │           │   └── DraweeMocksTest.java
│           │   │           └── view/
│           │   │               ├── AspectRatioMeasureTest.java
│           │   │               ├── DraweeHolderTest.java
│           │   │               ├── DraweeViewTest.java
│           │   │               └── MultiDraweeHolderTest.java
│           │   └── javax/
│           │       └── microedition/
│           │           └── khronos/
│           │               └── opengles/
│           │                   └── GL.java
│           └── resources/
│               └── org.robolectric.Config.properties
├── drawee-backends/
│   └── drawee-pipeline/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           ├── main/
│           │   ├── AndroidManifest.xml
│           │   └── java/
│           │       └── com/
│           │           └── facebook/
│           │               └── drawee/
│           │                   └── backends/
│           │                       └── pipeline/
│           │                           ├── DefaultDrawableFactory.java
│           │                           ├── DraweeConfig.java
│           │                           ├── Fresco.java
│           │                           ├── PipelineDraweeController.java
│           │                           ├── PipelineDraweeControllerBuilder.java
│           │                           ├── PipelineDraweeControllerBuilderSupplier.java
│           │                           ├── PipelineDraweeControllerFactory.java
│           │                           ├── info/
│           │                           │   ├── ForwardingImageOriginListener.java
│           │                           │   ├── ForwardingImagePerfDataListener.java
│           │                           │   ├── ImageOrigin.kt
│           │                           │   ├── ImageOriginListener.java
│           │                           │   ├── ImageOriginRequestListener.java
│           │                           │   ├── ImageOriginUtils.java
│           │                           │   ├── ImagePerfExtra.kt
│           │                           │   ├── ImagePerfMonitor.java
│           │                           │   └── internal/
│           │                           │       ├── ImagePerfRequestListener.java
│           │                           │       └── ImagePerfStateManager.java
│           │                           └── package-info.java
│           └── test/
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── drawee/
│                               └── backends/
│                                   └── pipeline/
│                                       └── info/
│                                           └── ImagePerfMonitorTest.java
├── drawee-span/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── drawee/
│       │                   └── span/
│       │                       ├── DraweeSpan.java
│       │                       ├── DraweeSpanStringBuilder.java
│       │                       └── SimpleDraweeSpanTextView.java
│       └── test/
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── drawee/
│                           └── span/
│                               ├── DraweeSpanStringBuilderTest.java
│                               └── DraweeSpanTest.java
├── fbcore/
│   ├── AndroidManifest.xml
│   ├── build.gradle
│   ├── gradle.properties
│   ├── proguard-fresco.pro
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       ├── com/
│       │       │   └── facebook/
│       │       │       ├── common/
│       │       │       │   ├── activitylistener/
│       │       │       │   │   ├── ActivityListener.java
│       │       │       │   │   ├── ActivityListenerManager.java
│       │       │       │   │   ├── BaseActivityListener.java
│       │       │       │   │   └── ListenableActivity.java
│       │       │       │   ├── callercontext/
│       │       │       │   │   ├── ContextChain.java
│       │       │       │   │   └── ImageAttribution.java
│       │       │       │   ├── closeables/
│       │       │       │   │   └── AutoCleanupDelegate.kt
│       │       │       │   ├── disk/
│       │       │       │   │   ├── DiskTrimmable.kt
│       │       │       │   │   ├── DiskTrimmableRegistry.kt
│       │       │       │   │   ├── NoOpDiskTrimmableRegistry.kt
│       │       │       │   │   └── package-info.kt
│       │       │       │   ├── executors/
│       │       │       │   │   ├── CallerThreadExecutor.java
│       │       │       │   │   ├── ConstrainedExecutorService.java
│       │       │       │   │   ├── DefaultSerialExecutorService.java
│       │       │       │   │   ├── HandlerExecutorService.java
│       │       │       │   │   ├── HandlerExecutorServiceImpl.java
│       │       │       │   │   ├── ScheduledFutureImpl.java
│       │       │       │   │   ├── SerialExecutorService.java
│       │       │       │   │   ├── StatefulRunnable.java
│       │       │       │   │   └── UiThreadImmediateExecutorService.java
│       │       │       │   ├── file/
│       │       │       │   │   ├── FileTree.java
│       │       │       │   │   ├── FileTreeVisitor.java
│       │       │       │   │   └── FileUtils.java
│       │       │       │   ├── internal/
│       │       │       │   │   ├── AndroidPredicates.java
│       │       │       │   │   ├── ByteStreams.java
│       │       │       │   │   ├── Closeables.java
│       │       │       │   │   ├── CountingOutputStream.java
│       │       │       │   │   ├── DoNotStrip.java
│       │       │       │   │   ├── Files.java
│       │       │       │   │   ├── Fn.java
│       │       │       │   │   ├── ImmutableList.java
│       │       │       │   │   ├── ImmutableMap.java
│       │       │       │   │   ├── ImmutableSet.java
│       │       │       │   │   ├── Objects.java
│       │       │       │   │   ├── Preconditions.java
│       │       │       │   │   ├── Predicate.java
│       │       │       │   │   ├── Sets.java
│       │       │       │   │   ├── Supplier.java
│       │       │       │   │   ├── Suppliers.java
│       │       │       │   │   ├── Throwables.java
│       │       │       │   │   ├── package-info.java
│       │       │       │   │   └── proguard_annotations.pro
│       │       │       │   ├── lifecycle/
│       │       │       │   │   └── AttachDetachListener.kt
│       │       │       │   ├── logging/
│       │       │       │   │   ├── FLog.kt
│       │       │       │   │   ├── FLogDefaultLoggingDelegate.java
│       │       │       │   │   ├── LoggingDelegate.java
│       │       │       │   │   ├── logging.pro
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── media/
│       │       │       │   │   ├── MediaUtils.kt
│       │       │       │   │   └── MimeTypeMapWrapper.kt
│       │       │       │   ├── memory/
│       │       │       │   │   ├── ByteArrayPool.java
│       │       │       │   │   ├── DecodeBufferHelper.java
│       │       │       │   │   ├── MemoryTrimType.java
│       │       │       │   │   ├── MemoryTrimmable.java
│       │       │       │   │   ├── MemoryTrimmableRegistry.java
│       │       │       │   │   ├── NoOpMemoryTrimmableRegistry.java
│       │       │       │   │   ├── Pool.java
│       │       │       │   │   ├── PooledByteArrayBufferedInputStream.java
│       │       │       │   │   ├── PooledByteBuffer.kt
│       │       │       │   │   ├── PooledByteBufferFactory.java
│       │       │       │   │   ├── PooledByteBufferInputStream.java
│       │       │       │   │   ├── PooledByteBufferOutputStream.java
│       │       │       │   │   ├── PooledByteStreams.java
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── references/
│       │       │       │   │   ├── CloseableReference.java
│       │       │       │   │   ├── DefaultCloseableReference.java
│       │       │       │   │   ├── FinalizerCloseableReference.java
│       │       │       │   │   ├── HasBitmap.java
│       │       │       │   │   ├── NoOpCloseableReference.java
│       │       │       │   │   ├── OOMSoftReference.java
│       │       │       │   │   ├── RefCountCloseableReference.java
│       │       │       │   │   ├── ResourceReleaser.java
│       │       │       │   │   ├── SharedReference.java
│       │       │       │   │   └── package-info.java
│       │       │       │   ├── statfs/
│       │       │       │   │   └── StatFsHelper.java
│       │       │       │   ├── streams/
│       │       │       │   │   ├── LimitedInputStream.kt
│       │       │       │   │   └── TailAppendingInputStream.kt
│       │       │       │   ├── time/
│       │       │       │   │   ├── AwakeTimeSinceBootClock.java
│       │       │       │   │   ├── Clock.java
│       │       │       │   │   ├── CurrentThreadTimeClock.java
│       │       │       │   │   ├── MonotonicClock.java
│       │       │       │   │   ├── MonotonicNanoClock.java
│       │       │       │   │   ├── RealtimeSinceBootClock.java
│       │       │       │   │   └── SystemClock.java
│       │       │       │   ├── util/
│       │       │       │   │   ├── ByteConstants.java
│       │       │       │   │   ├── ExceptionWithNoStacktrace.java
│       │       │       │   │   ├── HashCodeUtil.kt
│       │       │       │   │   ├── Hex.kt
│       │       │       │   │   ├── SecureHashUtil.kt
│       │       │       │   │   ├── StreamUtil.java
│       │       │       │   │   ├── TriState.java
│       │       │       │   │   └── UriUtil.java
│       │       │       │   └── webp/
│       │       │       │       ├── BitmapCreator.java
│       │       │       │       ├── WebpBitmapFactory.java
│       │       │       │       └── WebpSupportStatus.java
│       │       │       ├── datasource/
│       │       │       │   ├── AbstractDataSource.java
│       │       │       │   ├── BaseBooleanSubscriber.java
│       │       │       │   ├── BaseDataSubscriber.java
│       │       │       │   ├── DataSource.java
│       │       │       │   ├── DataSources.java
│       │       │       │   ├── DataSubscriber.java
│       │       │       │   ├── FirstAvailableDataSourceSupplier.java
│       │       │       │   ├── IncreasingQualityDataSourceSupplier.java
│       │       │       │   ├── RetainingDataSourceSupplier.java
│       │       │       │   ├── SimpleDataSource.kt
│       │       │       │   ├── SuccessfulVoidDataSource.kt
│       │       │       │   └── package-info.java
│       │       │       ├── memory/
│       │       │       │   └── helper/
│       │       │       │       └── HashCode.kt
│       │       │       └── widget/
│       │       │           └── text/
│       │       │               └── span/
│       │       │                   └── BetterImageSpan.java
│       │       └── pom.xml
│       └── test/
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           ├── common/
│           │           │   ├── callercontext/
│           │           │   │   └── ContextChainTest.kt
│           │           │   ├── executors/
│           │           │   │   ├── HandlerExecutorServiceImplTest.java
│           │           │   │   └── StatefulRunnableTest.java
│           │           │   ├── file/
│           │           │   │   └── FileUtilsTest.java
│           │           │   ├── media/
│           │           │   │   └── MediaUtilsTest.java
│           │           │   ├── references/
│           │           │   │   ├── CloseableReferenceTest.java
│           │           │   │   └── SharedReferenceTest.java
│           │           │   ├── streams/
│           │           │   │   ├── LimitedInputStreamTest.java
│           │           │   │   └── TailAppendingInputStreamTest.java
│           │           │   └── util/
│           │           │       ├── HashCodeUtilTest.java
│           │           │       ├── StreamUtilTest.java
│           │           │       ├── TriStateTest.java
│           │           │       └── UriUtilTest.java
│           │           ├── datasource/
│           │           │   ├── AbstractDataSourceTest.java
│           │           │   ├── DataSourceTestUtils.java
│           │           │   ├── DataSourcesTest.java
│           │           │   ├── FirstAvailableDataSourceSupplierTest.java
│           │           │   └── IncreasingQualityDataSourceSupplierTest.java
│           │           └── widget/
│           │               └── text/
│           │                   └── span/
│           │                       ├── BetterImageSpanMarginTest.java
│           │                       └── BetterImageSpanTest.java
│           └── resources/
│               └── robolectric.properties
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── imagepipeline/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── imagepipeline/
│       │                   ├── bitmaps/
│       │                   │   ├── Api31BitmapFactory.kt
│       │                   │   ├── ArtBitmapFactory.kt
│       │                   │   ├── EmptyJpegGenerator.kt
│       │                   │   ├── HoneycombBitmapCreator.kt
│       │                   │   └── PlatformBitmapFactoryProvider.kt
│       │                   ├── cache/
│       │                   │   ├── BitmapMemoryCacheKey.kt
│       │                   │   ├── BufferedDiskCache.kt
│       │                   │   ├── CacheKeyFactory.kt
│       │                   │   ├── CacheMissException.kt
│       │                   │   ├── DefaultBitmapMemoryCacheParamsSupplier.java
│       │                   │   ├── DefaultCacheKeyFactory.java
│       │                   │   ├── DefaultEncodedMemoryCacheParamsSupplier.java
│       │                   │   ├── EncodedCountingMemoryCacheFactory.java
│       │                   │   ├── EncodedMemoryCacheFactory.java
│       │                   │   ├── ImageCacheStatsTracker.kt
│       │                   │   ├── InstrumentedMemoryCache.java
│       │                   │   ├── InstrumentedMemoryCacheBitmapMemoryCacheFactory.java
│       │                   │   ├── MemoryCacheTracker.kt
│       │                   │   ├── NativeMemoryCacheTrimStrategy.java
│       │                   │   ├── NoOpImageCacheStatsTracker.java
│       │                   │   ├── StagingArea.java
│       │                   │   └── package-info.kt
│       │                   ├── core/
│       │                   │   ├── CloseableReferenceFactory.java
│       │                   │   ├── DiskCachesStore.kt
│       │                   │   ├── DiskCachesStoreFactory.kt
│       │                   │   ├── DiskStorageCacheFactory.java
│       │                   │   ├── DiskStorageFactory.kt
│       │                   │   ├── DownsampleMode.kt
│       │                   │   ├── DynamicDefaultDiskStorageFactory.java
│       │                   │   ├── FileCacheFactory.kt
│       │                   │   ├── ImagePipeline.kt
│       │                   │   ├── ImagePipelineConfig.kt
│       │                   │   ├── ImagePipelineConfigInterface.kt
│       │                   │   ├── ImagePipelineExperiments.kt
│       │                   │   ├── ImagePipelineFactory.java
│       │                   │   ├── ImageTranscoderType.java
│       │                   │   ├── MemoryChunkType.java
│       │                   │   ├── NativeCodeSetup.java
│       │                   │   ├── ProducerFactory.kt
│       │                   │   ├── ProducerSequenceFactory.kt
│       │                   │   └── package-info.kt
│       │                   ├── datasource/
│       │                   │   ├── AbstractProducerToDataSourceAdapter.kt
│       │                   │   ├── BaseBitmapDataSubscriber.kt
│       │                   │   ├── BaseBitmapReferenceDataSubscriber.kt
│       │                   │   ├── BaseListBitmapDataSubscriber.kt
│       │                   │   ├── CloseableProducerToDataSourceAdapter.java
│       │                   │   ├── ListDataSource.java
│       │                   │   ├── ProducerToDataSourceAdapter.kt
│       │                   │   ├── SettableDataSource.kt
│       │                   │   └── package-info.kt
│       │                   ├── debug/
│       │                   │   ├── CloseableReferenceLeakTracker.kt
│       │                   │   └── NoOpCloseableReferenceLeakTracker.kt
│       │                   ├── decoder/
│       │                   │   ├── DecodeException.kt
│       │                   │   ├── DefaultImageDecoder.java
│       │                   │   ├── ImageDecoderConfig.java
│       │                   │   ├── ProgressiveJpegConfig.java
│       │                   │   ├── ProgressiveJpegParser.java
│       │                   │   ├── SimpleProgressiveJpegConfig.java
│       │                   │   └── package-info.kt
│       │                   ├── filter/
│       │                   │   ├── InPlaceRoundFilter.kt
│       │                   │   ├── IterativeBoxBlurFilter.kt
│       │                   │   ├── NTSCDampeningFilterUtil.kt
│       │                   │   ├── RenderScriptBlurFilter.kt
│       │                   │   └── XferRoundFilter.kt
│       │                   ├── listener/
│       │                   │   ├── BaseRequestListener.kt
│       │                   │   ├── BaseRequestListener2.kt
│       │                   │   ├── ForwardingRequestListener.java
│       │                   │   ├── ForwardingRequestListener2.kt
│       │                   │   ├── RequestListener.java
│       │                   │   ├── RequestListener2.java
│       │                   │   ├── RequestLoggingListener.kt
│       │                   │   └── package-info.kt
│       │                   ├── memory/
│       │                   │   ├── BasePool.kt
│       │                   │   ├── BitmapCounter.java
│       │                   │   ├── BitmapCounterConfig.kt
│       │                   │   ├── BitmapCounterProvider.kt
│       │                   │   ├── BitmapPool.kt
│       │                   │   ├── BitmapPoolBackend.kt
│       │                   │   ├── BitmapPoolType.kt
│       │                   │   ├── Bucket.java
│       │                   │   ├── BucketMap.java
│       │                   │   ├── BucketsBitmapPool.kt
│       │                   │   ├── DefaultBitmapPoolParams.kt
│       │                   │   ├── DefaultByteArrayPoolParams.kt
│       │                   │   ├── DefaultFlexByteArrayPoolParams.kt
│       │                   │   ├── DefaultNativeMemoryChunkPoolParams.kt
│       │                   │   ├── DummyBitmapPool.kt
│       │                   │   ├── DummyTrackingInUseBitmapPool.kt
│       │                   │   ├── FlexByteArrayPool.kt
│       │                   │   ├── GenericByteArrayPool.kt
│       │                   │   ├── LruBitmapPool.java
│       │                   │   ├── LruBucketsPoolBackend.java
│       │                   │   ├── MemoryChunk.kt
│       │                   │   ├── MemoryChunkPool.java
│       │                   │   ├── MemoryChunkUtil.kt
│       │                   │   ├── MemoryPooledByteBuffer.kt
│       │                   │   ├── MemoryPooledByteBufferFactory.kt
│       │                   │   ├── MemoryPooledByteBufferOutputStream.kt
│       │                   │   ├── NoOpPoolStatsTracker.java
│       │                   │   ├── OOMSoftReferenceBucket.java
│       │                   │   ├── PoolBackend.kt
│       │                   │   ├── PoolConfig.kt
│       │                   │   ├── PoolFactory.kt
│       │                   │   ├── PoolParams.java
│       │                   │   ├── PoolStatsTracker.kt
│       │                   │   ├── SharedByteArray.java
│       │                   │   └── package-info.kt
│       │                   ├── multiuri/
│       │                   │   └── MultiUri.java
│       │                   ├── platform/
│       │                   │   ├── ArtDecoder.kt
│       │                   │   ├── DefaultDecoder.java
│       │                   │   ├── OreoDecoder.kt
│       │                   │   ├── PlatformDecoder.kt
│       │                   │   ├── PlatformDecoderFactory.kt
│       │                   │   ├── PlatformDecoderOptions.kt
│       │                   │   └── PreverificationHelper.kt
│       │                   ├── postprocessors/
│       │                   │   ├── BlurPostProcessor.kt
│       │                   │   ├── DownScaleBlurPostProcessor.kt
│       │                   │   ├── RoundPostprocessor.kt
│       │                   │   └── TintPostProcessor.kt
│       │                   ├── producers/
│       │                   │   ├── AddImageTransformMetaDataProducer.java
│       │                   │   ├── BaseConsumer.kt
│       │                   │   ├── BaseNetworkFetcher.kt
│       │                   │   ├── BaseProducerContext.java
│       │                   │   ├── BaseProducerContextCallbacks.kt
│       │                   │   ├── BitmapMemoryCacheGetProducer.kt
│       │                   │   ├── BitmapMemoryCacheKeyMultiplexProducer.java
│       │                   │   ├── BitmapMemoryCacheProducer.java
│       │                   │   ├── BitmapPrepareProducer.java
│       │                   │   ├── BitmapProbeProducer.java
│       │                   │   ├── BranchOnSeparateImagesProducer.java
│       │                   │   ├── Consumer.kt
│       │                   │   ├── CustomProducerSequenceFactory.java
│       │                   │   ├── DataFetchProducer.java
│       │                   │   ├── DecodeProducer.kt
│       │                   │   ├── DelayProducer.kt
│       │                   │   ├── DelegatingConsumer.kt
│       │                   │   ├── DiskCacheDecision.kt
│       │                   │   ├── DiskCacheReadProducer.java
│       │                   │   ├── DiskCacheWriteProducer.kt
│       │                   │   ├── EncodedCacheKeyMultiplexProducer.java
│       │                   │   ├── EncodedMemoryCacheProducer.java
│       │                   │   ├── EncodedProbeProducer.java
│       │                   │   ├── ExperimentalThreadHandoffProducerQueueImpl.kt
│       │                   │   ├── FetchState.kt
│       │                   │   ├── HttpUrlConnectionNetworkFetcher.java
│       │                   │   ├── InternalProducerListener.kt
│       │                   │   ├── InternalRequestListener.kt
│       │                   │   ├── JobScheduler.java
│       │                   │   ├── LocalAssetFetchProducer.kt
│       │                   │   ├── LocalContentUriFetchProducer.kt
│       │                   │   ├── LocalContentUriThumbnailFetchProducer.java
│       │                   │   ├── LocalExifThumbnailProducer.java
│       │                   │   ├── LocalFetchProducer.java
│       │                   │   ├── LocalFileFetchProducer.kt
│       │                   │   ├── LocalResourceFetchProducer.kt
│       │                   │   ├── LocalThumbnailBitmapSdk29Producer.java
│       │                   │   ├── LocalVideoThumbnailProducer.java
│       │                   │   ├── MultiplexProducer.java
│       │                   │   ├── NetworkFetchProducer.java
│       │                   │   ├── NetworkFetcher.java
│       │                   │   ├── PartialDiskCacheProducer.java
│       │                   │   ├── PostprocessedBitmapMemoryCacheProducer.java
│       │                   │   ├── PostprocessorProducer.kt
│       │                   │   ├── PriorityStarvingThrottlingProducer.java
│       │                   │   ├── Producer.kt
│       │                   │   ├── ProducerConstants.kt
│       │                   │   ├── ProducerContext.kt
│       │                   │   ├── ProducerContextCallbacks.kt
│       │                   │   ├── ProducerListener.java
│       │                   │   ├── ProducerListener2.java
│       │                   │   ├── QualifiedResourceFetchProducer.kt
│       │                   │   ├── RemoveImageTransformMetaDataProducer.kt
│       │                   │   ├── ResizeAndRotateProducer.java
│       │                   │   ├── SettableProducerContext.java
│       │                   │   ├── StatefulProducerRunnable.kt
│       │                   │   ├── SwallowResultProducer.java
│       │                   │   ├── ThreadHandoffProducer.kt
│       │                   │   ├── ThreadHandoffProducerQueue.java
│       │                   │   ├── ThreadHandoffProducerQueueImpl.kt
│       │                   │   ├── ThrottlingProducer.java
│       │                   │   ├── ThumbnailBranchProducer.java
│       │                   │   ├── ThumbnailProducer.kt
│       │                   │   ├── ThumbnailSizeChecker.kt
│       │                   │   └── package-info.kt
│       │                   ├── request/
│       │                   │   ├── BasePostprocessor.java
│       │                   │   ├── BaseRepeatedPostProcessor.kt
│       │                   │   ├── HasImageRequest.kt
│       │                   │   ├── ImageRequest.java
│       │                   │   ├── ImageRequestBuilder.java
│       │                   │   ├── Postprocessor.java
│       │                   │   ├── RepeatedPostprocessor.kt
│       │                   │   ├── RepeatedPostprocessorRunner.kt
│       │                   │   └── package-info.kt
│       │                   ├── transcoder/
│       │                   │   ├── MultiImageTranscoderFactory.kt
│       │                   │   ├── SimpleImageTranscoder.kt
│       │                   │   └── SimpleImageTranscoderFactory.kt
│       │                   └── xml/
│       │                       ├── XmlDrawableFactory.kt
│       │                       └── XmlFormatDecoder.kt
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       ├── common/
│           │   │       │   └── memory/
│           │   │       │       ├── PooledByteArrayBufferedInputStreamTest.kt
│           │   │       │       ├── PooledByteBufferInputStreamTest.kt
│           │   │       │       └── PooledByteStreamsTest.kt
│           │   │       └── imagepipeline/
│           │   │           ├── cache/
│           │   │           │   ├── BufferedDiskCacheTest.kt
│           │   │           │   └── StagingAreaTest.kt
│           │   │           ├── core/
│           │   │           │   ├── ImagePipelineConfigTest.kt
│           │   │           │   ├── ImagePipelineTest.java
│           │   │           │   └── ProducerSequenceFactoryTest.java
│           │   │           ├── datasource/
│           │   │           │   ├── CloseableProducerToDataSourceAdapterTest.kt
│           │   │           │   ├── ListDataSourceTest.kt
│           │   │           │   └── ProducerToDataSourceAdapterTest.kt
│           │   │           ├── decoder/
│           │   │           │   └── ProgressiveJpegParserTest.kt
│           │   │           ├── filter/
│           │   │           │   ├── InPlaceRoundFilterTest.kt
│           │   │           │   ├── IterativeBoxBlurFilterTest.kt
│           │   │           │   ├── RenderScriptBlurFilterTest.kt
│           │   │           │   └── XferRoundFilterTest.kt
│           │   │           ├── memory/
│           │   │           │   ├── BasePoolTest.kt
│           │   │           │   ├── BitmapCounterTest.kt
│           │   │           │   ├── BitmapPoolTest.java
│           │   │           │   ├── BucketMapTest.kt
│           │   │           │   ├── CloseableReferences.java
│           │   │           │   ├── FlexByteArrayPoolTest.java
│           │   │           │   ├── GenericByteArrayPoolTest.java
│           │   │           │   ├── LruBitmapPoolTest.kt
│           │   │           │   └── SharedByteArrayTest.java
│           │   │           ├── platform/
│           │   │           │   └── ArtDecoderTest.kt
│           │   │           ├── prioritization/
│           │   │           │   └── PriorityTest.kt
│           │   │           ├── producers/
│           │   │           │   ├── AddImageTransformMetaDataProducerTest.java
│           │   │           │   ├── BaseConsumerTest.kt
│           │   │           │   ├── BitmapMemoryCacheGetProducerTest.java
│           │   │           │   ├── BitmapMemoryCacheProducerTest.java
│           │   │           │   ├── BitmapPrepareProducerTest.java
│           │   │           │   ├── BranchOnSeparateImagesProducerTest.java
│           │   │           │   ├── DataFetchProducerTest.kt
│           │   │           │   ├── DecodeProducerTest.java
│           │   │           │   ├── DiskCacheReadProducerTest.java
│           │   │           │   ├── DiskCacheWriteProducerTest.java
│           │   │           │   ├── DownsampleUtilTest.kt
│           │   │           │   ├── EncodedMemoryCacheProducerTest.java
│           │   │           │   ├── HttpUrlConnectionNetworkFetcherTest.kt
│           │   │           │   ├── JobSchedulerTest.kt
│           │   │           │   ├── LocalAssetFetchProducerTest.kt
│           │   │           │   ├── LocalContentUriFetchProducerTest.kt
│           │   │           │   ├── LocalContentUriThumbnailFetchProducerTest.kt
│           │   │           │   ├── LocalExifThumbnailProducerTest.kt
│           │   │           │   ├── LocalFileFetchProducerTest.kt
│           │   │           │   ├── LocalResourceFetchProducerTest.kt
│           │   │           │   ├── LocalVideoThumbnailProducerTest.kt
│           │   │           │   ├── MultiplexProducerTest.java
│           │   │           │   ├── NetworkFetchProducerTest.java
│           │   │           │   ├── NetworkFetcherCallbackTest.java
│           │   │           │   ├── PartialDiskCacheProducerTest.java
│           │   │           │   ├── PostprocessedBitmapMemoryCacheProducerTest.java
│           │   │           │   ├── PriorityStarvingThrottlingProducerTest.java
│           │   │           │   ├── QualifiedResourceFetchProducerTest.kt
│           │   │           │   ├── RemoveImageTransformMetaDataProducerTest.java
│           │   │           │   ├── RepeatedPostprocessorProducerTest.java
│           │   │           │   ├── ResizeAndRotateProducerTest.kt
│           │   │           │   ├── SettableProducerContextTest.kt
│           │   │           │   ├── SingleUsePostprocessorProducerTest.java
│           │   │           │   ├── StatefulProducerRunnableTest.kt
│           │   │           │   ├── SwallowResultProducerTest.java
│           │   │           │   ├── ThreadHandoffProducerTest.kt
│           │   │           │   ├── ThrottlingProducerTest.java
│           │   │           │   ├── ThumbnailBranchProducerTest.java
│           │   │           │   └── ThumbnailSizeCheckerTest.kt
│           │   │           └── request/
│           │   │               ├── ForwardingRequestListenerTest.kt
│           │   │               ├── ImageRequestBuilderCacheEnabledTest.kt
│           │   │               └── ImageRequestTest.kt
│           │   └── org/
│           │       └── mockito/
│           │           └── configuration/
│           │               └── MockitoConfiguration.java
│           └── resources/
│               ├── org/
│               │   └── powermock/
│               │       └── extensions/
│               │           └── configuration.properties
│               └── org.robolectric.Config.properties
├── imagepipeline-backends/
│   ├── imagepipeline-okhttp3/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           └── backends/
│   │                               └── okhttp3/
│   │                                   ├── OkHttpImagePipelineConfigFactory.kt
│   │                                   ├── OkHttpNetworkFetcher.kt
│   │                                   ├── OkHttpNetworkFetcherException.kt
│   │                                   └── package-info.kt
│   └── imagepipeline-volley/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               └── backends/
│                                   └── volley/
│                                       ├── RawRequest.java
│                                       ├── VolleyImagePipelineConfigFactory.java
│                                       └── VolleyNetworkFetcher.java
├── imagepipeline-base/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               ├── binaryresource/
│       │               │   ├── BinaryResource.kt
│       │               │   ├── ByteArrayBinaryResource.kt
│       │               │   └── FileBinaryResource.kt
│       │               ├── cache/
│       │               │   ├── common/
│       │               │   │   ├── BaseCacheEventListener.java
│       │               │   │   ├── CacheErrorLogger.java
│       │               │   │   ├── CacheEvent.java
│       │               │   │   ├── CacheEventListener.java
│       │               │   │   ├── CacheKey.java
│       │               │   │   ├── CacheKeyUtil.kt
│       │               │   │   ├── DebuggingCacheKey.java
│       │               │   │   ├── HasDebugData.kt
│       │               │   │   ├── MultiCacheKey.java
│       │               │   │   ├── NoOpCacheErrorLogger.java
│       │               │   │   ├── NoOpCacheEventListener.java
│       │               │   │   ├── SimpleCacheKey.java
│       │               │   │   ├── WriterCallback.java
│       │               │   │   ├── WriterCallbacks.java
│       │               │   │   └── package-info.java
│       │               │   └── disk/
│       │               │       ├── DefaultDiskStorage.kt
│       │               │       ├── DefaultEntryEvictionComparatorSupplier.java
│       │               │       ├── DiskCacheConfig.java
│       │               │       ├── DiskStorage.java
│       │               │       ├── DiskStorageCache.kt
│       │               │       ├── DynamicDefaultDiskStorage.java
│       │               │       ├── EntryEvictionComparator.java
│       │               │       ├── EntryEvictionComparatorSupplier.java
│       │               │       ├── FileCache.kt
│       │               │       ├── ScoreBasedEvictionComparatorSupplier.java
│       │               │       ├── SettableCacheEvent.java
│       │               │       └── package-info.java
│       │               ├── callercontext/
│       │               │   └── CallerContextVerifier.kt
│       │               ├── drawable/
│       │               │   └── base/
│       │               │       └── DrawableWithCaches.kt
│       │               ├── imageformat/
│       │               │   ├── DefaultImageFormatChecker.kt
│       │               │   ├── DefaultImageFormats.kt
│       │               │   ├── ImageFormat.kt
│       │               │   ├── ImageFormatChecker.kt
│       │               │   └── ImageFormatCheckerUtils.kt
│       │               ├── imagepipeline/
│       │               │   ├── animated/
│       │               │   │   └── factory/
│       │               │   │       ├── AnimatedFactory.kt
│       │               │   │       ├── AnimatedFactoryProvider.kt
│       │               │   │       └── package-info.kt
│       │               │   ├── bitmaps/
│       │               │   │   ├── PlatformBitmapFactory.java
│       │               │   │   ├── SimpleBitmapReleaser.java
│       │               │   │   └── package-info.kt
│       │               │   ├── cache/
│       │               │   │   ├── AbstractAdaptiveCountingMemoryCache.java
│       │               │   │   ├── BitmapMemoryCacheFactory.kt
│       │               │   │   ├── BitmapMemoryCacheTrimStrategy.kt
│       │               │   │   ├── BoundedLinkedHashSet.kt
│       │               │   │   ├── CountingLruBitmapMemoryCacheFactory.java
│       │               │   │   ├── CountingLruMap.java
│       │               │   │   ├── CountingMemoryCache.java
│       │               │   │   ├── CountingMemoryCacheInspector.kt
│       │               │   │   ├── LruCountingMemoryCache.java
│       │               │   │   ├── MemoryCache.kt
│       │               │   │   ├── MemoryCacheParams.kt
│       │               │   │   ├── ValueDescriptor.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── common/
│       │               │   │   ├── BytesRange.kt
│       │               │   │   ├── ImageDecodeOptions.java
│       │               │   │   ├── ImageDecodeOptionsBuilder.java
│       │               │   │   ├── Priority.kt
│       │               │   │   ├── ResizeOptions.kt
│       │               │   │   ├── RotationOptions.kt
│       │               │   │   ├── SourceUriType.kt
│       │               │   │   ├── TooManyBitmapsException.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── core/
│       │               │   │   ├── DefaultExecutorSupplier.kt
│       │               │   │   ├── ExecutorSupplier.kt
│       │               │   │   ├── PriorityThreadFactory.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── decoder/
│       │               │   │   ├── ImageDecoder.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── drawable/
│       │               │   │   ├── DrawableFactory.kt
│       │               │   │   └── package-info.kt
│       │               │   ├── image/
│       │               │   │   ├── BaseCloseableImage.java
│       │               │   │   ├── BaseCloseableStaticBitmap.java
│       │               │   │   ├── CloseableBitmap.java
│       │               │   │   ├── CloseableImage.java
│       │               │   │   ├── CloseableStaticBitmap.java
│       │               │   │   ├── CloseableXml.kt
│       │               │   │   ├── DefaultCloseableImage.java
│       │               │   │   ├── DefaultCloseableStaticBitmap.java
│       │               │   │   ├── DefaultCloseableXml.kt
│       │               │   │   ├── EncodedImage.java
│       │               │   │   ├── HasImageMetadata.java
│       │               │   │   ├── ImageInfo.java
│       │               │   │   ├── ImageInfoImpl.java
│       │               │   │   ├── ImmutableQualityInfo.java
│       │               │   │   ├── QualityInfo.java
│       │               │   │   └── package-info.kt
│       │               │   ├── instrumentation/
│       │               │   │   └── FrescoInstrumenter.kt
│       │               │   ├── nativecode/
│       │               │   │   └── NativeImageTranscoderFactory.kt
│       │               │   ├── network/
│       │               │   │   └── NetworkResponseData.kt
│       │               │   ├── systrace/
│       │               │   │   ├── DefaultFrescoSystrace.kt
│       │               │   │   └── FrescoSystrace.kt
│       │               │   ├── transcoder/
│       │               │   │   ├── DownsampleUtil.kt
│       │               │   │   ├── ImageTranscodeResult.kt
│       │               │   │   ├── ImageTranscoder.kt
│       │               │   │   ├── ImageTranscoderFactory.kt
│       │               │   │   ├── JpegTranscoderUtils.kt
│       │               │   │   └── TranscodeStatus.kt
│       │               │   └── transformation/
│       │               │       ├── BitmapTransformation.kt
│       │               │       ├── CircularTransformation.kt
│       │               │       └── TransformationUtils.kt
│       │               └── imageutils/
│       │                   ├── BitmapUtil.kt
│       │                   ├── HeifExifUtil.kt
│       │                   ├── ImageMetaData.kt
│       │                   ├── JfifUtil.kt
│       │                   ├── StreamProcessor.kt
│       │                   ├── TiffUtil.kt
│       │                   └── WebpUtil.kt
│       └── test/
│           ├── java/
│           │   ├── com/
│           │   │   └── facebook/
│           │   │       ├── cache/
│           │   │       │   ├── common/
│           │   │       │   │   └── CacheEventAssert.kt
│           │   │       │   └── disk/
│           │   │       │       ├── DefaultDiskStorageTest.kt
│           │   │       │       ├── DefaultEntryEvictionComparatorSupplierTest.kt
│           │   │       │       ├── DiskStorageCacheTest.kt
│           │   │       │       ├── DynamicDefaultDiskStorageTest.kt
│           │   │       │       ├── ScoreBasedEvictionComparatorSupplierTest.kt
│           │   │       │       └── SettableCacheEventTest.kt
│           │   │       ├── imageformat/
│           │   │       │   └── ImageFormatCheckerTest.kt
│           │   │       ├── imagepipeline/
│           │   │       │   ├── cache/
│           │   │       │   │   ├── AbstractAdaptiveCountingMemoryCacheTest.kt
│           │   │       │   │   ├── BoundedLinkedHashSetTest.kt
│           │   │       │   │   ├── CountingLruMapTest.kt
│           │   │       │   │   └── LruCountingMemoryCacheTest.kt
│           │   │       │   ├── common/
│           │   │       │   │   ├── BytesRangeTest.kt
│           │   │       │   │   ├── ImageDecodeOptionsTest.kt
│           │   │       │   │   └── ResizeOptionsTest.kt
│           │   │       │   └── image/
│           │   │       │       ├── CloseableBitmapTest.kt
│           │   │       │       ├── CloseableStaticBitmapTest.kt
│           │   │       │       └── EncodedImageTest.kt
│           │   │       └── imageutils/
│           │   │           ├── BitmapUtilTest.kt
│           │   │           ├── JfifTestUtils.kt
│           │   │           ├── JfifTestUtilsTest.kt
│           │   │           ├── JfifUtilTest.kt
│           │   │           └── WebPUtilTest.kt
│           │   └── org/
│           │       └── mockito/
│           │           └── configuration/
│           │               └── MockitoConfiguration.java
│           └── resources/
│               ├── com/
│               │   └── facebook/
│               │       └── imageformat/
│               │           ├── heifs/
│               │           │   └── 1.heif
│               │           └── xmls/
│               │               ├── AndroidManifest.xml
│               │               ├── README.md
│               │               ├── compiled/
│               │               │   ├── layer_list.xml
│               │               │   ├── level_list.xml
│               │               │   ├── state_list.xml
│               │               │   └── vector_drawable.xml
│               │               ├── convert.sh
│               │               └── raw/
│               │                   └── drawable/
│               │                       ├── layer_list.xml
│               │                       ├── level_list.xml
│               │                       ├── state_list.xml
│               │                       └── vector_drawable.xml
│               └── org.robolectric.Config.properties
├── imagepipeline-base-test/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           └── testing/
│                               ├── DeltaQueue.java
│                               ├── FakeClock.java
│                               ├── ScheduledQueue.java
│                               ├── TestExecutorService.java
│                               ├── TestNativeLoader.kt
│                               ├── TestScheduledExecutorService.java
│                               ├── TestScheduledFuture.java
│                               ├── TrivialBufferPooledByteBuffer.java
│                               └── TrivialPooledByteBuffer.java
├── imagepipeline-native/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               └── nativecode/
│           │                   ├── Bitmaps.kt
│           │                   ├── DalvikPurgeableDecoder.kt
│           │                   └── ImagePipelineNativeLoader.kt
│           └── jni/
│               ├── Application.mk
│               ├── bitmaps/
│               │   ├── Android.mk
│               │   ├── Bitmaps.c
│               │   └── Bitmaps.h
│               ├── imagepipeline/
│               │   ├── Android.mk
│               │   ├── exceptions.cpp
│               │   ├── exceptions.h
│               │   ├── init.cpp
│               │   └── logging.h
│               └── memchunk/
│                   ├── Android.mk
│                   ├── NativeMemoryChunk.c
│                   └── NativeMemoryChunk.h
├── imagepipeline-test/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           ├── memory/
│                           │   ├── IntPair.java
│                           │   └── PoolStats.java
│                           └── testing/
│                               └── MockBitmapFactory.kt
├── memory-types/
│   ├── ashmem/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── imagepipeline/
│   │       │                   └── memory/
│   │       │                       ├── AshmemMemoryChunk.java
│   │       │                       └── AshmemMemoryChunkPool.java
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           ├── memory/
│   │                           │   ├── AshmemMemoryChunkPoolTest.kt
│   │                           │   ├── MemoryPooledByteBufferFactoryTest.java
│   │                           │   ├── MemoryPooledByteBufferOutputStreamTest.java
│   │                           │   └── MemoryPooledByteBufferTest.java
│   │                           └── testing/
│   │                               ├── FakeAshmemMemoryChunk.java
│   │                               └── FakeAshmemMemoryChunkPool.java
│   ├── nativememory/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── imagepipeline/
│   │       │                   └── memory/
│   │       │                       ├── NativeMemoryChunk.java
│   │       │                       └── NativeMemoryChunkPool.java
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           ├── memory/
│   │                           │   ├── MemoryPooledByteBufferFactoryTest.java
│   │                           │   ├── MemoryPooledByteBufferOutputStreamTest.java
│   │                           │   ├── MemoryPooledByteBufferTest.java
│   │                           │   ├── NativeMemoryChunkPoolTest.java
│   │                           │   └── TestUsingNativeMemoryChunk.java
│   │                           └── testing/
│   │                               ├── FakeNativeMemoryChunk.java
│   │                               └── FakeNativeMemoryChunkPool.java
│   └── simple/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           ├── main/
│           │   ├── AndroidManifest.xml
│           │   └── java/
│           │       └── com/
│           │           └── facebook/
│           │               └── imagepipeline/
│           │                   └── memory/
│           │                       ├── BufferMemoryChunk.kt
│           │                       └── BufferMemoryChunkPool.kt
│           └── test/
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               ├── memory/
│                               │   ├── BufferMemoryChunkPoolTest.java
│                               │   ├── MemoryPooledByteBufferFactoryTest.java
│                               │   ├── MemoryPooledByteBufferOutputStreamTest.java
│                               │   └── MemoryPooledByteBufferTest.java
│                               └── testing/
│                                   └── FakeBufferMemoryChunkPool.kt
├── middleware/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── middleware/
│                               ├── HasExtraData.kt
│                               └── MiddlewareUtils.kt
├── mockito-config/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── java/
│               └── org/
│                   └── mockito/
│                       └── configuration/
│                           └── MockitoConfiguration.java
├── native-filters/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               ├── nativecode/
│           │               │   ├── NativeBlurFilter.kt
│           │               │   ├── NativeFiltersLoader.kt
│           │               │   └── NativeRoundingFilter.kt
│           │               └── postprocessors/
│           │                   ├── IterativeBoxBlurPostProcessor.kt
│           │                   ├── RoundAsCirclePostprocessor.kt
│           │                   └── RoundedCornersPostprocessor.kt
│           └── jni/
│               ├── Application.mk
│               ├── filters/
│               │   ├── Android.mk
│               │   ├── blur_filter.c
│               │   ├── blur_filter.h
│               │   ├── rounding_filter.c
│               │   └── rounding_filter.h
│               └── native-filters/
│                   ├── Android.mk
│                   ├── exceptions_handling.cpp
│                   ├── exceptions_handling.h
│                   ├── init.cpp
│                   ├── java_globals.h
│                   └── logging.h
├── native-imagetranscoder/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           └── imagepipeline/
│           │               └── nativecode/
│           │                   ├── NativeJpegTranscoder.java
│           │                   ├── NativeJpegTranscoderFactory.java
│           │                   └── NativeJpegTranscoderSoLoader.java
│           └── jni/
│               ├── Application.mk
│               ├── native-imagetranscoder/
│               │   ├── Android.mk
│               │   ├── JpegTranscoder.cpp
│               │   ├── JpegTranscoder.h
│               │   ├── decoded_image.cpp
│               │   ├── decoded_image.h
│               │   ├── exceptions_handler.cpp
│               │   ├── exceptions_handler.h
│               │   ├── init.cpp
│               │   ├── java_globals.h
│               │   ├── jpeg/
│               │   │   ├── jpeg_codec.cpp
│               │   │   ├── jpeg_codec.h
│               │   │   ├── jpeg_error_handler.cpp
│               │   │   ├── jpeg_error_handler.h
│               │   │   ├── jpeg_memory_io.cpp
│               │   │   ├── jpeg_memory_io.h
│               │   │   ├── jpeg_stream_wrappers.cpp
│               │   │   └── jpeg_stream_wrappers.h
│               │   ├── logging.h
│               │   ├── transformations.cpp
│               │   └── transformations.h
│               └── third-party/
│                   └── libjpeg-turbo-2.1.5.1/
│                       ├── Android.mk
│                       ├── config.h
│                       ├── jconfig.h
│                       ├── jconfigint.h
│                       ├── jversion.h
│                       └── neon-compat.h
├── run_comparison.py
├── samples/
│   ├── README.md
│   ├── animation2/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── build.gradle
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── animation2/
│   │           │                   ├── AnimationApplication.java
│   │           │                   ├── MediaControlFragment.java
│   │           │                   ├── SampleData.java
│   │           │                   ├── StandaloneActivity.java
│   │           │                   ├── bitmap/
│   │           │                   │   ├── BitmapAnimationCacheSelectorConfigurator.java
│   │           │                   │   ├── BitmapAnimationDebugFragment.java
│   │           │                   │   ├── BitmapAnimationFragment.java
│   │           │                   │   ├── DebugBitmapAnimationFrameListener.java
│   │           │                   │   ├── ExampleBitmapAnimationFactory.java
│   │           │                   │   └── NaiveCacheAllFramesCachingBackend.java
│   │           │                   ├── color/
│   │           │                   │   ├── ExampleColorBackend.java
│   │           │                   │   └── SimpleColorFragment.java
│   │           │                   ├── local/
│   │           │                   │   └── LocalDrawableAnimationBackend.java
│   │           │                   └── utils/
│   │           │                       ├── AnimationBackendUtils.java
│   │           │                       ├── AnimationControlsManager.java
│   │           │                       └── SampleAnimationBackendConfigurator.java
│   │           └── res/
│   │               ├── drawable/
│   │               │   └── ic_play_pause_24dp.xml
│   │               ├── layout/
│   │               │   ├── activity_standalone.xml
│   │               │   ├── backends.xml
│   │               │   ├── cache_selector.xml
│   │               │   ├── controls.xml
│   │               │   ├── fragment_debug_bitmap.xml
│   │               │   ├── fragment_media_controls.xml
│   │               │   ├── fragment_simple_container.xml
│   │               │   └── frame_info.xml
│   │               ├── values/
│   │               │   ├── colors.xml
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               └── values-w820dp/
│   │                   └── dimens.xml
│   ├── comparison/
│   │   ├── build.gradle
│   │   ├── proguard.pro
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── comparison/
│   │           │                   ├── ComparisonApp.java
│   │           │                   ├── Drawables.java
│   │           │                   ├── MainActivity.kt
│   │           │                   ├── adapters/
│   │           │                   │   ├── AQueryAdapter.java
│   │           │                   │   ├── FrescoAdapter.java
│   │           │                   │   ├── GlideAdapter.java
│   │           │                   │   ├── ImageListAdapter.java
│   │           │                   │   ├── PicassoAdapter.java
│   │           │                   │   ├── UilAdapter.java
│   │           │                   │   └── VolleyAdapter.java
│   │           │                   ├── configs/
│   │           │                   │   ├── ConfigConstants.java
│   │           │                   │   ├── glide/
│   │           │                   │   │   └── SampleGlideModule.java
│   │           │                   │   ├── imagepipeline/
│   │           │                   │   │   └── ImagePipelineConfigFactory.java
│   │           │                   │   ├── picasso/
│   │           │                   │   │   └── SamplePicassoFactory.java
│   │           │                   │   ├── uil/
│   │           │                   │   │   └── SampleUilFactory.java
│   │           │                   │   └── volley/
│   │           │                   │       ├── SampleVolleyFactory.java
│   │           │                   │       └── VolleyMemoryCache.java
│   │           │                   ├── holders/
│   │           │                   │   ├── AQueryHolder.java
│   │           │                   │   ├── BaseViewHolder.java
│   │           │                   │   ├── FrescoHolder.java
│   │           │                   │   ├── GlideHolder.java
│   │           │                   │   ├── PicassoHolder.java
│   │           │                   │   ├── UilHolder.java
│   │           │                   │   ├── VolleyDraweeHolder.java
│   │           │                   │   └── VolleyHolder.java
│   │           │                   ├── instrumentation/
│   │           │                   │   ├── Instrumentation.java
│   │           │                   │   ├── Instrumented.java
│   │           │                   │   ├── InstrumentedDraweeView.java
│   │           │                   │   ├── InstrumentedImageView.java
│   │           │                   │   ├── InstrumentedNetworkImageView.java
│   │           │                   │   └── PerfListener.java
│   │           │                   └── urlsfetcher/
│   │           │                       ├── ImageFormat.java
│   │           │                       ├── ImageSize.java
│   │           │                       ├── ImageUrlsFetcher.java
│   │           │                       ├── ImageUrlsRequest.java
│   │           │                       └── ImageUrlsRequestBuilder.java
│   │           └── res/
│   │               ├── layout/
│   │               │   └── activity_main.xml
│   │               ├── menu/
│   │               │   └── menu_main.xml
│   │               └── values/
│   │                   ├── colors.xml
│   │                   ├── dimens.xml
│   │                   ├── strings.xml
│   │                   └── styles.xml
│   ├── contrib/
│   │   └── com/
│   │       └── facebook/
│   │           └── drawee/
│   │               └── drawable/
│   │                   └── CircleProgressBarDrawable.java
│   ├── gestures/
│   │   ├── build.gradle
│   │   └── src/
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── samples/
│   │       │                   └── gestures/
│   │       │                       ├── MultiPointerGestureDetector.java
│   │       │                       └── TransformGestureDetector.java
│   │       └── test/
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── samples/
│   │           │               └── gestures/
│   │           │                   ├── MotionEventTestUtils.java
│   │           │                   ├── MultiPointerGestureDetectorTest.java
│   │           │                   └── TransformGestureDetectorTest.java
│   │           └── resources/
│   │               └── org.robolectric.Config.properties
│   ├── scrollperf/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-scrollperf.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── facebook/
│   │       │   │           └── samples/
│   │       │   │               └── scrollperf/
│   │       │   │                   └── data/
│   │       │   │                       └── impl/
│   │       │   │                           ├── InfiniteSimpleAdapterTest.java
│   │       │   │                           └── LocalResourceSimpleAdapterTest.java
│   │       │   └── res/
│   │       │       └── values/
│   │       │           ├── colors.xml
│   │       │           └── strings_untranslated.xml
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── facebook/
│   │       │   │           └── samples/
│   │       │   │               └── scrollperf/
│   │       │   │                   ├── MainActivity.java
│   │       │   │                   ├── ScrollPerfApplication.java
│   │       │   │                   ├── conf/
│   │       │   │                   │   ├── Config.java
│   │       │   │                   │   └── Const.java
│   │       │   │                   ├── data/
│   │       │   │                   │   ├── Decorator.java
│   │       │   │                   │   ├── SimpleAdapter.java
│   │       │   │                   │   └── impl/
│   │       │   │                   │       ├── ContentProviderSimpleAdapter.java
│   │       │   │                   │       ├── DistinctUriDecorator.java
│   │       │   │                   │       └── LocalResourceSimpleAdapter.java
│   │       │   │                   ├── fragments/
│   │       │   │                   │   ├── MainFragment.java
│   │       │   │                   │   ├── SettingsFragment.java
│   │       │   │                   │   └── recycler/
│   │       │   │                   │       ├── VitoViewAdapter.java
│   │       │   │                   │       ├── VitoViewHolder.java
│   │       │   │                   │       └── VitoViewListAdapter.java
│   │       │   │                   ├── instrumentation/
│   │       │   │                   │   ├── Instrumentation.java
│   │       │   │                   │   ├── Instrumented.java
│   │       │   │                   │   ├── InstrumentedVitoView.java
│   │       │   │                   │   └── PerfListener.java
│   │       │   │                   ├── internal/
│   │       │   │                   │   └── ScrollPerfExecutorSupplier.java
│   │       │   │                   ├── postprocessor/
│   │       │   │                   │   └── DelayPostprocessor.java
│   │       │   │                   ├── preferences/
│   │       │   │                   │   └── SizePreferences.java
│   │       │   │                   └── util/
│   │       │   │                       ├── PipelineUtil.java
│   │       │   │                       ├── SizeUtil.java
│   │       │   │                       ├── TimeWaster.java
│   │       │   │                       ├── UI.java
│   │       │   │                       └── VitoUtil.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   ├── activity_main.xml
│   │       │       │   ├── content_listview.xml
│   │       │       │   ├── content_recyclerview.xml
│   │       │       │   ├── fragment_main.xml
│   │       │       │   └── size_preference.xml
│   │       │       ├── menu/
│   │       │       │   └── menu.xml
│   │       │       ├── values/
│   │       │       │   ├── array.xml
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   ├── strings_untranslated.xml
│   │       │       │   └── styles.xml
│   │       │       └── xml/
│   │       │           └── preferences.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── samples/
│   │                           └── scrollperf/
│   │                               └── util/
│   │                                   └── TimeWasterTest.java
│   ├── showcase/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-showcase.pro
│   │   ├── proguard-test.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── facebook/
│   │       │               └── fresco/
│   │       │                   └── samples/
│   │       │                       └── showcase/
│   │       │                           └── ShowcaseRunTest.java
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── facebook/
│   │           │           └── fresco/
│   │           │               └── samples/
│   │           │                   └── showcase/
│   │           │                       ├── BaseShowcaseFragment.java
│   │           │                       ├── BaseShowcaseKotlinFragment.kt
│   │           │                       ├── CustomImageFormatConfigurator.java
│   │           │                       ├── ExampleCategory.kt
│   │           │                       ├── ExampleDatabase.kt
│   │           │                       ├── ExampleItem.kt
│   │           │                       ├── ImageOptionsBottomSheet.kt
│   │           │                       ├── LithoSample.kt
│   │           │                       ├── LithoSampleHostFragment.kt
│   │           │                       ├── MainActivity.kt
│   │           │                       ├── ShowcaseApplication.kt
│   │           │                       ├── common/
│   │           │                       │   ├── CustomScaleTypes.java
│   │           │                       │   ├── DimensionUtils.kt
│   │           │                       │   ├── SimpleScaleTypeAdapter.java
│   │           │                       │   └── SpinnerUtils.kt
│   │           │                       ├── imageformat/
│   │           │                       │   ├── color/
│   │           │                       │   │   ├── ColorImageExample.java
│   │           │                       │   │   └── ImageFormatColorFragment.java
│   │           │                       │   ├── datauri/
│   │           │                       │   │   └── ImageFormatDataUriFragment.java
│   │           │                       │   ├── gif/
│   │           │                       │   │   └── ImageFormatGifFragment.java
│   │           │                       │   ├── keyframes/
│   │           │                       │   │   ├── AnimatableKeyframesDrawable.java
│   │           │                       │   │   ├── ImageFormatKeyframesFragment.java
│   │           │                       │   │   └── KeyframesDecoderExample.java
│   │           │                       │   ├── override/
│   │           │                       │   │   └── ImageFormatOverrideExample.java
│   │           │                       │   ├── pjpeg/
│   │           │                       │   │   └── ImageFormatProgressiveJpegFragment.java
│   │           │                       │   ├── svg/
│   │           │                       │   │   ├── ImageFormatSvgFragment.java
│   │           │                       │   │   └── SvgDecoderExample.java
│   │           │                       │   ├── webp/
│   │           │                       │   │   └── ImageFormatWebpFragment.java
│   │           │                       │   └── xml/
│   │           │                       │       └── ImageFormatXmlFragment.java
│   │           │                       ├── imagepipeline/
│   │           │                       │   ├── DurationCallback.java
│   │           │                       │   ├── ImagePipelineBitmapFactoryFragment.java
│   │           │                       │   ├── ImagePipelineDownsampleFragment.java
│   │           │                       │   ├── ImagePipelineNotificationFragment.java
│   │           │                       │   ├── ImagePipelinePostProcessorFragment.java
│   │           │                       │   ├── ImagePipelinePrefetchFragment.java
│   │           │                       │   ├── ImagePipelineQualifiedResourceFragment.java
│   │           │                       │   ├── ImagePipelineRegionDecodingFragment.java
│   │           │                       │   ├── ImagePipelineResizingFragment.java
│   │           │                       │   ├── PartialRequestFragment.java
│   │           │                       │   └── widget/
│   │           │                       │       └── ResizableFrameLayout.java
│   │           │                       ├── misc/
│   │           │                       │   ├── CheckerBoardDrawable.java
│   │           │                       │   ├── DebugImageListener.kt
│   │           │                       │   ├── DebugOverlaySupplierSingleton.java
│   │           │                       │   ├── ImageSourceSpinner.kt
│   │           │                       │   ├── ImageUriProvider.kt
│   │           │                       │   ├── LogcatImagePerfDataListener.java
│   │           │                       │   ├── LogcatRequestListener2.kt
│   │           │                       │   └── WelcomeFragment.java
│   │           │                       ├── permissions/
│   │           │                       │   └── StoragePermissionHelper.kt
│   │           │                       ├── postprocessor/
│   │           │                       │   ├── BasePostprocessorWithDurationCallback.java
│   │           │                       │   ├── BenchmarkPostprocessorForDuplicatedBitmap.java
│   │           │                       │   ├── BenchmarkPostprocessorForDuplicatedBitmapInPlace.java
│   │           │                       │   ├── BenchmarkPostprocessorForManualBitmapHandling.java
│   │           │                       │   ├── CachedWatermarkPostprocessor.java
│   │           │                       │   ├── FasterGreyScalePostprocessor.java
│   │           │                       │   ├── ScalingBlurPostprocessor.java
│   │           │                       │   ├── SlowGreyScalePostprocessor.java
│   │           │                       │   └── WatermarkPostprocessor.java
│   │           │                       ├── settings/
│   │           │                       │   └── SettingsFragment.java
│   │           │                       └── vito/
│   │           │                           ├── FrescoVitoImageDecodeOptions.java
│   │           │                           ├── FrescoVitoImageDecodeOptionsBuilder.java
│   │           │                           ├── FrescoVitoLithoDrawableImageSourceExample.kt
│   │           │                           ├── FrescoVitoLithoGalleryFragment.java
│   │           │                           ├── FrescoVitoLithoImageOptionsConfigFragment.kt
│   │           │                           ├── FrescoVitoLithoListenerExample.kt
│   │           │                           ├── FrescoVitoLithoRegionDecodeFragment.java
│   │           │                           ├── FrescoVitoLithoSectionsFragment.java
│   │           │                           ├── FrescoVitoLithoSimpleExample.kt
│   │           │                           ├── FrescoVitoRegionDecoder.java
│   │           │                           ├── ImageLayersFragment.java
│   │           │                           ├── ImageSourceConfigurator.kt
│   │           │                           ├── LithoSlideshowSample.kt
│   │           │                           ├── MultiUriFragment.kt
│   │           │                           ├── RetainingDataSourceSupplierFragment.java
│   │           │                           ├── SimpleGallerySectionSpec.java
│   │           │                           ├── SimpleListItemSpec.java
│   │           │                           ├── SimpleListSectionSpec.java
│   │           │                           ├── VitoMediaPickerFragment.kt
│   │           │                           ├── VitoRotationFragment.java
│   │           │                           ├── VitoRoundedCornersFragment.java
│   │           │                           ├── VitoScaleTypeFragment.java
│   │           │                           ├── VitoSimpleFragment.java
│   │           │                           ├── VitoSpanFragment.kt
│   │           │                           ├── VitoSpinners.kt
│   │           │                           ├── VitoViewKtxFragment.kt
│   │           │                           ├── VitoViewPrefetchFragment.kt
│   │           │                           ├── VitoViewRecyclerFragment.java
│   │           │                           ├── VitoViewSimpleFragment.java
│   │           │                           ├── ninepatch/
│   │           │                           │   ├── LithoNinePatchSample.kt
│   │           │                           │   └── NinePatchExample.java
│   │           │                           ├── renderer/
│   │           │                           │   ├── RendererColorFilterExampleFragment.kt
│   │           │                           │   ├── RendererExampleDrawable.kt
│   │           │                           │   ├── RendererExampleUtils.kt
│   │           │                           │   ├── RendererFadeExampleFragment.kt
│   │           │                           │   ├── RendererShapeExampleFragment.kt
│   │           │                           │   └── VitoLayerExample.kt
│   │           │                           ├── source/
│   │           │                           │   └── ImageRequestImageSource.kt
│   │           │                           └── transition/
│   │           │                               ├── ImageDetailsActivity.java
│   │           │                               └── VitoTransitionFragment.java
│   │           └── res/
│   │               ├── drawable/
│   │               │   ├── ic_error_black_96dp.xml
│   │               │   ├── ic_retry_black_48dp.xml
│   │               │   ├── ic_settings_black_24dp.xml
│   │               │   ├── resize_outline.xml
│   │               │   ├── side_nav_bar.xml
│   │               │   ├── xml_bitmap.xml
│   │               │   ├── xml_layer_list.xml
│   │               │   ├── xml_level_list.xml
│   │               │   ├── xml_nine_patch.xml
│   │               │   ├── xml_state_list.xml
│   │               │   └── xml_vector.xml
│   │               ├── drawable-anydpi/
│   │               │   ├── ic_arrow_left.xml
│   │               │   ├── ic_arrow_right.xml
│   │               │   └── ic_edit.xml
│   │               ├── layout/
│   │               │   ├── activity_main.xml
│   │               │   ├── activity_vito_transition_detail.xml
│   │               │   ├── app_bar_main.xml
│   │               │   ├── content_main.xml
│   │               │   ├── dialog_fragment_uri_override.xml
│   │               │   ├── fragment_format_color.xml
│   │               │   ├── fragment_format_datauri.xml
│   │               │   ├── fragment_format_gif.xml
│   │               │   ├── fragment_format_keyframes.xml
│   │               │   ├── fragment_format_override.xml
│   │               │   ├── fragment_format_progressive_jpeg.xml
│   │               │   ├── fragment_format_svg.xml
│   │               │   ├── fragment_format_webp.xml
│   │               │   ├── fragment_format_xml.xml
│   │               │   ├── fragment_image_layers.xml
│   │               │   ├── fragment_imagepipeline_bitmap_factory.xml
│   │               │   ├── fragment_imagepipeline_downsample.xml
│   │               │   ├── fragment_imagepipeline_notification.xml
│   │               │   ├── fragment_imagepipeline_postprocessor.xml
│   │               │   ├── fragment_imagepipeline_prefetch.xml
│   │               │   ├── fragment_imagepipeline_qualified_resource.xml
│   │               │   ├── fragment_imagepipeline_region_decoding.xml
│   │               │   ├── fragment_imagepipeline_resizing.xml
│   │               │   ├── fragment_litho_host.xml
│   │               │   ├── fragment_partial_request.xml
│   │               │   ├── fragment_recycler.xml
│   │               │   ├── fragment_scrolling_linear_layout.xml
│   │               │   ├── fragment_vito_image_options_config.xml
│   │               │   ├── fragment_vito_litho_region_decoding.xml
│   │               │   ├── fragment_vito_media_picker.xml
│   │               │   ├── fragment_vito_multi_uri.xml
│   │               │   ├── fragment_vito_retaining_supplier.xml
│   │               │   ├── fragment_vito_rotation.xml
│   │               │   ├── fragment_vito_rounded_corners.xml
│   │               │   ├── fragment_vito_scale_type.xml
│   │               │   ├── fragment_vito_simple.xml
│   │               │   ├── fragment_vito_text_span.xml
│   │               │   ├── fragment_vito_transition.xml
│   │               │   ├── fragment_vito_view_ktx.xml
│   │               │   ├── fragment_vito_view_prefetch.xml
│   │               │   ├── fragment_vito_view_simple.xml
│   │               │   ├── fragment_welcome.xml
│   │               │   ├── nav_header_main.xml
│   │               │   └── vito_recycler_item.xml
│   │               ├── menu/
│   │               │   └── main.xml
│   │               ├── raw/
│   │               │   ├── custom_color1.color
│   │               │   └── custom_color2.color
│   │               ├── values/
│   │               │   ├── colors.xml
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               ├── values-v21/
│   │               │   └── styles.xml
│   │               ├── values-w820dp/
│   │               │   └── dimens.xml
│   │               └── xml/
│   │                   └── preferences.xml
│   ├── zoomable/
│   │   ├── build.gradle
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── samples/
│   │                           └── zoomable/
│   │                               ├── AbstractAnimatedZoomableController.java
│   │                               ├── AnimatedZoomableController.java
│   │                               ├── DefaultZoomableController.java
│   │                               ├── DoubleTapGestureListener.java
│   │                               ├── GestureListenerWrapper.java
│   │                               ├── MultiGestureListener.java
│   │                               ├── MultiZoomableControllerListener.java
│   │                               ├── ZoomableController.java
│   │                               ├── ZoomableDraweeView.java
│   │                               └── ZoomableVitoView.java
│   └── zoomableapp/
│       ├── .gitignore
│       ├── build.gradle
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               ├── java/
│               │   └── com/
│               │       └── facebook/
│               │           └── samples/
│               │               └── zoomableapp/
│               │                   ├── MainActivity.java
│               │                   ├── MyPagerAdapter.java
│               │                   └── ZoomableApplication.java
│               └── res/
│                   ├── layout/
│                   │   ├── activity_main.xml
│                   │   └── zoomable_image.xml
│                   ├── menu/
│                   │   └── menu.xml
│                   └── values/
│                       ├── colors.xml
│                       ├── strings.xml
│                       └── styles.xml
├── settings.gradle
├── soloader/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── imagepipeline/
│                           └── nativecode/
│                               └── NativeCodeInitializer.kt
├── static-webp/
│   ├── .gitignore
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       ├── androidTest/
│       │   └── java/
│       │       └── com/
│       │           └── facebook/
│       │               └── webpsupport/
│       │                   ├── AndroidManifest.xml
│       │                   ├── WebpBitmapFactoryTest.java
│       │                   └── WebpDecodingTest.java
│       └── main/
│           ├── AndroidManifest.xml
│           ├── java/
│           │   └── com/
│           │       └── facebook/
│           │           ├── imagepipeline/
│           │           │   └── nativecode/
│           │           │       └── StaticWebpNativeLoader.kt
│           │           └── webpsupport/
│           │               ├── WebPImageDecoder.java
│           │               └── WebpBitmapFactoryImpl.java
│           └── jni/
│               ├── Application.mk
│               ├── static-webp/
│               │   ├── Android.mk
│               │   ├── decoded_image.cpp
│               │   ├── decoded_image.h
│               │   ├── exceptions.cpp
│               │   ├── exceptions.h
│               │   ├── java_globals.h
│               │   ├── jni_helpers.cpp
│               │   ├── jni_helpers.h
│               │   ├── logging.h
│               │   ├── streams.cpp
│               │   ├── streams.h
│               │   ├── transformations.cpp
│               │   ├── transformations.h
│               │   ├── webp.cpp
│               │   ├── webp.h
│               │   └── webp_bitmapfactory.cpp
│               └── third-party/
│                   ├── libjpeg-turbo-2.1.5.1/
│                   │   ├── Android.mk
│                   │   ├── config.h
│                   │   ├── jconfig.h
│                   │   ├── jconfigint.h
│                   │   ├── jversion.h
│                   │   └── neon-compat.h
│                   ├── libpng-1.6.37/
│                   │   ├── Android.mk
│                   │   └── pnglibconf.h
│                   └── libwebp-1.3.2/
│                       └── Android.mk
├── tools/
│   ├── flipper/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── imagepipeline/
│   │                           └── debug/
│   │                               ├── DebugImageTracker.kt
│   │                               ├── FlipperCacheKeyFactory.kt
│   │                               ├── FlipperCloseableReferenceLeakTracker.kt
│   │                               ├── FlipperImageTracker.kt
│   │                               ├── LruMap.kt
│   │                               └── NoOpDebugImageTracker.kt
│   ├── flipper-fresco-plugin/
│   │   ├── build.gradle
│   │   ├── gradle.properties
│   │   └── src/
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           └── java/
│   │               └── com/
│   │                   └── facebook/
│   │                       └── flipper/
│   │                           └── plugins/
│   │                               └── fresco/
│   │                                   ├── FrescoFlipperDebugPrefHelper.java
│   │                                   ├── FrescoFlipperPlugin.java
│   │                                   ├── FrescoFlipperRequestListener.java
│   │                                   └── objecthelper/
│   │                                       └── FlipperObjectHelper.java
│   └── stetho/
│       ├── build.gradle
│       ├── gradle.properties
│       └── src/
│           └── main/
│               ├── AndroidManifest.xml
│               └── java/
│                   └── com/
│                       └── facebook/
│                           └── imagepipeline/
│                               └── stetho/
│                                   ├── BaseFrescoStethoPlugin.kt
│                                   └── FrescoStethoPlugin.kt
├── ui-common/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── ui/
│                               └── common/
│                                   ├── BaseControllerListener2.kt
│                                   ├── ControllerListener2.kt
│                                   ├── DimensionsInfo.kt
│                                   ├── ForwardingControllerListener2.kt
│                                   ├── ImageLoadStatus.kt
│                                   ├── ImagePerfData.kt
│                                   ├── ImagePerfDataListener.kt
│                                   ├── ImagePerfDataNotifier.kt
│                                   ├── ImagePerfLoggingState.kt
│                                   ├── ImagePerfNotifier.kt
│                                   ├── ImagePerfNotifierHolder.kt
│                                   ├── ImagePerfState.kt
│                                   ├── ImageRenderingInfra.kt
│                                   ├── LegacyOnFadeListener.kt
│                                   ├── MultiUriHelper.kt
│                                   ├── NoOpImagePerfNotifier.kt
│                                   ├── OnDrawControllerListener.kt
│                                   ├── OnFadeListener.kt
│                                   ├── SimpleImagePerfNotifier.kt
│                                   ├── VisibilityAware.kt
│                                   ├── VisibilityState.kt
│                                   └── VitoUtils.kt
├── ui-core/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           └── java/
│               ├── AndroidManifest.xml
│               └── com/
│                   └── facebook/
│                       └── drawee/
│                           └── drawable/
│                               ├── ScalingUtils.java
│                               ├── SizingHint.kt
│                               └── Viewport.kt
├── urimod/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── urimod/
│                               ├── Dimensions.kt
│                               ├── FetchStrategy.kt
│                               ├── NopUriModifier.kt
│                               ├── UriModifier.kt
│                               └── UriModifierInterface.kt
├── viewport/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── facebook/
│                       └── fresco/
│                           └── viewport/
│                               ├── HasTransform.kt
│                               └── ViewportData.kt
└── vito/
    ├── compose/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── compose/
    │                                   └── VitoImage.kt
    ├── core/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       ├── core/
    │       │                       │   ├── AnimatedImagePerfLoggingListener.kt
    │       │                       │   ├── BaseVitoImageRequestListener.kt
    │       │                       │   ├── CombinedImageListener.kt
    │       │                       │   ├── ComposedImagePerfLoggingListener.kt
    │       │                       │   ├── DefaultFrescoVitoConfig.kt
    │       │                       │   ├── FrescoController2.kt
    │       │                       │   ├── FrescoDrawableInterface.kt
    │       │                       │   ├── FrescoVitoConfig.kt
    │       │                       │   ├── FrescoVitoPrefetcher.kt
    │       │                       │   ├── ImagePerfLoggingListener.kt
    │       │                       │   ├── ImagePipelineUtils.kt
    │       │                       │   ├── ListVitoImagePerfListener.kt
    │       │                       │   ├── NopDrawable.kt
    │       │                       │   ├── PrefetchConfig.kt
    │       │                       │   ├── PrefetchReason.kt
    │       │                       │   ├── PrefetchTarget.kt
    │       │                       │   ├── ReleaseStrategy.kt
    │       │                       │   ├── VitoImagePerfListener.kt
    │       │                       │   ├── VitoImagePipeline.kt
    │       │                       │   ├── VitoImageRequest.kt
    │       │                       │   └── VitoImageRequestListener.kt
    │       │                       ├── drawable/
    │       │                       │   ├── ArrayVitoDrawableFactory.kt
    │       │                       │   ├── BitmapDrawableFactory.kt
    │       │                       │   ├── CircularBorderBitmapDrawable.kt
    │       │                       │   └── RoundingUtils.kt
    │       │                       └── listener/
    │       │                           ├── BaseImageListener.kt
    │       │                           ├── ForwardingImageListener.kt
    │       │                           └── ImageListener.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               ├── core/
    │                               │   └── VitoImageRequestTest.kt
    │                               └── drawable/
    │                                   ├── BitmapDrawableFactoryTest.kt
    │                                   └── RoundingUtilsTest.kt
    ├── core-common-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── BaseVitoImagePerfListener.kt
    │                                       ├── CombinedImageListenerImpl.kt
    │                                       └── debug/
    │                                           ├── DebugDataProvider.kt
    │                                           ├── DebugOverlayDrawable.kt
    │                                           ├── DebugOverlayImageOriginColor.kt
    │                                           └── LightweightDebugOverlayDrawable.kt
    ├── core-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── ActualImageHandler.kt
    │                                       ├── BackgroundLayerHandler.kt
    │                                       ├── BorderRenderer.kt
    │                                       ├── DebugDataProvider.kt
    │                                       ├── DebugOverlayHandler.kt
    │                                       ├── DrawableExtensions.kt
    │                                       ├── ExtrasUtils.kt
    │                                       ├── ImageFetchSubscriber.kt
    │                                       ├── ImageLayerDataModel.kt
    │                                       ├── ImageLayerDataModelExtensions.kt
    │                                       ├── ImageReleaseScheduler.kt
    │                                       ├── ImageWithTransformationAndBorderRenderer.kt
    │                                       ├── KFrescoController.kt
    │                                       ├── KFrescoVitoDrawable.kt
    │                                       ├── KImageOptions.kt
    │                                       ├── NopImagePerfListener.kt
    │                                       ├── ProgressLayerHandler.kt
    │                                       ├── PropertyDelegates.kt
    │                                       └── ShapeCalculator.kt
    ├── core-java-impl/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── core/
    │       │                           └── impl/
    │       │                               ├── DefaultImageDecodeOptionsProviderImpl.kt
    │       │                               ├── DrawableDataSubscriber.kt
    │       │                               ├── FrescoController2Impl.kt
    │       │                               ├── FrescoDrawable2.kt
    │       │                               ├── FrescoDrawable2Impl.kt
    │       │                               ├── FrescoVitoPrefetcherImpl.kt
    │       │                               ├── Hierarcher.kt
    │       │                               ├── HierarcherImpl.kt
    │       │                               ├── ImagePipelineUtilsImpl.kt
    │       │                               ├── ImageSourceToImagePipelineAdapter.kt
    │       │                               ├── NoOpFrescoVitoPrefetcher.kt
    │       │                               ├── VitoImagePipelineImpl.kt
    │       │                               ├── debug/
    │       │                               │   ├── BaseDebugOverlayFactory2.kt
    │       │                               │   ├── DebugOverlayFactory2.kt
    │       │                               │   ├── DefaultDebugOverlayFactory2.kt
    │       │                               │   ├── FrescoDrawable2DebugDataProviders.kt
    │       │                               │   ├── LightweightDebugOverlayFactory2.kt
    │       │                               │   └── NoOpDebugOverlayFactory2.kt
    │       │                               └── source/
    │       │                                   ├── DataSourceImageSource.kt
    │       │                                   ├── ImagePipelineImageSource.kt
    │       │                                   └── RetainingImageSource.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── core/
    │                                   └── impl/
    │                                       ├── FrescoDrawable2ImplTest.kt
    │                                       ├── HierarcherImplTest.kt
    │                                       ├── ImagePipelineUtilsImplTest.kt
    │                                       └── VitoImagePipelineImplTest.kt
    ├── drawable-holder/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           └── java/
    │               ├── AndroidManifest.xml
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── drawableholder/
    │                                   └── MultiVitoDrawableHolder.kt
    ├── drawee-support/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── draweesupport/
    │       │                           ├── ControllerListenerWrapper.kt
    │       │                           ├── DrawableFactoryWrapper.kt
    │       │                           ├── RoundingParamsWrapper.kt
    │       │                           └── VitoViewInflater.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── draweesupport/
    │                                   └── ControllerListenerWrapperTest.kt
    ├── init/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── init/
    │                                   └── FrescoVito.kt
    ├── ktx/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── ktx/
    │                                   ├── ImageSourceExtensions.kt
    │                                   └── ViewExtensions.kt
    ├── litho/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── litho/
    │                                   ├── FrescoVitoImage2Spec.kt
    │                                   └── FrescoVitoTapToRetryImageSpec.kt
    ├── litho-slideshow/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── litho/
    │                                   └── slideshow/
    │                                       ├── FrescoVitoSlideshowComponentSpec.kt
    │                                       └── FrescoVitoSlideshowDrawable.kt
    ├── nativecode/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── nativecode/
    │                                   ├── CircularBitmapTransformation.kt
    │                                   └── NativeCircularBitmapRounding.kt
    ├── options/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       ├── main/
    │       │   ├── AndroidManifest.xml
    │       │   └── java/
    │       │       └── com/
    │       │           └── facebook/
    │       │               └── fresco/
    │       │                   └── vito/
    │       │                       └── options/
    │       │                           ├── AnimatedOptions.kt
    │       │                           ├── BitmapConfig.kt
    │       │                           ├── BorderOptions.kt
    │       │                           ├── DecodedImageOptions.kt
    │       │                           ├── EncodedImageOptions.kt
    │       │                           ├── ImageOptions.kt
    │       │                           ├── ImageOptionsDrawableFactory.kt
    │       │                           └── RoundingOptions.kt
    │       └── test/
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── options/
    │                                   └── RoundingOptionsTest.kt
    ├── provider/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── provider/
    │                                   ├── FrescoVitoProvider.kt
    │                                   ├── components/
    │                                   │   └── FrescoVitoComponents.kt
    │                                   ├── impl/
    │                                   │   ├── DefaultFrescoVitoProvider.kt
    │                                   │   ├── NoOpCallerContextVerifier.kt
    │                                   │   └── kotlin/
    │                                   │       └── KFrescoVitoProvider.kt
    │                                   └── setup/
    │                                       └── FrescoVitoSetup.kt
    ├── renderer/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── renderer/
    │                                   ├── CanvasTransformation.kt
    │                                   ├── CanvasTransformationHandler.kt
    │                                   ├── ImageDataModel.kt
    │                                   ├── ImageRenderer.kt
    │                                   ├── Shape.kt
    │                                   └── util/
    │                                       └── ColorUtils.kt
    ├── source/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── source/
    │                                   ├── BitmapImageSource.kt
    │                                   ├── ColorImageSource.kt
    │                                   ├── DrawableImageSource.kt
    │                                   ├── DrawableResImageSource.kt
    │                                   ├── EmptyImageSource.kt
    │                                   ├── FirstAvailableImageSource.kt
    │                                   ├── ImageSource.kt
    │                                   ├── ImageSourceExtras.kt
    │                                   ├── ImageSourceProvider.kt
    │                                   ├── IncreasingQualityImageSource.kt
    │                                   ├── SingleImageSource.kt
    │                                   ├── SingleImageSourceImpl.kt
    │                                   ├── SmartFetchOptIn.kt
    │                                   ├── SmartImageSource.kt
    │                                   └── UriImageSource.kt
    ├── textspan/
    │   ├── build.gradle
    │   ├── gradle.properties
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           └── java/
    │               └── com/
    │                   └── facebook/
    │                       └── fresco/
    │                           └── vito/
    │                               └── textspan/
    │                                   ├── VitoSpan.kt
    │                                   └── VitoSpanLoader.kt
    ├── tools/
    │   └── liveeditor/
    │       ├── build.gradle
    │       ├── gradle.properties
    │       └── src/
    │           └── main/
    │               ├── AndroidManifest.xml
    │               └── java/
    │                   └── com/
    │                       └── facebook/
    │                           └── fresco/
    │                               └── vito/
    │                                   └── tools/
    │                                       └── liveeditor/
    │                                           ├── ImageLiveEditor.kt
    │                                           ├── ImageOptionsSampleValues.kt
    │                                           ├── ImageSelector.kt
    │                                           ├── ImageSourceParser.kt
    │                                           ├── ImageSourceSampleValues.kt
    │                                           ├── ImageSourceSyntaxException.kt
    │                                           ├── ImageSourceUiUtil.kt
    │                                           ├── ImageTracker.kt
    │                                           ├── LiveEditorOnScreenButtonController.kt
    │                                           └── LiveEditorUiUtils.kt
    └── view/
        ├── build.gradle
        ├── gradle.properties
        └── src/
            └── main/
                ├── AndroidManifest.xml
                └── java/
                    └── com/
                        └── facebook/
                            └── fresco/
                                └── vito/
                                    └── view/
                                        ├── ImageViewWithAspectRatio.kt
                                        ├── VitoView.kt
                                        ├── impl/
                                        │   └── VitoViewImpl2.kt
                                        └── transition/
                                            └── VitoTransition.kt
Download .txt
SYMBOL INDEX (553 symbols across 36 files)

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableBackend.java
  type AnimatedDrawableBackend (line 21) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method getAnimatedImageResult (line 29) | AnimatedImageResult getAnimatedImageResult();
    method getDurationMs (line 36) | int getDurationMs();
    method getFrameCount (line 43) | int getFrameCount();
    method getLoopCount (line 50) | int getLoopCount();
    method getWidth (line 57) | int getWidth();
    method getHeight (line 64) | int getHeight();
    method getRenderedWidth (line 72) | int getRenderedWidth();
    method getRenderedHeight (line 80) | int getRenderedHeight();
    method getFrameInfo (line 88) | AnimatedDrawableFrameInfo getFrameInfo(int frameNumber);
    method renderFrame (line 96) | void renderFrame(int frameNumber, Canvas canvas);
    method renderDeltas (line 106) | void renderDeltas(int frameNumber, Canvas canvas);
    method getFrameForTimestampMs (line 115) | int getFrameForTimestampMs(int timestampMs);
    method getTimestampMsForFrame (line 123) | int getTimestampMsForFrame(int frameNumber);
    method getDurationMsForFrame (line 131) | int getDurationMsForFrame(int frameNumber);
    method getFrameForPreview (line 138) | int getFrameForPreview();
    method forNewBounds (line 147) | AnimatedDrawableBackend forNewBounds(@Nullable Rect bounds);
    method getMemoryUsage (line 154) | int getMemoryUsage();
    method getPreDecodedFrame (line 164) | @Nullable
    method hasPreDecodedFrame (line 174) | boolean hasPreDecodedFrame(int frameNumber);
    method dropCaches (line 177) | void dropCaches();

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableFrameInfo.java
  class AnimatedDrawableFrameInfo (line 13) | @Nullsafe(Nullsafe.Mode.LOCAL)
    type DisposalMethod (line 17) | public enum DisposalMethod {
    type BlendOperation (line 33) | public enum BlendOperation {
    method AnimatedDrawableFrameInfo (line 48) | public AnimatedDrawableFrameInfo(

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptions.java
  class AnimatedDrawableOptions (line 14) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method AnimatedDrawableOptions (line 37) | public AnimatedDrawableOptions(AnimatedDrawableOptionsBuilder builder) {
    method newBuilder (line 49) | public static AnimatedDrawableOptionsBuilder newBuilder() {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptionsBuilder.java
  class AnimatedDrawableOptionsBuilder (line 13) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method getForceKeepAllFramesInMemory (line 26) | public boolean getForceKeepAllFramesInMemory() {
    method setForceKeepAllFramesInMemory (line 36) | public AnimatedDrawableOptionsBuilder setForceKeepAllFramesInMemory(
    method getAllowPrefetching (line 47) | public boolean getAllowPrefetching() {
    method setAllowPrefetching (line 57) | public AnimatedDrawableOptionsBuilder setAllowPrefetching(boolean allo...
    method getMaximumBytes (line 68) | public int getMaximumBytes() {
    method setMaximumBytes (line 79) | public AnimatedDrawableOptionsBuilder setMaximumBytes(int maximumBytes) {
    method getEnableDebugging (line 89) | public boolean getEnableDebugging() {
    method setEnableDebugging (line 99) | public AnimatedDrawableOptionsBuilder setEnableDebugging(boolean enabl...
    method build (line 109) | public AnimatedDrawableOptions build() {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImage.java
  type AnimatedImage (line 15) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method dispose (line 26) | void dispose();
    method getWidth (line 33) | int getWidth();
    method getHeight (line 40) | int getHeight();
    method getFrameCount (line 47) | int getFrameCount();
    method getDuration (line 54) | int getDuration();
    method getFrameDurations (line 62) | int[] getFrameDurations();
    method getLoopCount (line 69) | int getLoopCount();
    method getFrame (line 77) | AnimatedImageFrame getFrame(int frameNumber);
    method doesRenderSupportScaling (line 85) | boolean doesRenderSupportScaling();
    method getSizeInBytes (line 93) | int getSizeInBytes();
    method getFrameInfo (line 101) | AnimatedDrawableFrameInfo getFrameInfo(int frameNumber);
    method getAnimatedBitmapConfig (line 108) | @Nullable

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageFrame.java
  type AnimatedImageFrame (line 14) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method dispose (line 23) | void dispose();
    method renderFrame (line 33) | void renderFrame(int width, int height, Bitmap bitmap);
    method getDurationMs (line 40) | int getDurationMs();
    method getWidth (line 47) | int getWidth();
    method getHeight (line 54) | int getHeight();
    method getXOffset (line 61) | int getXOffset();
    method getYOffset (line 68) | int getYOffset();

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResult.java
  class AnimatedImageResult (line 22) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method AnimatedImageResult (line 32) | AnimatedImageResult(AnimatedImageResultBuilder builder) {
    method AnimatedImageResult (line 41) | private AnimatedImageResult(AnimatedImage image) {
    method forAnimatedImage (line 52) | public static AnimatedImageResult forAnimatedImage(AnimatedImage image) {
    method newBuilder (line 62) | public static AnimatedImageResultBuilder newBuilder(AnimatedImage imag...
    method getImage (line 71) | public AnimatedImage getImage() {
    method getSource (line 80) | @Nullable
    method getFrameForPreview (line 91) | public int getFrameForPreview() {
    method getDecodedFrame (line 103) | public synchronized @Nullable CloseableReference<Bitmap> getDecodedFra...
    method hasDecodedFrame (line 117) | public synchronized boolean hasDecodedFrame(int index) {
    method getBitmapTransformation (line 126) | public @Nullable BitmapTransformation getBitmapTransformation() {
    method getPreviewBitmap (line 137) | @Nullable
    method dispose (line 143) | public synchronized void dispose() {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResultBuilder.java
  class AnimatedImageResultBuilder (line 18) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method AnimatedImageResultBuilder (line 28) | AnimatedImageResultBuilder(AnimatedImage image) {
    method getImage (line 37) | public AnimatedImage getImage() {
    method getPreviewBitmap (line 47) | public @Nullable CloseableReference<Bitmap> getPreviewBitmap() {
    method setPreviewBitmap (line 57) | public AnimatedImageResultBuilder setPreviewBitmap(
    method getFrameForPreview (line 69) | public int getFrameForPreview() {
    method setFrameForPreview (line 79) | public AnimatedImageResultBuilder setFrameForPreview(int frameForPrevi...
    method getDecodedFrames (line 91) | public @Nullable List<CloseableReference<Bitmap>> getDecodedFrames() {
    method getSource (line 98) | @Nullable
    method setDecodedFrames (line 109) | public AnimatedImageResultBuilder setDecodedFrames(
    method getBitmapTransformation (line 120) | @Nullable
    method setBitmapTransformation (line 130) | public AnimatedImageResultBuilder setBitmapTransformation(
    method setSource (line 142) | public AnimatedImageResultBuilder setSource(@Nullable String source) {
    method build (line 154) | public AnimatedImageResult build() {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendImpl.java
  class AnimatedDrawableBackendImpl (line 32) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method AnimatedDrawableBackendImpl (line 52) | public AnimatedDrawableBackendImpl(
    method getBoundsToUse (line 74) | private static Rect getBoundsToUse(AnimatedImage image, @Nullable Rect...
    method getAnimatedImageResult (line 85) | @Override
    method getDurationMs (line 90) | @Override
    method getFrameCount (line 95) | @Override
    method getLoopCount (line 100) | @Override
    method getWidth (line 105) | @Override
    method getHeight (line 110) | @Override
    method getRenderedWidth (line 115) | @Override
    method getRenderedHeight (line 120) | @Override
    method getFrameInfo (line 125) | @Override
    method getFrameForTimestampMs (line 130) | @Override
    method getTimestampMsForFrame (line 135) | @Override
    method getDurationMsForFrame (line 141) | @Override
    method getFrameForPreview (line 146) | @Override
    method forNewBounds (line 151) | @Override
    method getMemoryUsage (line 162) | @Override
    method getPreDecodedFrame (line 172) | @Override
    method hasPreDecodedFrame (line 177) | @Override
    method renderFrame (line 182) | @Override
    method renderDeltas (line 200) | @Override
    method prepareTempBitmapForThisSize (line 222) | private synchronized Bitmap prepareTempBitmapForThisSize(int width, in...
    method renderImageSupportsScaling (line 236) | private void renderImageSupportsScaling(Canvas canvas, AnimatedImageFr...
    method renderScalingFrames (line 263) | private void renderScalingFrames(
    method maybeDisposeBackground (line 329) | private void maybeDisposeBackground(
    method renderImageDoesNotSupportScaling (line 346) | private void renderImageDoesNotSupportScaling(Canvas canvas, AnimatedI...
    method renderNonScalingFrames (line 378) | private void renderNonScalingFrames(
    method dropCaches (line 419) | @Override
    method clearTempBitmap (line 424) | private synchronized void clearTempBitmap() {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendProvider.java
  type AnimatedDrawableBackendProvider (line 17) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method get (line 27) | AnimatedDrawableBackend get(AnimatedImageResult animatedImageResult, @...

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedFrameCache.java
  class AnimatedFrameCache (line 28) | @Nullsafe(Nullsafe.Mode.LOCAL)
    class FrameKey (line 31) | @VisibleForTesting
      method FrameKey (line 37) | public FrameKey(CacheKey imageCacheKey, int frameIndex) {
      method toString (line 42) | @Override
      method equals (line 50) | @Override
      method hashCode (line 63) | @Override
      method containsUri (line 68) | @Override
      method getUriString (line 73) | @Override
      method isResourceIdForDebugging (line 79) | @Override
    method AnimatedFrameCache (line 92) | public AnimatedFrameCache(
    method onReusabilityChange (line 106) | public synchronized void onReusabilityChange(CacheKey key, boolean isR...
    method cache (line 122) | @Nullable
    method get (line 133) | @Nullable
    method contains (line 139) | public boolean contains(int frameIndex) {
    method getForReuse (line 152) | @Nullable
    method popFirstFreeItemKey (line 166) | @Nullable
    method keyFor (line 177) | private FrameKey keyFor(int frameIndex) {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedImageCompositor.java
  class AnimatedImageCompositor (line 34) | @Nullsafe(Nullsafe.Mode.LOCAL)
    type Callback (line 38) | public interface Callback {
      method onIntermediateResult (line 49) | void onIntermediateResult(int frameNumber, Bitmap bitmap);
      method getCachedBitmap (line 60) | @Nullable
    method AnimatedImageCompositor (line 69) | public AnimatedImageCompositor(
    method renderDeltas (line 82) | public void renderDeltas(int frameNumber, Bitmap baseBitmap) {
    method renderFrame (line 93) | public void renderFrame(int frameNumber, Bitmap bitmap) {
    type FrameNeededResult (line 140) | private enum FrameNeededResult {
    method prepareCanvasWithClosestCachedFrame (line 164) | private int prepareCanvasWithClosestCachedFrame(int previousFrameNumbe...
    method disposeToBackground (line 203) | private void disposeToBackground(Canvas canvas, AnimatedDrawableFrameI...
    method isFrameNeededForRendering (line 219) | private FrameNeededResult isFrameNeededForRendering(int index) {
    method isKeyFrame (line 242) | private boolean isKeyFrame(int index) {
    method isFullFrame (line 255) | private boolean isFullFrame(AnimatedDrawableFrameInfo frameInfo) {
    method maybeApplyTransformation (line 262) | private void maybeApplyTransformation(Bitmap bitmap) {

FILE: animated-base/src/main/java/com/facebook/imagepipeline/image/CloseableAnimatedImage.java
  class CloseableAnimatedImage (line 19) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method CloseableAnimatedImage (line 26) | public CloseableAnimatedImage(AnimatedImageResult imageResult) {
    method CloseableAnimatedImage (line 30) | public CloseableAnimatedImage(AnimatedImageResult imageResult, boolean...
    method getWidth (line 35) | @Override
    method getHeight (line 40) | @Override
    method close (line 45) | @Override
    method isClosed (line 58) | @Override
    method getSizeInBytes (line 63) | @Override
    method isStateful (line 68) | @Override
    method getImageResult (line 73) | public synchronized @Nullable AnimatedImageResult getImageResult() {
    method getImage (line 77) | public synchronized @Nullable AnimatedImage getImage() {

FILE: animated-base/src/test/java/android/net/http/AndroidHttpClient.java
  class AndroidHttpClient (line 10) | public class AndroidHttpClient {}

FILE: animated-base/src/test/java/com/facebook/imagepipeline/animated/testing/TestAnimatedDrawableBackend.java
  class TestAnimatedDrawableBackend (line 21) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method TestAnimatedDrawableBackend (line 31) | public TestAnimatedDrawableBackend(int width, int height, int[] frameD...
    method pixelValue (line 43) | public static int pixelValue(int frameNumber, int x, int y) {
    method getAnimatedImageResult (line 47) | @Nullable
    method getDurationMs (line 54) | @Override
    method getFrameCount (line 59) | @Override
    method getLoopCount (line 64) | @Override
    method getWidth (line 69) | @Override
    method getHeight (line 74) | @Override
    method getRenderedWidth (line 79) | @Override
    method getRenderedHeight (line 84) | @Override
    method getFrameInfo (line 89) | @Override
    method renderFrame (line 101) | @Override
    method renderDeltas (line 114) | @Override
    method getFrameForTimestampMs (line 119) | @Override
    method getTimestampMsForFrame (line 131) | @Override
    method getDurationMsForFrame (line 136) | @Override
    method getFrameForPreview (line 141) | @Override
    method forNewBounds (line 146) | @Override
    method getMemoryUsage (line 151) | @Override
    method getPreDecodedFrame (line 156) | @Nullable
    method hasPreDecodedFrame (line 162) | @Override
    method getDropCachesCallCount (line 167) | public int getDropCachesCallCount() {
    method dropCaches (line 171) | @Override

FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackend.java
  type AnimationBackend (line 18) | public interface AnimationBackend extends AnimationInformation {
    type Listener (line 20) | interface Listener {
      method onAnimationLoaded (line 23) | void onAnimationLoaded();
    method drawFrame (line 42) | boolean drawFrame(Drawable parent, Canvas canvas, int frameNumber);
    method setAlpha (line 50) | void setAlpha(@IntRange(from = 0, to = 255) int alpha);
    method setColorFilter (line 58) | void setColorFilter(@Nullable ColorFilter colorFilter);
    method setBounds (line 70) | void setBounds(Rect bounds);
    method getIntrinsicWidth (line 81) | int getIntrinsicWidth();
    method getIntrinsicHeight (line 92) | int getIntrinsicHeight();
    method getSizeInBytes (line 99) | int getSizeInBytes();
    method clear (line 105) | void clear();
    method preloadAnimation (line 108) | void preloadAnimation();
    method setAnimationListener (line 111) | void setAnimationListener(@Nullable Listener listener);

FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackendDelegateWithInactivityCheck.java
  class AnimationBackendDelegateWithInactivityCheck (line 29) | @Nullsafe(Nullsafe.Mode.LOCAL)
    type InactivityListener (line 33) | public interface InactivityListener {
      method onInactive (line 39) | void onInactive();
    method createForBackend (line 42) | public static <
    method createForBackend (line 52) | public static <T extends AnimationBackend> AnimationBackendDelegate<T>...
    method run (line 78) | @Override
    method AnimationBackendDelegateWithInactivityCheck (line 93) | private AnimationBackendDelegateWithInactivityCheck(
    method drawFrame (line 104) | @Override
    method setInactivityListener (line 112) | public void setInactivityListener(@Nullable InactivityListener inactiv...
    method getInactivityCheckPollingTimeMs (line 116) | public long getInactivityCheckPollingTimeMs() {
    method setInactivityCheckPollingTimeMs (line 120) | public void setInactivityCheckPollingTimeMs(long inactivityCheckPollin...
    method getInactivityThresholdMs (line 124) | public long getInactivityThresholdMs() {
    method setInactivityThresholdMs (line 128) | public void setInactivityThresholdMs(long inactivityThresholdMs) {
    method isInactive (line 132) | private boolean isInactive() {
    method maybeScheduleInactivityCheck (line 136) | private synchronized void maybeScheduleInactivityCheck() {

FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationInformation.java
  type AnimationInformation (line 13) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method getFrameCount (line 27) | int getFrameCount();
    method getFrameDurationMs (line 35) | int getFrameDurationMs(int frameNumber);
    method getLoopDurationMs (line 42) | int getLoopDurationMs();
    method width (line 47) | int width();
    method height (line 52) | int height();
    method getLoopCount (line 59) | int getLoopCount();

FILE: animated-drawable/src/main/java/com/facebook/fresco/animation/frame/FrameScheduler.java
  type FrameScheduler (line 13) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method getFrameNumberToRender (line 28) | int getFrameNumberToRender(long animationTimeMs, long lastFrameTimeMs);
    method getLoopDurationMs (line 35) | long getLoopDurationMs();
    method getTargetRenderTimeMs (line 43) | long getTargetRenderTimeMs(int frameNumber);
    method getTargetRenderTimeForNextFrameMs (line 53) | long getTargetRenderTimeForNextFrameMs(long animationTimeMs);
    method isInfiniteAnimation (line 58) | boolean isInfiniteAnimation();

FILE: animated-drawable/src/test/java/javax/microedition/khronos/opengles/GL.java
  type GL (line 11) | public interface GL {}

FILE: animated-gif-lite/src/main/java/com/facebook/animated/giflite/GifDecoder.java
  class GifDecoder (line 31) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method decode (line 34) | @Override
    method translateFrameDisposal (line 91) | private static AnimatedDrawableFrameInfo.DisposalMethod translateFrame...

FILE: animated-gif-lite/src/main/java/com/facebook/animated/giflite/decoder/GifMetadataDecoder.java
  class GifMetadataDecoder (line 21) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method create (line 42) | public static GifMetadataDecoder create(InputStream is, @Nullable Outp...
    method GifMetadataDecoder (line 53) | private GifMetadataDecoder(InputStream is, @Nullable OutputStream os) {
    method decode (line 58) | public void decode() throws IOException {
    method getScreenWidth (line 66) | public int getScreenWidth() {
    method getScreenHeight (line 73) | public int getScreenHeight() {
    method getFrameCount (line 80) | public int getFrameCount() {
    method getLoopCount (line 87) | public int getLoopCount() {
    method getFrameDisposal (line 94) | public int getFrameDisposal(int frameNumber) {
    method getFrameDurationMs (line 101) | public int getFrameDurationMs(int frameNumber) {
    method readGifInfo (line 115) | private void readGifInfo() throws IOException {
    method addFrame (line 160) | private void addFrame(int[] control) {
    method validateAndIgnoreHeader (line 164) | private void validateAndIgnoreHeader() throws IOException {
    method ignoreColorTable (line 191) | private void ignoreColorTable(int numColors) throws IOException {
    method readBlock (line 195) | private int readBlock() throws IOException {
    method skipExtension (line 206) | private void skipExtension() throws IOException {
    method skipImage (line 213) | private void skipImage() throws IOException {
    method isNetscape (line 226) | private boolean isNetscape() {
    method readNetscapeExtension (line 239) | private void readNetscapeExtension() throws IOException {
    method readGraphicsControlExtension (line 249) | private void readGraphicsControlExtension(int[] control) throws IOExce...
    method readNextByte (line 262) | private int readNextByte() throws IOException {
    method readTwoByteInt (line 271) | private int readTwoByteInt() throws IOException {
    method readIntoBlock (line 275) | private int readIntoBlock(int offset, int length) throws IOException {
    method readAndWriteNextByte (line 287) | private int readAndWriteNextByte() throws IOException {
    method writeNextByte (line 293) | private void writeNextByte(int b) throws IOException {
    method writeTwoByteInt (line 300) | private void writeTwoByteInt(int content) throws IOException {
    method skipAndWriteBytes (line 305) | private void skipAndWriteBytes(int length) throws IOException {
    method initFixedOutputStream (line 315) | private void initFixedOutputStream() throws IOException {
    method copyFromIsToOs (line 325) | private void copyFromIsToOs(InputStream in, OutputStream out, int leng...

FILE: animated-gif/src/main/java/com/facebook/animated/gif/GifFrame.java
  class GifFrame (line 17) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method GifFrame (line 31) | @DoNotStrip
    method finalize (line 37) | @Override
    method dispose (line 42) | @Override
    method renderFrame (line 47) | @Override
    method getDurationMs (line 52) | @Override
    method getWidth (line 57) | @Override
    method getHeight (line 62) | @Override
    method getXOffset (line 67) | @Override
    method getYOffset (line 72) | @Override
    method hasTransparency (line 77) | public boolean hasTransparency() {
    method getTransparentPixelColor (line 81) | public int getTransparentPixelColor() {
    method getDisposalMode (line 85) | public int getDisposalMode() {
    method nativeRenderFrame (line 89) | @DoNotStrip
    method nativeGetDurationMs (line 92) | @DoNotStrip
    method nativeGetWidth (line 95) | @DoNotStrip
    method nativeGetHeight (line 98) | @DoNotStrip
    method nativeGetXOffset (line 101) | @DoNotStrip
    method nativeGetYOffset (line 104) | @DoNotStrip
    method nativeGetDisposalMode (line 107) | @DoNotStrip
    method nativeGetTransparentPixelColor (line 110) | @DoNotStrip
    method nativeHasTransparency (line 113) | @DoNotStrip
    method nativeDispose (line 116) | @DoNotStrip
    method nativeFinalize (line 119) | @DoNotStrip

FILE: animated-gif/src/main/java/com/facebook/animated/gif/GifImage.java
  class GifImage (line 28) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method ensure (line 45) | private static synchronized void ensure() {
    method createFromByteArray (line 58) | public static GifImage createFromByteArray(byte[] source) {
    method createFromByteBuffer (line 74) | public static GifImage createFromByteBuffer(ByteBuffer byteBuffer) {
    method createFromByteBuffer (line 84) | public static GifImage createFromByteBuffer(ByteBuffer byteBuffer, Ima...
    method createFromNativeMemory (line 95) | public static GifImage createFromNativeMemory(
    method createFromFileDescriptor (line 112) | public static GifImage createFromFileDescriptor(int fileDescriptor, Im...
    method decodeFromNativeMemory (line 119) | @Override
    method decodeFromByteBuffer (line 125) | @Override
    method GifImage (line 130) | @DoNotStrip
    method GifImage (line 138) | @DoNotStrip
    method finalize (line 144) | @Override
    method dispose (line 149) | @Override
    method getWidth (line 154) | @Override
    method getHeight (line 159) | @Override
    method getFrameCount (line 164) | @Override
    method getDuration (line 169) | @Override
    method getFrameDurations (line 174) | @Override
    method getLoopCount (line 179) | @Override
    method getFrame (line 197) | @Override
    method doesRenderSupportScaling (line 202) | @Override
    method getSizeInBytes (line 207) | @Override
    method isAnimated (line 212) | public boolean isAnimated() {
    method getFrameInfo (line 216) | @Override
    method getAnimatedBitmapConfig (line 233) | @Override
    method fromGifDisposalMethod (line 239) | private static AnimatedDrawableFrameInfo.DisposalMethod fromGifDisposa...
    method nativeCreateFromDirectByteBuffer (line 253) | @DoNotStrip
    method nativeCreateFromNativeMemory (line 257) | @DoNotStrip
    method nativeCreateFromFileDescriptor (line 261) | @DoNotStrip
    method nativeGetWidth (line 265) | @DoNotStrip
    method nativeGetHeight (line 268) | @DoNotStrip
    method nativeGetDuration (line 271) | @DoNotStrip
    method nativeGetFrameCount (line 274) | @DoNotStrip
    method nativeGetFrameDurations (line 277) | @DoNotStrip
    method nativeGetLoopCount (line 280) | @DoNotStrip
    method nativeGetFrame (line 283) | @DoNotStrip
    method nativeGetSizeInBytes (line 286) | @DoNotStrip
    method nativeIsAnimated (line 289) | @DoNotStrip
    method nativeDispose (line 292) | @DoNotStrip
    method nativeFinalize (line 295) | @DoNotStrip

FILE: animated-gif/src/main/jni/gifimage/OnLoad.cpp
  function jint (line 19) | __attribute__((visibility("default"))) jint

FILE: animated-gif/src/main/jni/gifimage/gif.cpp
  function DGifCloseFile2 (line 46) | static void DGifCloseFile2(GifFileType* pGifFile) {
  class DataWrapper (line 51) | class DataWrapper {
    method DataWrapper (line 53) | DataWrapper() {}
  class BytesDataWrapper (line 66) | class BytesDataWrapper : public DataWrapper {
    method BytesDataWrapper (line 68) | BytesDataWrapper(std::vector<uint8_t>&& pBuffer)
    method rangeAdd (line 73) | inline static size_t rangeAdd(size_t current, size_t increment, size_t...
    method read (line 84) | size_t read(GifByteType* dest, size_t size) override {
    method getBufferSize (line 96) | size_t getBufferSize() override {
    method getPosition (line 100) | size_t getPosition() override {
    method setPosition (line 104) | bool setPosition(size_t position) override {
  class FileDataWrapper (line 119) | class FileDataWrapper : public DataWrapper {
    method FileDataWrapper (line 121) | static FileDataWrapper* create(JNIEnv* pEnv, int fd) {
    method FileDataWrapper (line 148) | FileDataWrapper(FILE* file, size_t length)
    method read (line 155) | size_t read(GifByteType* dest, size_t size) override {
    method getBufferSize (line 159) | size_t getBufferSize() override {
    method getPosition (line 163) | size_t getPosition() override {
    method setPosition (line 168) | bool setPosition(size_t position) override {
  class GifWrapper (line 177) | class GifWrapper {
    method GifWrapper (line 179) | GifWrapper(
    method GifFileType (line 190) | GifFileType* get() {
    method DataWrapper (line 194) | DataWrapper* getData() {
    method addFrameByteOffset (line 198) | void addFrameByteOffset(size_t offset) {
    method getFrameByteOffset (line 202) | size_t getFrameByteOffset(int frameNum) {
    method getFrameSize (line 206) | size_t getFrameSize() {
    method getLoopCount (line 210) | int getLoopCount() {
    method getRasterBitsCapacity (line 218) | size_t getRasterBitsCapacity() {
    method resizeRasterBuffer (line 222) | void resizeRasterBuffer(size_t bufferSize) {
    method setLoopCount (line 230) | void setLoopCount(int pLoopCount) {
    method isAnimated (line 234) | bool isAnimated() {
    method setAnimated (line 238) | void setAnimated(bool animated) {
    method RWLock (line 242) | RWLock* getSavedImagesRWLock() {
  type GifImageNativeContext (line 260) | struct GifImageNativeContext {
  type GifFrameNativeContext (line 296) | struct GifFrameNativeContext {
  function directByteBufferReadFun (line 338) | static int directByteBufferReadFun(
  type PixelType32 (line 352) | struct PixelType32 {
  function ColorMapObject (line 383) | static ColorMapObject* genDefColorMap(void) {
  function getGraphicsControlBlockForImage (line 400) | bool getGraphicsControlBlockForImage(
  function readSingleFrame (line 437) | int readSingleFrame(
  function decodeExtension (line 544) | int decodeExtension(GifFileType* pGifFile) {
  function parseApplicationExtensions (line 592) | void parseApplicationExtensions(
  function modifiedDGifSlurp (line 640) | int modifiedDGifSlurp(
  function jobject (line 717) | jobject createFromDataWrapper(
  function jobject (line 808) | jobject GifImage_nativeCreateFromByteVector(
  function GifImageNativeContext_releaseRef (line 823) | void GifImageNativeContext_releaseRef(
  type GifImageNativeContextReleaser (line 838) | struct GifImageNativeContextReleaser {
    method GifImageNativeContextReleaser (line 842) | GifImageNativeContextReleaser(JNIEnv* pEnv, jobject gifImage)
  function getGifImageNativeContext (line 856) | std::unique_ptr<GifImageNativeContext, GifImageNativeContextReleaser>
  function jobject (line 884) | jobject GifImage_nativeCreateFromDirectByteBuffer(
  function jobject (line 916) | jobject GifImage_nativeCreateFromNativeMemory(
  function jobject (line 945) | jobject GifImage_nativeCreateFromFileDescriptor(
  function jint (line 966) | jint GifImage_nativeGetWidth(JNIEnv* pEnv, jobject thiz) {
  function jint (line 980) | jint GifImage_nativeGetHeight(JNIEnv* pEnv, jobject thiz) {
  function jint (line 994) | jint GifImage_nativeGetFrameCount(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1008) | jint GifImage_nativeGetDuration(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1022) | jint GifImage_nativeGetLoopCount(JNIEnv* pEnv, jobject thiz) {
  function jintArray (line 1037) | jintArray GifImage_nativeGetFrameDurations(JNIEnv* pEnv, jobject thiz) {
  function jobject (line 1064) | jobject GifImage_nativeGetFrame(JNIEnv* pEnv, jobject thiz, jint index) {
  function GifFrameNativeContext_releaseRef (line 1121) | void GifFrameNativeContext_releaseRef(
  type GifFrameNativeContextReleaser (line 1136) | struct GifFrameNativeContextReleaser {
    method GifFrameNativeContextReleaser (line 1140) | GifFrameNativeContextReleaser(JNIEnv* pEnv, jobject gifFrame)
  function getGifFrameNativeContext (line 1154) | std::unique_ptr<GifFrameNativeContext, GifFrameNativeContextReleaser>
  function jint (line 1178) | jint GifImage_nativeGetSizeInBytes(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1199) | jint GifImage_nativeIsAnimated(JNIEnv* pEnv, jobject thiz) {
  function GifImage_nativeDispose (line 1212) | void GifImage_nativeDispose(JNIEnv* pEnv, jobject thiz) {
  function GifImage_nativeFinalize (line 1227) | void GifImage_nativeFinalize(JNIEnv* pEnv, jobject thiz) {
  function PixelType32 (line 1238) | static PixelType32 packARGB32(
  function PixelType32 (line 1258) | static PixelType32 getColorFromTable(
  function blitLine (line 1280) | static void blitLine(
  function blitNormal (line 1305) | static void blitNormal(
  function GifFrame_nativeRenderFrame (line 1342) | void GifFrame_nativeRenderFrame(
  function jint (line 1443) | jint GifFrame_nativeGetDurationMs(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1459) | jint GifFrame_nativeGetTransparentPixelColor(JNIEnv* pEnv, jobject thiz) {
  function jboolean (line 1503) | jboolean GifFrame_nativeHasTransparency(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1517) | jint GifFrame_nativeGetWidth(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1531) | jint GifFrame_nativeGetHeight(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1545) | jint GifFrame_nativeGetXOffset(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1559) | jint GifFrame_nativeGetYOffset(JNIEnv* pEnv, jobject thiz) {
  function jint (line 1573) | jint GifFrame_nativeGetDisposalMode(JNIEnv* pEnv, jobject thiz) {
  function GifFrame_nativeDispose (line 1585) | void GifFrame_nativeDispose(JNIEnv* pEnv, jobject thiz) {
  function GifFrame_nativeFinalize (line 1600) | void GifFrame_nativeFinalize(JNIEnv* pEnv, jobject thiz) {
  function initGifImage (line 1651) | int initGifImage(JNIEnv* pEnv) {

FILE: animated-gif/src/main/jni/gifimage/jni_helpers.cpp
  type facebook (line 14) | namespace facebook {
    function jint (line 25) | jint throwException(
    function jint (line 44) | jint throwNoClassDefError(JNIEnv* pEnv, const char* szFmt, ...) {
    function jint (line 61) | jint throwRuntimeException(JNIEnv* pEnv, const char* szFmt, ...) {
    function jint (line 77) | jint throwIllegalArgumentException(JNIEnv* pEnv, const char* szFmt, .....
    function jint (line 94) | jint throwIllegalStateException(JNIEnv* pEnv, const char* szFmt, ...) {
    function jint (line 111) | jint throwOutOfMemoryError(JNIEnv* pEnv, const char* szFmt, ...) {
    function jint (line 127) | jint throwAssertionError(JNIEnv* pEnv, const char* szFmt, ...) {
    function jint (line 143) | jint throwIOException(JNIEnv* pEnv, const char* szFmt, ...) {
    function jclass (line 161) | jclass findClassOrThrow(JNIEnv* pEnv, const char* szClassName) {
    function jfieldID (line 180) | jfieldID getFieldIdOrThrow(
    function jmethodID (line 199) | jmethodID getMethodIdOrThrow(

FILE: animated-gif/src/main/jni/gifimage/jni_helpers.h
  function namespace (line 14) | namespace facebook {

FILE: animated-gif/src/main/jni/gifimage/locks.h
  function class (line 14) | class RWLock {
  function class (line 45) | class ReaderLock {
  function class (line 73) | class WriterLock {

FILE: animated-gif/src/main/jni/gifimage/secure_memcpy.h
  function try_checked_memcpy (line 28) | __attribute__((warn_unused_result)) inline int try_checked_memcpy(

FILE: animated-webp/src/main/java/com/facebook/animated/webp/WebPFrame.java
  class WebPFrame (line 17) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method WebPFrame (line 31) | @DoNotStrip
    method finalize (line 37) | @Override
    method dispose (line 42) | @Override
    method renderFrame (line 47) | @Override
    method getDurationMs (line 52) | @Override
    method getWidth (line 57) | @Override
    method getHeight (line 62) | @Override
    method getXOffset (line 67) | @Override
    method getYOffset (line 72) | @Override
    method shouldDisposeToBackgroundColor (line 77) | public boolean shouldDisposeToBackgroundColor() {
    method isBlendWithPreviousFrame (line 81) | public boolean isBlendWithPreviousFrame() {
    method nativeRenderFrame (line 85) | private native void nativeRenderFrame(int width, int height, Bitmap bi...
    method nativeGetDurationMs (line 87) | private native int nativeGetDurationMs();
    method nativeGetWidth (line 89) | private native int nativeGetWidth();
    method nativeGetHeight (line 91) | private native int nativeGetHeight();
    method nativeGetXOffset (line 93) | private native int nativeGetXOffset();
    method nativeGetYOffset (line 95) | private native int nativeGetYOffset();
    method nativeShouldDisposeToBackgroundColor (line 97) | private native boolean nativeShouldDisposeToBackgroundColor();
    method nativeIsBlendWithPreviousFrame (line 99) | private native boolean nativeIsBlendWithPreviousFrame();
    method nativeDispose (line 101) | private native void nativeDispose();
    method nativeFinalize (line 103) | private native void nativeFinalize();

FILE: animated-webp/src/main/java/com/facebook/animated/webp/WebPImage.java
  class WebPImage (line 30) | @Nullsafe(Nullsafe.Mode.LOCAL)
    method WebPImage (line 42) | @DoNotStrip
    method WebPImage (line 50) | @DoNotStrip
    method finalize (line 56) | @Override
    method dispose (line 61) | @Override
    method createFromByteArray (line 72) | public static WebPImage createFromByteArray(byte[] source, @Nullable I...
    method createFromByteBuffer (line 93) | public static WebPImage createFromByteBuffer(
    method createFromNativeMemory (line 105) | public static WebPImage createFromNativeMemory(
    method decodeFromNativeMemory (line 116) | @Override
    method decodeFromByteBuffer (line 122) | @Override
    method getWidth (line 127) | @Override
    method getHeight (line 132) | @Override
    method getFrameCount (line 137) | @Override
    method getDuration (line 142) | @Override
    method getFrameDurations (line 147) | @Override
    method getLoopCount (line 152) | @Override
    method getFrame (line 157) | @Override
    method getSizeInBytes (line 162) | @Override
    method doesRenderSupportScaling (line 167) | @Override
    method getFrameInfo (line 172) | @Override
    method getAnimatedBitmapConfig (line 193) | @Override
    method nativeCreateFromDirectByteBuffer (line 199) | private static native WebPImage nativeCreateFromDirectByteBuffer(ByteB...
    method nativeCreateFromNativeMemory (line 201) | private static native WebPImage nativeCreateFromNativeMemory(long nati...
    method nativeGetWidth (line 203) | private native int nativeGetWidth();
    method nativeGetHeight (line 205) | private native int nativeGetHeight();
    method nativeGetDuration (line 207) | private native int nativeGetDuration();
    method nativeGetFrameCount (line 209) | private native int nativeGetFrameCount();
    method nativeGetFrameDurations (line 211) | private native int[] nativeGetFrameDurations();
    method nativeGetLoopCount (line 213) | private native int nativeGetLoopCount();
    method nativeGetFrame (line 215) | private native WebPFrame nativeGetFrame(int frameNumber);
    method nativeGetSizeInBytes (line 217) | private native int nativeGetSizeInBytes();
    method nativeDispose (line 219) | private native void nativeDispose();
    method nativeFinalize (line 221) | private native void nativeFinalize();

FILE: docs/javadoc/assets/doclava-developer-docs.js
  function addLoadEvent (line 17) | function addLoadEvent(newfun) {
  function mobileSetup (line 49) | function mobileSetup() {
  function setToRoot (line 72) | function setToRoot(root, assets) {
  function restoreWidth (line 78) | function restoreWidth(navWidth) {
  function restoreHeight (line 92) | function restoreHeight(packageHeight) {
  function readCookie (line 105) | function readCookie(cookie) {
  function writeCookie (line 122) | function writeCookie(cookie, val, section, expiration) {
  function getSection (line 133) | function getSection() {
  function init (line 145) | function init() {
  function highlightNav (line 179) | function highlightNav(fullPageName) {
  function resizePackagesHeight (line 235) | function resizePackagesHeight() {
  function resizeHeight (line 250) | function resizeHeight() {
  function resizeWidth (line 283) | function resizeWidth() {
  function resizeAll (line 309) | function resizeAll() {
  function getBaseUri (line 314) | function getBaseUri(uri) {
  function requestAppendHL (line 327) | function requestAppendHL(uri) {
  function loadLast (line 340) | function loadLast(cookiePath) {
  function toggle (line 364) | function toggle(obj, slide) {
  function buildToggleLists (line 384) | function buildToggleLists() {
  function getNavPref (line 392) | function getNavPref() {
  function chooseDefaultNav (line 400) | function chooseDefaultNav() {
  function swapNav (line 410) | function swapNav() {
  function scrollIntoView (line 433) | function scrollIntoView(nav) {
  function changeTabLang (line 450) | function changeTabLang(lang) {
  function changeNavLang (line 464) | function changeNavLang(lang) {
  function changeDocLang (line 478) | function changeDocLang(lang) {
  function changeLangPref (line 483) | function changeLangPref(lang, refresh) {
  function loadLangPref (line 495) | function loadLangPref() {
  function getLangPref (line 502) | function getLangPref() {
  function toggleContent (line 511) | function toggleContent(obj) {

FILE: docs/javadoc/assets/doclava-developer-reference.js
  function toggleApiLevelSelector (line 5) | function toggleApiLevelSelector(checkbox) {
  function buildApiLevelSelector (line 21) | function buildApiLevelSelector() {
  function changeApiLevel (line 45) | function changeApiLevel() {
  function showApiWarning (line 65) | function showApiWarning(thing, selectedLevelIndex, minLevelIndex) {
  function toggleVisisbleApis (line 77) | function toggleVisisbleApis(selectedLevelIndex, context) {
  function apiKeyToIndex (line 95) | function apiKeyToIndex(key) {
  function getSelectedLevelIndex (line 104) | function getSelectedLevelIndex() {
  function new_node (line 110) | function new_node(me, mom, text, link, children_data, api_level)
  function expand_node (line 187) | function expand_node(me, node)
  function get_node (line 206) | function get_node(me, mom)
  function this_page_relative (line 216) | function this_page_relative(toroot)
  function find_page (line 243) | function find_page(url, data)
  function load_navtree_data (line 262) | function load_navtree_data() {
  function init_default_navtree (line 269) | function init_default_navtree(toroot) {
  function init_navtree (line 277) | function init_navtree(navtree_id, toroot, root_nodes)
  function toggleInherited (line 317) | function toggleInherited(linkObj, expand) {
  function toggleAllInherited (line 344) | function toggleAllInherited(linkObj, expand) {
  function toggleAllClassInherited (line 364) | function toggleAllClassInherited() {
  function ensureAllInheritedExpanded (line 382) | function ensureAllInheritedExpanded() {

FILE: docs/javadoc/assets/prettify.js
  function Ld (line 11) | function Ld(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb).rep...
  function ga (line 11) | function ga(a){return a.replace(Ja,pb).replace(Ka,qb).replace(La,rb)}
  function Sd (line 12) | function Sd(a){var b=a.indexOf(G);if(b<0)return a;for(--b;(b=a.indexOf(t...
  function Ma (line 12) | function Ma(a){return yb===a.tagName}
  function W (line 12) | function W(a,b){switch(a.nodeType){case 1:var c=
  function Na (line 13) | function Na(a){for(var b=0,c=z,d=z,g=0,i=a.length;g<i;++g){var m=a[g];if...
  function Td (line 18) | function Td(a){if(r===ha){var b=document.createElement(gc);b.appendChild...
  function Ud (line 18) | function Ud(a){var b=0;return function(c){for(var d=r,g=0,i=0,m=c.length...
  function Zd (line 19) | function Zd(a){var b=a.match(Vd),c=[],d=0,g=[];if(b)for(var i=0,m=b.leng...
  function $d (line 20) | function $d(a){return!!a.replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*...
  function ia (line 20) | function ia(a,b,c,d){if(b){var g={source:b,b:a};c(g);d.push.apply(d,g.c)}}
  function K (line 20) | function K(a,b){var c={},d;(function(){for(var m=a.concat(b),
  function C (line 22) | function C(a){var b=[],c=[];if(a.tripleQuotedStrings)b.push([U,/^(?:\'\'...
  function be (line 24) | function be(a){var b=a.source,c=a.f,d=a.c,
  function y (line 26) | function y(a,b){for(var c=b.length;--c>=0;){var d=b[c];if(X.hasOwnProper...
  function Ra (line 26) | function Ra(a,b){a&&X.hasOwnProperty(a)||(a=/^\s*</.test(b)?Kc:Lc);retur...
  function Sa (line 29) | function Sa(a){var b=a.e,c=a.d;a.a=b;try{var d=Zd(b),g=d.source;a.source...
  function ce (line 29) | function ce(a,b){var c={e:a,d:b};Sa(c);return c.a}
  function de (line 29) | function de(a){for(var b=window._pr_isIE6(),c=[document.getElementsByTag...

FILE: docs/javadoc/assets/search_autocomplete.js
  function set_row_selected (line 10) | function set_row_selected(row, selected)
  function set_row_values (line 23) | function set_row_values(toroot, row, match)
  function sync_selection_table (line 31) | function sync_selection_table(toroot)
  function search_changed (line 105) | function search_changed(e, kd, toroot)
  function rank_autocomplete_results (line 167) | function rank_autocomplete_results(query) {
  function highlight_autocomplete_result_labels (line 237) | function highlight_autocomplete_result_labels(query) {
  function search_focus_changed (line 252) | function search_focus_changed(obj, focused)
  function submit_search (line 268) | function submit_search() {
Copy disabled (too large) Download .json
Condensed preview — 2570 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (16,775K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 781,
    "preview": "We use GitHub Issues for bugs.\n\nIf you have a non-bug question, please ask on Stack Overflow: http://stackoverflow.com/q"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 1230,
    "preview": "Thanks for submitting a PR! Please read these instructions carefully:\n\n- [ ] Explain the **motivation** for making this "
  },
  {
    "path": ".github/stale.yml",
    "chars": 1131,
    "preview": "# Configuration for probot-stale - https://github.com/probot/stale\n# Number of days of inactivity before an issue become"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 1195,
    "preview": "name: facebook/fresco/build\non:\n  push:\n    branches:\n    - main\n  pull_request:\n    branches:\n    - main\njobs:\n  build:"
  },
  {
    "path": ".github/workflows/gradle-wrapper-validation.yml",
    "chars": 224,
    "preview": "name: \"Validate Gradle Wrapper\"\non: [push, pull_request]\n\njobs:\n  validation:\n    name: \"Validation\"\n    runs-on: ubuntu"
  },
  {
    "path": ".github/workflows/release.yml",
    "chars": 1618,
    "preview": "name: Publish\n\non:\n  push:\n    tags:\n      - v*\n  workflow_dispatch:\n    inputs:\n      tag:\n        description: \"Tag to"
  },
  {
    "path": ".gitignore",
    "chars": 207,
    "preview": ".gradle\n.DS_Store\n.idea\nbuild/\nlocal.properties\nlocalhost/\nobj/\n*.iml\nGemfile.lock\n_site/\n\n# Kotlin 2.0\n# https://kotlin"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3356,
    "preview": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2882,
    "preview": "# Contributing to Fresco\n\nWe want to make contributing to this project as easy and transparent as\npossible.\n\n## Security"
  },
  {
    "path": "LICENSE",
    "chars": 1088,
    "preview": "MIT License\n\nCopyright (c) Meta Platforms, Inc. and affiliates.\n\nPermission is hereby granted, free of charge, to any pe"
  },
  {
    "path": "README.md",
    "chars": 2399,
    "preview": "# Fresco\n\n<img alt=\"Fresco Logo\" align=\"right\" src=\"docs/static/sample-images/fresco_logo.svg\" width=\"15%\" />\n\n[![Build "
  },
  {
    "path": "animated-base/.gitignore",
    "chars": 12,
    "preview": "nativedeps/\n"
  },
  {
    "path": "animated-base/build.gradle",
    "chars": 2191,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/gradle.properties",
    "chars": 122,
    "preview": "POM_NAME=AnimatedBase\nPOM_DESCRIPTION=Base classes for animation support\nPOM_ARTIFACT_ID=animated-base\nPOM_PACKAGING=aar"
  },
  {
    "path": "animated-base/src/main/AndroidManifest.xml",
    "chars": 180,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    pack"
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/bitmap/cache/AnimationFrameCacheKey.kt",
    "chars": 1287,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/bitmap/cache/FrescoFrameCache.kt",
    "chars": 8014,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendAnimationInformation.kt",
    "chars": 1073,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendFrameRenderer.kt",
    "chars": 2729,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/drawable/animator/AnimatedDrawableValueAnimatorHelper.kt",
    "chars": 2460,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/factory/AnimatedFactoryV2Impl.kt",
    "chars": 5283,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/fresco/animation/factory/DefaultBitmapAnimationDrawableFactory.kt",
    "chars": 11609,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableBackend.java",
    "chars": 5158,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableFrameInfo.java",
    "chars": 1668,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptions.java",
    "chars": 1766,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedDrawableOptionsBuilder.java",
    "chars": 3385,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImage.java",
    "chars": 2917,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageFrame.java",
    "chars": 1892,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResult.java",
    "chars": 4803,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageResultBuilder.java",
    "chars": 5011,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/AnimatedImageValidator.kt",
    "chars": 596,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/base/package-info.java",
    "chars": 307,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageDecoder.kt",
    "chars": 1156,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageDecoderBase.kt",
    "chars": 7523,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/factory/AnimatedImageFactory.kt",
    "chars": 1469,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendImpl.java",
    "chars": 15429,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendProvider.java",
    "chars": 963,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedFrameCache.java",
    "chars": 5410,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/AnimatedImageCompositor.java",
    "chars": 10907,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/impl/package-info.java",
    "chars": 311,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/util/AnimatedDrawableUtil.kt",
    "chars": 4013,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/animated/util/package-info.kt",
    "chars": 291,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/image/CloseableAnimatedImage.java",
    "chars": 2064,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/main/java/com/facebook/imagepipeline/image/package-info.java",
    "chars": 321,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/android/net/http/AndroidHttpClient.java",
    "chars": 252,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/fresco/animation/bitmap/cache/FrescoFrameCacheTest.kt",
    "chars": 5497,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendAnimationInformationTest.kt",
    "chars": 2321,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/fresco/animation/bitmap/wrapper/AnimatedDrawableBackendFrameRendererTest.kt",
    "chars": 3632,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/animated/impl/AnimatedDrawableBackendImplTest.kt",
    "chars": 3601,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/animated/impl/AnimatedFrameCacheTest.kt",
    "chars": 5518,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/animated/testing/TestAnimatedDrawableBackend.java",
    "chars": 4489,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/animated/util/AnimatedDrawableUtilTest.kt",
    "chars": 3841,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/producers/AnimatedRepeatedPostprocessorProducerTest.kt",
    "chars": 9608,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-base/src/test/java/com/facebook/imagepipeline/producers/AnimatedSingleUsePostprocessorProducerTest.kt",
    "chars": 5697,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/.gitignore",
    "chars": 19,
    "preview": "/build\nnativedeps/\n"
  },
  {
    "path": "animated-drawable/README.md",
    "chars": 196,
    "preview": "# Experimental Implementation for Animated Images\n\nThis is an experimental new animation implementation that is still wo"
  },
  {
    "path": "animated-drawable/build.gradle",
    "chars": 2193,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/gradle.properties",
    "chars": 159,
    "preview": "POM_NAME=AnimatedDrawable\nPOM_DESCRIPTION=Animated drawable that renders GIFs, WebPs and other Animations\nPOM_ARTIFACT_I"
  },
  {
    "path": "animated-drawable/src/main/AndroidManifest.xml",
    "chars": 175,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    pack"
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackend.java",
    "chars": 3451,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackendDelegate.kt",
    "chars": 3916,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationBackendDelegateWithInactivityCheck.java",
    "chars": 5154,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/backend/AnimationInformation.java",
    "chars": 1355,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/BitmapAnimationBackend.kt",
    "chars": 20996,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/BitmapFrameCache.kt",
    "chars": 5041,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/BitmapFrameRenderer.kt",
    "chars": 1340,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/cache/KeepLastFrameCache.kt",
    "chars": 3371,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/cache/NoOpCache.kt",
    "chars": 1558,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/BitmapFramePreparationStrategy.kt",
    "chars": 1921,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/BitmapFramePreparer.kt",
    "chars": 990,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/DefaultBitmapFramePreparer.kt",
    "chars": 5974,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/FixedNumberBitmapFramePreparationStrategy.kt",
    "chars": 1438,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/FrameLoaderStrategy.kt",
    "chars": 4582,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/loadframe/AnimationLoaderExecutor.kt",
    "chars": 681,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/loadframe/FpsCompressorInfo.kt",
    "chars": 3953,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/AnimationBitmapFrame.kt",
    "chars": 678,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/AnimationCoordinator.kt",
    "chars": 4866,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/AnimationLoaderFactory.kt",
    "chars": 2374,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/BufferFrameLoader.kt",
    "chars": 10507,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/CircularList.kt",
    "chars": 834,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/bitmap/preparation/ondemandanimation/FrameLoader.kt",
    "chars": 2517,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/AnimatedDrawable2.kt",
    "chars": 16168,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/AnimatedDrawable2DebugDrawListener.kt",
    "chars": 2617,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/AnimationFrameScheduler.kt",
    "chars": 3307,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/AnimationListener.kt",
    "chars": 1656,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/BaseAnimationListener.kt",
    "chars": 892,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/KAnimatedDrawable2.kt",
    "chars": 7393,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/drawable/animator/AnimatedDrawable2ValueAnimatorHelper.kt",
    "chars": 2005,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/frame/DropFramesFrameScheduler.kt",
    "chars": 3438,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/main/java/com/facebook/fresco/animation/frame/FrameScheduler.java",
    "chars": 1849,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/backend/AnimationBackendDelegateTest.kt",
    "chars": 4494,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/backend/AnimationBackendDelegateWithInactivityCheckTest.kt",
    "chars": 2136,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/bitmap/BitmapAnimationBackendTest.kt",
    "chars": 44440,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/bitmap/preparation/DefaultBitmapFramePreparerTest.kt",
    "chars": 8473,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/bitmap/preparation/FixedNumberBitmapFramePreparationStrategyTest.kt",
    "chars": 4512,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/com/facebook/fresco/animation/frame/DropFramesFrameSchedulerTest.kt",
    "chars": 7182,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-drawable/src/test/java/javax/microedition/khronos/opengles/GL.java",
    "chars": 312,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/.gitignore",
    "chars": 12,
    "preview": "nativedeps/\n"
  },
  {
    "path": "animated-gif/build.gradle",
    "chars": 2341,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/gradle.properties",
    "chars": 121,
    "preview": "POM_NAME=AnimatedGif\nPOM_DESCRIPTION=The classes to support animated gif\nPOM_ARTIFACT_ID=animated-gif\nPOM_PACKAGING=aar\n"
  },
  {
    "path": "animated-gif/src/main/AndroidManifest.xml",
    "chars": 170,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    pack"
  },
  {
    "path": "animated-gif/src/main/java/com/facebook/animated/gif/AnimatedImageGifValidator.kt",
    "chars": 1566,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/java/com/facebook/animated/gif/GifFrame.java",
    "chars": 2592,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/java/com/facebook/animated/gif/GifImage.java",
    "chars": 8746,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/java/com/facebook/animated/gif/GifImageDecoder.kt",
    "chars": 2547,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/Application.mk",
    "chars": 990,
    "preview": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n#\n# This source code is licensed under the MIT license found in the"
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/Android.mk",
    "chars": 705,
    "preview": "# Copyright (c) Meta Platforms, Inc. and affiliates.\n#\n# This source code is licensed under the MIT license found in the"
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/OnLoad.cpp",
    "chars": 716,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/gif.cpp",
    "chars": 50674,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/jni_helpers.cpp",
    "chars": 5929,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/jni_helpers.h",
    "chars": 4316,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/locks.h",
    "chars": 2013,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/gifimage/secure_memcpy.h",
    "chars": 1299,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif/src/main/jni/third-party/giflib/Android.mk",
    "chars": 256,
    "preview": "LOCAL_PATH := $(call my-dir)\n\ninclude $(CLEAR_VARS)\nLOCAL_CFLAGS    := -DHAVE_CONFIG_H\nLOCAL_MODULE    := gif\nLOCAL_SRC_"
  },
  {
    "path": "animated-gif/src/test/java/com/facebook/animated/gif/GifImageDecoderTest.kt",
    "chars": 18173,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/.gitignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "animated-gif-lite/build.gradle",
    "chars": 1015,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/gradle.properties",
    "chars": 141,
    "preview": "POM_NAME=AnimatedGifLite\nPOM_DESCRIPTION=The classes to support animated gif without ndk\nPOM_ARTIFACT_ID=animated-gif-li"
  },
  {
    "path": "animated-gif-lite/src/main/AndroidManifest.xml",
    "chars": 174,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    pack"
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/GifDecoder.java",
    "chars": 3875,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/decoder/GifMetadataDecoder.java",
    "chars": 9645,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/draw/MovieAnimatedImage.kt",
    "chars": 2271,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/draw/MovieDrawer.kt",
    "chars": 1394,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/draw/MovieFrame.kt",
    "chars": 1229,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/draw/MovieScaleHolder.kt",
    "chars": 1773,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-gif-lite/src/main/java/com/facebook/animated/giflite/drawable/GifAnimationBackend.kt",
    "chars": 4890,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/.gitignore",
    "chars": 12,
    "preview": "nativedeps/\n"
  },
  {
    "path": "animated-webp/build.gradle",
    "chars": 1840,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/gradle.properties",
    "chars": 124,
    "preview": "POM_NAME=AnimatedWebp\nPOM_DESCRIPTION=The classes to support animated webp\nPOM_ARTIFACT_ID=animated-webp\nPOM_PACKAGING=a"
  },
  {
    "path": "animated-webp/src/main/AndroidManifest.xml",
    "chars": 171,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    pack"
  },
  {
    "path": "animated-webp/src/main/java/com/facebook/animated/webp/WebPFrame.java",
    "chars": 2374,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/src/main/java/com/facebook/animated/webp/WebPImage.java",
    "chars": 6243,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/src/main/java/com/facebook/animated/webp/WebPImageDecoder.kt",
    "chars": 2143,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/src/main/java/com/facebook/animated/webpdrawable/WebpAnimationBackend.kt",
    "chars": 4755,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "animated-webp/src/test/java/com/facebook/animated/webp/WebPImageDecoderTest.kt",
    "chars": 16202,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "bots/IssueCommands.txt",
    "chars": 618,
    "preview": "@facebook-github-bot stack-overflow\ncomment Hey {issue_author} and thanks for posting this! {author} tells me this issue"
  },
  {
    "path": "build.gradle",
    "chars": 11349,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/build.gradle.kts",
    "chars": 249,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/src/main/java/com/facebook/fresco/buildsrc/FrescoConfig.kt",
    "chars": 479,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/src/main/java/com/facebook/fresco/buildsrc/GradleDeps.kt",
    "chars": 776,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/src/main/java/com/facebook/fresco/buildsrc/TestDeps.kt",
    "chars": 1139,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/src/main/java/com/facebook/fresco/buildsrc/dependencies-samples.kt",
    "chars": 1680,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "buildSrc/src/main/java/com/facebook/fresco/buildsrc/dependencies.kt",
    "chars": 2475,
    "preview": "/*\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found "
  },
  {
    "path": "ci/build-and-test.sh",
    "chars": 463,
    "preview": "#!/bin/bash\n# Copyright (c) Meta Platforms, Inc. and affiliates.\n#\n# This source code is licensed under the MIT license "
  },
  {
    "path": "ci/print-debug-info.sh",
    "chars": 377,
    "preview": "#!/bin/bash\n# Copyright (c) Meta Platforms, Inc. and affiliates.\n#\n# This source code is licensed under the MIT license "
  },
  {
    "path": "docs/.gitignore",
    "chars": 147,
    "preview": ".DS_STORE\n_site/\n*-e\nGemfile.lock\n*.swo\n*.swp\n.gradle\n.DS_Store\n.idea\nbuild/\nlocal.properties\nobj/\n*.iml\nnativedeps/\n.sa"
  },
  {
    "path": "docs/CNAME",
    "chars": 13,
    "preview": "frescolib.org"
  },
  {
    "path": "docs/Gemfile",
    "chars": 84,
    "preview": "source 'https://rubygems.org'\n\ngem 'github-pages', '~> 145', group: :jekyll_plugins\n"
  },
  {
    "path": "docs/NOGREP",
    "chars": 2,
    "preview": "\n\n"
  },
  {
    "path": "docs/README.md",
    "chars": 401,
    "preview": "# User Documentation for frescolib.org\n\nThis folder contains the user and feature documentation for Fresco.\n\n### Run the"
  },
  {
    "path": "docs/_config.yml",
    "chars": 1375,
    "preview": "---\npermalink: /blog/:categories/:year/:month/:day/:title.html\nurl: \"https://frescolib.org\"\nbaseurl: \"\"\ntitle: Fresco\nta"
  },
  {
    "path": "docs/_data/authors.yml",
    "chars": 350,
    "preview": "balazsbalazs:\n  full_name: Balazs Balazs\n  fbid: 100000563635135\nkirwanlyster:\n  full_name: Kirwan Lyster\n  fbid: 688556"
  },
  {
    "path": "docs/_data/nav.yml",
    "chars": 300,
    "preview": "- title: Docs\n  href: /docs/\n  category: docs\n\n- title: Support\n  href: /support.html\n  category: support\n\n- title: API\n"
  },
  {
    "path": "docs/_data/nav_docs.yml",
    "chars": 1138,
    "preview": "- title: Getting Started\n  items:\n  - id: index\n  - id: proguard\n- title: Basic Features\n  items:\n  - id: using-simpledr"
  },
  {
    "path": "docs/_data/powered_by.yml",
    "chars": 4744,
    "preview": "- title: Apps Using Fresco\n  items:\n  - name: TamTam Messenger\n    url: https://play.google.com/store/apps/details?id=ru"
  },
  {
    "path": "docs/_data/powered_by_highlight.yml",
    "chars": 514,
    "preview": "- title: Apps Using Fresco\n  items:\n  - name: Twitter\n    url: https://play.google.com/store/apps/details?id=com.twitter"
  },
  {
    "path": "docs/_data/promo.yml",
    "chars": 117,
    "preview": "- type: plugin_row\n  children:\n  - type: button\n    href: docs/index.html\n    text: Get Started\n\n- type: github_star\n"
  },
  {
    "path": "docs/_docs/03-customizing-image-formats.md",
    "chars": 7975,
    "preview": "---\ndocid: customizing-image-formats\ntitle: Customizing Image Formats\nlayout: docs\npermalink: /docs/customizing-image-fo"
  },
  {
    "path": "docs/_docs/animations.md",
    "chars": 2073,
    "preview": "---\ndocid: animations\ntitle: Animated Images\nlayout: docs\npermalink: /docs/animations.html\n---\n\nFresco supports animated"
  },
  {
    "path": "docs/_docs/building-from-source.md",
    "chars": 3162,
    "preview": "---\ndocid: building-from-source\ntitle: Building from Source\nlayout: docs\npermalink: /docs/building-from-source.html\n---\n"
  },
  {
    "path": "docs/_docs/caching.md",
    "chars": 6214,
    "preview": "---\ndocid: caching\ntitle: Caching\nlayout: docs\npermalink: /docs/caching.html\n---\n\nFresco stores images in three differen"
  },
  {
    "path": "docs/_docs/closeable-references.md",
    "chars": 4985,
    "preview": "---\ndocid: closeable-references\ntitle: Closeable References\nlayout: docs\npermalink: /docs/closeable-references.html\n---\n"
  },
  {
    "path": "docs/_docs/concepts.md",
    "chars": 2172,
    "preview": "---\ndocid: concepts\ntitle: Concepts\nlayout: docs\npermalink: /docs/concepts.html\n---\n\n## Drawees\n\nDrawees are spaces in w"
  },
  {
    "path": "docs/_docs/configure-image-pipeline.md",
    "chars": 4653,
    "preview": "---\ndocid: configure-image-pipeline\ntitle: Configuring the Image Pipeline\nlayout: docs\npermalink: /docs/configure-image-"
  },
  {
    "path": "docs/_docs/datasources-datasubscribers.md",
    "chars": 8884,
    "preview": "---\ndocid: datasources-datasubscribers\ntitle: DataSources and DataSubscribers\nlayout: docs\npermalink: /docs/datasources-"
  },
  {
    "path": "docs/_docs/drawee-branches.md",
    "chars": 5163,
    "preview": "---\ndocid: drawee-branches\ntitle: Drawee Branches\nlayout: docs\npermalink: /docs/drawee-branches.html\n---\n\n### What are B"
  },
  {
    "path": "docs/_docs/faq.md",
    "chars": 5015,
    "preview": "---\ndocid: faq\ntitle: FAQ\nlayout: docs\npermalink: /docs/faq.html\n---\n\nThese are common questions asked on our GitHub pre"
  },
  {
    "path": "docs/_docs/gotchas.md",
    "chars": 3533,
    "preview": "---\ndocid: gotchas\ntitle: Gotchas\nlayout: docs\npermalink: /docs/gotchas.html\n---\n\n#### Don't use ScrollViews\n\nIf you wan"
  },
  {
    "path": "docs/_docs/image-requests.md",
    "chars": 2264,
    "preview": "---\ndocid: image-requests\ntitle: Image Requests\nlayout: docs\npermalink: /docs/image-requests.html\n---\n\nIf you need an `I"
  },
  {
    "path": "docs/_docs/images-in-notifications.md",
    "chars": 2716,
    "preview": "---\ndocid: images-in-notifications\ntitle: Images in Notifications\nlayout: docs\npermalink: /docs/images-in-notifications."
  },
  {
    "path": "docs/_docs/index.md",
    "chars": 5750,
    "preview": "---\ndocid: index\ntitle: Getting Started with Fresco\nlayout: docs\npermalink: /docs/index.html\n---\n\nThis Guide will walk y"
  },
  {
    "path": "docs/_docs/intro-image-pipeline.md",
    "chars": 1196,
    "preview": "---\ndocid: intro-image-pipeline\ntitle: Introduction to the Image Pipeline\nlayout: docs\npermalink: /docs/intro-image-pipe"
  },
  {
    "path": "docs/_docs/listening-to-events.md",
    "chars": 7101,
    "preview": "---\ndocid: listening-to-events\ntitle: Listening to Events\nlayout: docs\npermalink: /docs/listening-to-events.html\n---\n\n##"
  },
  {
    "path": "docs/_docs/media-variations.md",
    "chars": 122,
    "preview": "---\ndocid: media-variations\ntitle: Media Variations\nlayout: docs\npermalink: /docs/media-variations.html\n---\n\nComing soon"
  },
  {
    "path": "docs/_docs/placeholder-failure-retry.md",
    "chars": 3011,
    "preview": "---\ndocid: placeholder-failure-retry\ntitle: Placeholder, failure and retry images\nlayout: docs\npermalink: /docs/placehol"
  },
  {
    "path": "docs/_docs/post-processor.md",
    "chars": 9176,
    "preview": "---\ndocid: post-processor\ntitle: Modifying the Image (Post-processing)\nlayout: docs\nredirect_from: /docs/post-processor."
  },
  {
    "path": "docs/_docs/prefetching.md",
    "chars": 1639,
    "preview": "---\ndocid: prefetching\ntitle: Prefetching Images\nlayout: docs\npermalink: /docs/prefetching.html\n---\n\nPrefetching images "
  },
  {
    "path": "docs/_docs/progress-bars.md",
    "chars": 1458,
    "preview": "---\ndocid: progress-bars\ntitle: Progress Bars\nlayout: docs\npermalink: /docs/progress-bars.html\n---\n\nThe easiest way to s"
  },
  {
    "path": "docs/_docs/progressive-jpegs.md",
    "chars": 1621,
    "preview": "---\ndocid: progressive-jpegs\ntitle: Progressive JPEGs\nlayout: docs\npermalink: /docs/progressive-jpegs.html\n---\n\nFresco s"
  },
  {
    "path": "docs/_docs/proguard.md",
    "chars": 2036,
    "preview": "---\ndocid: proguard\ntitle: Shipping Your App with Fresco\nlayout: docs\nredirect_from: /docs/proguard.html\npermalink: /doc"
  },
  {
    "path": "docs/_docs/requesting-multiple-images.md",
    "chars": 3834,
    "preview": "---\ndocid: requesting-multiple-images\ntitle: Requesting Multiple Images (Multi-URI)\nlayout: docs\npermalink: /docs/reques"
  },
  {
    "path": "docs/_docs/resizing.md",
    "chars": 4730,
    "preview": "---\ndocid: resizing\ntitle: Resizing\nlayout: docs\npermalink: /docs/resizing.html\nredirect_from:\n  - /docs/resizing-rotati"
  },
  {
    "path": "docs/_docs/rotation.md",
    "chars": 1780,
    "preview": "---\ndocid: rotation\ntitle: Rotation\nlayout: docs\npermalink: /docs/rotation.html\n---\n\nYou can rotate images by specifying"
  },
  {
    "path": "docs/_docs/rounded-corners-and-circles.md",
    "chars": 4827,
    "preview": "---\ndocid: rounded-corners-and-circles\ntitle: Rounded Corners and Circles\nlayout: docs\npermalink: /docs/rounded-corners-"
  },
  {
    "path": "docs/_docs/sample-apps.md",
    "chars": 2153,
    "preview": "---\ndocid: sample-code\ntitle: Sample code\nlayout: docs\npermalink: /docs/sample-code.html\n---\n\n*Note: the samples are lic"
  },
  {
    "path": "docs/_docs/scaletypes.md",
    "chars": 8893,
    "preview": "---\ndocid: scaletypes\ntitle: ScaleTypes\nlayout: docs\npermalink: /docs/scaletypes.html\n---\n\nYou can specify a different s"
  },
  {
    "path": "docs/_docs/shared-transitions.md",
    "chars": 992,
    "preview": "---\ndocid: shared-transitions\ntitle: Shared Transitions\nlayout: docs\npermalink: /docs/shared-transitions.html\n---\n\n## Us"
  },
  {
    "path": "docs/_docs/supported-uris.md",
    "chars": 2847,
    "preview": "---\ndocid: supported-uris\ntitle: Supported URIs\nlayout: docs\npermalink: /docs/supported-uris.html\n---\n\nFresco supports i"
  },
  {
    "path": "docs/_docs/troubleshooting.md",
    "chars": 7789,
    "preview": "---\ndocid: troubleshooting\ntitle: Troubleshooting\nlayout: docs\npermalink: /docs/troubleshooting.html\n---\n\n##  Troublesho"
  },
  {
    "path": "docs/_docs/using-controllerbuilder.md",
    "chars": 2133,
    "preview": "---\ndocid: using-controllerbuilder\ntitle: Using the ControllerBuilder\nlayout: docs\npermalink: /docs/using-controllerbuil"
  },
  {
    "path": "docs/_docs/using-image-pipeline.md",
    "chars": 4551,
    "preview": "---\ndocid: using-image-pipeline\ntitle: Using the Image Pipeline Directly\nlayout: docs\npermalink: /docs/using-image-pipel"
  },
  {
    "path": "docs/_docs/using-other-network-layers.md",
    "chars": 3246,
    "preview": "---\ndocid: using-other-network-layers\ntitle: Using Other Network Layers\nlayout: docs\npermalink: /docs/using-other-networ"
  },
  {
    "path": "docs/_docs/using-simpledraweeview.md",
    "chars": 4413,
    "preview": "---\ndocid: using-simpledraweeview\ntitle: Using SimpleDraweeView\nlayout: docs\npermalink: /docs/using-simpledraweeview.htm"
  },
  {
    "path": "docs/_docs/webp-support.md",
    "chars": 2759,
    "preview": "---\ndocid: webp-support\ntitle: WebP Images\nlayout: docs\npermalink: /docs/webp-support.html\n---\n\n[WebP](https://en.wikipe"
  },
  {
    "path": "docs/_docs/writing-custom-views.md",
    "chars": 7527,
    "preview": "---\ndocid: writing-custom-views\ntitle: Writing Custom Views\nlayout: docs\npermalink: /docs/writing-custom-views.html\n---\n"
  },
  {
    "path": "docs/_includes/blog_pagination.html",
    "chars": 975,
    "preview": "<!-- Pagination links - copied from http://jekyllrb.com/docs/pagination/ -->\r\n{% if paginator.total_pages > 1 %}\r\n<br />"
  },
  {
    "path": "docs/_includes/content/gridblocks.html",
    "chars": 171,
    "preview": "<div class=\"gridBlock\">\r\n{% for item in {{include.data_source}} %}\r\n  {% include content/items/gridblock.html item=item "
  },
  {
    "path": "docs/_includes/content/items/gridblock.html",
    "chars": 286,
    "preview": "<div class=\"featureBlock {{ include.gridtype }}\">\r\n  {% if item.image %}\r\n  <img src=\"/static/{{ item.image }}\" alt=\"{{ "
  },
  {
    "path": "docs/_includes/doc.html",
    "chars": 757,
    "preview": "<div class=\"post\">\r\n  <header class=\"post-header\">\r\n    <h1 class=\"post-title\">{% if include.truncate %}<a href=\"{{ site"
  },
  {
    "path": "docs/_includes/doc_paging.html",
    "chars": 0,
    "preview": ""
  }
]

// ... and 2370 more files (download for full content)

About this extraction

This page contains the full source code of the facebook/fresco GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 2570 files (38.2 MB), approximately 4.1M tokens, and a symbol index with 553 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!