1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.messaging.datamodel.media;
17 
18 import android.content.res.Resources;
19 import android.graphics.Bitmap;
20 import android.graphics.drawable.Drawable;
21 import android.media.ExifInterface;
22 import android.support.rastermill.FrameSequence;
23 import android.support.rastermill.FrameSequenceDrawable;
24 
25 import com.android.messaging.util.Assert;
26 
27 import java.io.IOException;
28 import java.io.InputStream;
29 
30 public class GifImageResource extends ImageResource {
31     private FrameSequence mFrameSequence;
32 
GifImageResource(String key, FrameSequence frameSequence)33     public GifImageResource(String key, FrameSequence frameSequence) {
34         // GIF does not support exif tags
35         super(key, ExifInterface.ORIENTATION_NORMAL);
36         mFrameSequence = frameSequence;
37     }
38 
createGifImageResource(String key, InputStream inputStream)39     public static GifImageResource createGifImageResource(String key, InputStream inputStream) {
40         final FrameSequence frameSequence;
41         try {
42             frameSequence = FrameSequence.decodeStream(inputStream);
43         } finally {
44             try {
45                 inputStream.close();
46             } catch (IOException e) {
47                 // Nothing to do if we fail closing the stream
48             }
49         }
50         if (frameSequence == null) {
51             return null;
52         }
53         return new GifImageResource(key, frameSequence);
54     }
55 
56     @Override
getDrawable(Resources resources)57     public Drawable getDrawable(Resources resources) {
58         return new FrameSequenceDrawable(mFrameSequence);
59     }
60 
61     @Override
getBitmap()62     public Bitmap getBitmap() {
63         Assert.fail("GetBitmap() should never be called on a gif.");
64         return null;
65     }
66 
67     @Override
getBytes()68     public byte[] getBytes() {
69         Assert.fail("GetBytes() should never be called on a gif.");
70         return null;
71     }
72 
73     @Override
reuseBitmap()74     public Bitmap reuseBitmap() {
75         return null;
76     }
77 
78     @Override
supportsBitmapReuse()79     public boolean supportsBitmapReuse() {
80         // FrameSequenceDrawable a.) takes two bitmaps and thus does not fit into the current
81         // bitmap pool architecture b.) will rarely use bitmaps from one FrameSequenceDrawable to
82         // the next that are the same sizes since they are used by attachments.
83         return false;
84     }
85 
86     @Override
getMediaSize()87     public int getMediaSize() {
88         Assert.fail("GifImageResource should not be used by a media cache");
89         // Only used by the media cache, which this does not use.
90         return 0;
91     }
92 
93     @Override
isCacheable()94     public boolean isCacheable() {
95         return false;
96     }
97 
98     @Override
close()99     protected void close() {
100         acquireLock();
101         try {
102             if (mFrameSequence != null) {
103                 mFrameSequence = null;
104             }
105         } finally {
106             releaseLock();
107         }
108     }
109 
110 }
111