bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.67k stars 6.12k forks source link

use "avif-integration", GIFs cannot be played. #5051

Closed 6a209 closed 1 year ago

6a209 commented 1 year ago

I found after add "avif-integration", GIFs can't be played.

Debugging the code revealed that the GIF is no longer a GifDrawable but instead a BitmapDrawable.

avif prepend Bitmap.class to resource class by this code

registry.prepend(ByteBuffer.class, Bitmap.class, byteBufferBitmapDecoder);

Then in ResourceDecoderRegistry.java, getResourceClasses method

  @NonNull
  @SuppressWarnings("unchecked")
  public synchronized <T, R> List<Class<R>> getResourceClasses(
      @NonNull Class<T> dataClass, @NonNull Class<R> resourceClass) {
    List<Class<R>> result = new ArrayList<>();
    for (String bucket : bucketPriorityList) {
      List<Entry<?, ?>> entries = decoders.get(bucket);
      if (entries == null) {
        continue;
      }
      for (Entry<?, ?> entry : entries) {
        if (entry.handles(dataClass, resourceClass)
            && !result.contains((Class<R>) entry.resourceClass)) {
          result.add((Class<R>) entry.resourceClass);
        }
      }
    }
    return result;
  }

it's make the result list first is Bitmap.class.

Register.java#getDecodePaths in this code the registeredResourceClasses's first item is Bitmap.class; decoderRegistry.getDecoders("byteBuffer", Bitmap.class) is return value will container "Downsampler" decoder

  @NonNull
  private <Data, TResource, Transcode> List<DecodePath<Data, TResource, Transcode>> getDecodePaths(
      @NonNull Class<Data> dataClass,
      @NonNull Class<TResource> resourceClass,
      @NonNull Class<Transcode> transcodeClass) {
    List<DecodePath<Data, TResource, Transcode>> decodePaths = new ArrayList<>();
    List<Class<TResource>> registeredResourceClasses =
        decoderRegistry.getResourceClasses(dataClass, resourceClass);

    for (Class<TResource> registeredResourceClass : registeredResourceClasses) {
      List<Class<Transcode>> registeredTranscodeClasses =
          transcoderRegistry.getTranscodeClasses(registeredResourceClass, transcodeClass);

      for (Class<Transcode> registeredTranscodeClass : registeredTranscodeClasses) {

        List<ResourceDecoder<Data, TResource>> decoders =
            decoderRegistry.getDecoders(dataClass, registeredResourceClass);
        ResourceTranscoder<TResource, Transcode> transcoder =
            transcoderRegistry.get(registeredResourceClass, registeredTranscodeClass);
        @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
        DecodePath<Data, TResource, Transcode> path =
            new DecodePath<>(
                dataClass,
                registeredResourceClass,
                registeredTranscodeClass,
                decoders,
                transcoder,
                throwableListPool);
        decodePaths.add(path);
      }
    }
    return decodePaths;
  }

Downsampler will intercept gif pass to gifdrawable。 Downsampler's handles() always return true.

  public boolean handles(@SuppressWarnings("unused") ByteBuffer byteBuffer) {
    // We expect downsampler to handle any available type Android supports.
    return true;
  }

So if you prepend Bitmap.class Resources, your gif format will be not work.

How to remove Downsampler or move it to the behind make gif work ?

sea5241 commented 1 year ago

I have also encountered this problem. How can I solve it?