GifDrawable.java revision a37592fb57e7cd95b53d9493e0f339d04b38b808
1ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddpackage com.bumptech.glide.load.resource.gif;
2ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
3ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Bitmap;
4ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Canvas;
5ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.ColorFilter;
6ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Paint;
7ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.PixelFormat;
8ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.drawable.Animatable;
9ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.drawable.Drawable;
104f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Juddimport com.bumptech.glide.load.resource.gif.decoder.GifDecoder;
11ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
12ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddpublic class GifDrawable extends Drawable implements Animatable, GifFrameManager.FrameCallback {
13ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
14ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private final Paint paint;
15ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private final GifFrameManager frameManager;
16a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd    private int width;
17a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd    private int height;
18ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private GifDecoder decoder;
19ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private boolean isRunning;
20ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private Bitmap currentFrame;
214f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    private boolean isRecycled;
22ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
23ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public GifDrawable(GifDecoder decoder, GifFrameManager frameManager) {
24ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.decoder = decoder;
25ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.frameManager = frameManager;
26a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        width = -1;
27a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        height = -1;
28ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
29ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint = new Paint();
30ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
31ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
32ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
33ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void start() {
34ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (!isRunning) {
35ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            isRunning = true;
368e9362526ca1e73364de269ae09c75c98d0e23f5Sam Judd            frameManager.getNextFrame(this);
37ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            invalidateSelf();
38ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
39ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
40ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
41ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
42ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public boolean setVisible(boolean visible, boolean restart) {
43ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (!visible) {
44ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            stop();
45ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        } else {
46ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            start();
47ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
48ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return super.setVisible(visible, restart);
49ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
50ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
51a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd
52ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
53ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getIntrinsicWidth() {
54a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        return width;
55ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
56ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
57ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
58ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getIntrinsicHeight() {
59a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        return height;
60ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
61ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
62ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
63ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void stop() {
64ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        isRunning = false;
65ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
66ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
67ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
68ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public boolean isRunning() {
69ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return isRunning;
70ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
71ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
72ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    // For testing.
73ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    void setIsRunning(boolean isRunning) {
74ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.isRunning = isRunning;
75ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
76ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
77ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
78ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void draw(Canvas canvas) {
79ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (currentFrame != null) {
80ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            canvas.drawBitmap(currentFrame, 0, 0, paint);
81ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
82ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
83ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
84ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
85ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void setAlpha(int i) {
86ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint.setAlpha(i);
87ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
88ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
89ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
90ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void setColorFilter(ColorFilter colorFilter) {
91ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint.setColorFilter(colorFilter);
92ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
93ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
94ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
95ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getOpacity() {
96ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return decoder.isTransparent() ? PixelFormat.TRANSPARENT : PixelFormat.OPAQUE;
97ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
98ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
99ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
100ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void onFrameRead(Bitmap frame) {
101ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (!isRunning) {
102ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            return;
103ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
104a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        if (width == -1) {
105a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd            width = frame.getWidth();
106a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        }
107a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        if (height == -1) {
108a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd            height = frame.getHeight();
109a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        }
110ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
111ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (frame != null) {
112ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            currentFrame = frame;
113ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            invalidateSelf();
114ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
115ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
1168e9362526ca1e73364de269ae09c75c98d0e23f5Sam Judd        frameManager.getNextFrame(this);
117ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
118ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
119ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void recycle() {
1204f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd        isRecycled = true;
121ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        frameManager.clear();
122ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
1234f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd
1244f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    public boolean isRecycled() {
1254f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd        return isRecycled;
1264f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    }
127ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd}
128