1ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddpackage com.bumptech.glide.load.resource.gif;
2ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
3fcca8d79a3a04e71924d06799de2af46c923a84eSam Juddimport android.annotation.TargetApi;
4ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Bitmap;
5ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Canvas;
6ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.ColorFilter;
7ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.Paint;
8ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.PixelFormat;
9ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.drawable.Animatable;
10ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddimport android.graphics.drawable.Drawable;
11fcca8d79a3a04e71924d06799de2af46c923a84eSam Juddimport android.os.Build;
12fcca8d79a3a04e71924d06799de2af46c923a84eSam Judd
130f49c87b2f26f3e086f021461b7e5409a7d42be0Sam Juddimport com.bumptech.glide.gifdecoder.GifDecoder;
14ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
15ea01ddd754126290fc18c3dc8f6095ce0216768aSam Juddpublic class GifDrawable extends Drawable implements Animatable, GifFrameManager.FrameCallback {
16ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
17ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private final Paint paint;
18ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private final GifFrameManager frameManager;
19a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd    private int width;
20a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd    private int height;
21ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private GifDecoder decoder;
22ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private boolean isRunning;
23ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    private Bitmap currentFrame;
244f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    private boolean isRecycled;
25ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
26ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public GifDrawable(GifDecoder decoder, GifFrameManager frameManager) {
27ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.decoder = decoder;
28ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.frameManager = frameManager;
29a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        width = -1;
30a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        height = -1;
31ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
32ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint = new Paint();
33ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
34ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
35ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
36ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void start() {
37ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (!isRunning) {
38ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            isRunning = true;
398e9362526ca1e73364de269ae09c75c98d0e23f5Sam Judd            frameManager.getNextFrame(this);
40ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            invalidateSelf();
41ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
42ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
43ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
44ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
45ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public boolean setVisible(boolean visible, boolean restart) {
46ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (!visible) {
47ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            stop();
48ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        } else {
49ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            start();
50ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
51ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return super.setVisible(visible, restart);
52ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
53ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
54a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd
55ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
56ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getIntrinsicWidth() {
57a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        return width;
58ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
59ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
60ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
61ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getIntrinsicHeight() {
62a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        return height;
63ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
64ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
65ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
66ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void stop() {
67ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        isRunning = false;
68ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
69ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
70ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
71ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public boolean isRunning() {
72ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return isRunning;
73ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
74ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
75ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    // For testing.
76ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    void setIsRunning(boolean isRunning) {
77ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        this.isRunning = isRunning;
78ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
79ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
80ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
81ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void draw(Canvas canvas) {
82ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (currentFrame != null) {
83ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            canvas.drawBitmap(currentFrame, 0, 0, paint);
84ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
85ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
86ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
87ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
88ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void setAlpha(int i) {
89ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint.setAlpha(i);
90ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
91ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
92ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
93ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void setColorFilter(ColorFilter colorFilter) {
94ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        paint.setColorFilter(colorFilter);
95ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
96ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
97ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
98ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public int getOpacity() {
99ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        return decoder.isTransparent() ? PixelFormat.TRANSPARENT : PixelFormat.OPAQUE;
100ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
101ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
102fcca8d79a3a04e71924d06799de2af46c923a84eSam Judd    @TargetApi(11)
103ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    @Override
104ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void onFrameRead(Bitmap frame) {
105fcca8d79a3a04e71924d06799de2af46c923a84eSam Judd        if (Build.VERSION.SDK_INT >= 11 && getCallback() == null) {
1060d8a954b91ef8a37c944c2fdee75966c6f94d7bbSam Judd            stop();
1070d8a954b91ef8a37c944c2fdee75966c6f94d7bbSam Judd            return;
1080d8a954b91ef8a37c944c2fdee75966c6f94d7bbSam Judd        } if (!isRunning) {
109ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            return;
110ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
1110d8a954b91ef8a37c944c2fdee75966c6f94d7bbSam Judd
112a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        if (width == -1) {
113a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd            width = frame.getWidth();
114a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        }
115a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        if (height == -1) {
116a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd            height = frame.getHeight();
117a37592fb57e7cd95b53d9493e0f339d04b38b808Sam Judd        }
118ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
119ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        if (frame != null) {
120ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            currentFrame = frame;
121ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd            invalidateSelf();
122ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        }
123ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
1248e9362526ca1e73364de269ae09c75c98d0e23f5Sam Judd        frameManager.getNextFrame(this);
125ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
126ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd
127ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    public void recycle() {
1284f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd        isRecycled = true;
129ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd        frameManager.clear();
130ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd    }
1314f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd
1324f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    public boolean isRecycled() {
1334f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd        return isRecycled;
1344f96c1a82e7d2db4863ac63dd00a261e9f0746b1Sam Judd    }
135ea01ddd754126290fc18c3dc8f6095ce0216768aSam Judd}
136