private int getEstimatedTotalFrameSize() { if (frameSize == -1) { return decoder.getDecodedFramesByteSizeSum(); } else { return frameSize * decoder.getFrameCount(); } }
public GifFrameManager( Context context, BitmapPool bitmapPool, GifDecoder decoder, Handler mainHandler, Transformation<Bitmap> transformation, int targetWidth, int targetHeight) { this.context = context; this.decoder = decoder; this.mainHandler = mainHandler; this.transformation = transformation; this.targetWidth = targetWidth; this.targetHeight = targetHeight; calculator = new MemorySizeCalculator(context); frameLoader = new GifFrameModelLoader(); frameResourceDecoder = new GifFrameResourceDecoder(bitmapPool); sourceEncoder = NullEncoder.get(); if (!decoder.isTransparent()) { // For non transparent gifs, we can beat the performance of our gif decoder for each frame by // decoding jpegs // from disk. cacheDecoder = new StreamBitmapDecoder(context); encoder = new BitmapEncoder(Bitmap.CompressFormat.JPEG, 70); } else { // For transparent gifs, we would have to encode as pngs which is actually slower than our gif // decoder so we // avoid writing frames to the disk cache entirely. cacheDecoder = NullDecoder.get(); encoder = SkipCache.get(); } }
@Test public void testReturnsFrameFromGifDecoder() throws IOException { Bitmap expected = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_4444); when(gifDecoder.getNextFrame()).thenReturn(expected); assertEquals(expected, resourceDecoder.decode(gifDecoder, 100, 100).get()); }
public void getNextFrame(FrameCallback cb) { decoder.advance(); // We don't want to blow out the entire memory cache with frames of gifs, so try to set some // maximum size beyond which we will always just decode one frame at a time. boolean skipCache = getEstimatedTotalFrameSize() > calculator.getMemoryCacheSize() / 2; long targetTime = SystemClock.uptimeMillis() + (Math.max(MIN_FRAME_DELAY, decoder.getNextDelay())); next = new DelayTarget(cb, targetTime); Glide.with(context) .using(frameLoader, GifDecoder.class) .load(decoder) .as(Bitmap.class) .decoder(frameResourceDecoder) .cacheDecoder(cacheDecoder) .transform(transformation) .encoder(encoder) .sourceEncoder(sourceEncoder) .skipMemoryCache(skipCache) .into(next); }
@Override public Resource<Bitmap> decode(GifDecoder source, int width, int height) throws IOException { Bitmap bitmap = source.getNextFrame(); return new BitmapResource(bitmap, bitmapPool); }