1 /*
2  * Copyright (C) 2009 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 
17 package com.android.camera.gallery;
18 
19 import com.android.camera.BitmapManager;
20 import com.android.camera.Util;
21 
22 import android.content.ContentResolver;
23 import android.graphics.Bitmap;
24 import android.graphics.BitmapFactory;
25 import android.net.Uri;
26 import android.os.ParcelFileDescriptor;
27 import android.provider.MediaStore.Images;
28 import android.util.Log;
29 
30 import java.io.FileNotFoundException;
31 import java.io.IOException;
32 import java.io.InputStream;
33 
34 /**
35  * Represents a particular image and provides access to the underlying bitmap
36  * and two thumbnail bitmaps as well as other information such as the id, and
37  * the path to the actual image data.
38  */
39 public abstract class BaseImage implements IImage {
40     private static final String TAG = "BaseImage";
41     private static final int UNKNOWN_LENGTH = -1;
42     protected ContentResolver mContentResolver;
43 
44     // Database field
45     protected Uri mUri;
46     protected long mId;
47     protected String mDataPath;
48     protected final int mIndex;
49     protected String mMimeType;
50     private final long mDateTaken;
51     private String mTitle;
52 
53     protected BaseImageList mContainer;
54 
55     private int mWidth = UNKNOWN_LENGTH;
56     private int mHeight = UNKNOWN_LENGTH;
57 
BaseImage(BaseImageList container, ContentResolver cr, long id, int index, Uri uri, String dataPath, String mimeType, long dateTaken, String title)58     protected BaseImage(BaseImageList container, ContentResolver cr,
59             long id, int index, Uri uri, String dataPath, String mimeType,
60             long dateTaken, String title) {
61         mContainer = container;
62         mContentResolver = cr;
63         mId = id;
64         mIndex = index;
65         mUri = uri;
66         mDataPath = dataPath;
67         mMimeType = mimeType;
68         mDateTaken = dateTaken;
69         mTitle = title;
70     }
71 
getDataPath()72     public String getDataPath() {
73         return mDataPath;
74     }
75 
76     @Override
equals(Object other)77     public boolean equals(Object other) {
78         if (other == null || !(other instanceof Image)) return false;
79         return mUri.equals(((Image) other).mUri);
80     }
81 
82     @Override
hashCode()83     public int hashCode() {
84         return mUri.hashCode();
85     }
86 
fullSizeBitmap(int minSideLength, int maxNumberOfPixels)87     public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels) {
88         return fullSizeBitmap(minSideLength, maxNumberOfPixels,
89                 IImage.ROTATE_AS_NEEDED, IImage.NO_NATIVE);
90     }
91 
fullSizeBitmap(int minSideLength, int maxNumberOfPixels, boolean rotateAsNeeded, boolean useNative)92     public Bitmap fullSizeBitmap(int minSideLength, int maxNumberOfPixels,
93             boolean rotateAsNeeded, boolean useNative) {
94         Uri url = mContainer.contentUri(mId);
95         if (url == null) return null;
96 
97         Bitmap b = Util.makeBitmap(minSideLength, maxNumberOfPixels,
98                 url, mContentResolver, useNative);
99 
100         if (b != null && rotateAsNeeded) {
101             b = Util.rotate(b, getDegreesRotated());
102         }
103 
104         return b;
105     }
106 
fullSizeImageData()107     public InputStream fullSizeImageData() {
108         try {
109             InputStream input = mContentResolver.openInputStream(mUri);
110             return input;
111         } catch (IOException ex) {
112             return null;
113         }
114     }
115 
fullSizeImageUri()116     public Uri fullSizeImageUri() {
117         return mUri;
118     }
119 
getContainer()120     public IImageList getContainer() {
121         return mContainer;
122     }
123 
getDateTaken()124     public long getDateTaken() {
125         return mDateTaken;
126     }
127 
getDegreesRotated()128     public int getDegreesRotated() {
129         return 0;
130     }
131 
getMimeType()132     public String getMimeType() {
133         return mMimeType;
134     }
135 
getTitle()136     public String getTitle() {
137         return mTitle;
138     }
139 
setupDimension()140     private void setupDimension() {
141         ParcelFileDescriptor input = null;
142         try {
143             input = mContentResolver.openFileDescriptor(mUri, "r");
144             BitmapFactory.Options options = new BitmapFactory.Options();
145             options.inJustDecodeBounds = true;
146             BitmapManager.instance().decodeFileDescriptor(
147                     input.getFileDescriptor(), options);
148             mWidth = options.outWidth;
149             mHeight = options.outHeight;
150         } catch (FileNotFoundException ex) {
151             mWidth = 0;
152             mHeight = 0;
153         } finally {
154             Util.closeSilently(input);
155         }
156     }
157 
getWidth()158     public int getWidth() {
159         if (mWidth == UNKNOWN_LENGTH) setupDimension();
160         return mWidth;
161     }
162 
getHeight()163     public int getHeight() {
164         if (mHeight == UNKNOWN_LENGTH) setupDimension();
165         return mHeight;
166     }
167 
miniThumbBitmap()168     public Bitmap miniThumbBitmap() {
169         Bitmap b = null;
170         try {
171             long id = mId;
172             b = BitmapManager.instance().getThumbnail(mContentResolver, id,
173                     Images.Thumbnails.MICRO_KIND, null, false);
174         } catch (Throwable ex) {
175             Log.e(TAG, "miniThumbBitmap got exception", ex);
176             return null;
177         }
178         if (b != null) {
179             b = Util.rotate(b, getDegreesRotated());
180         }
181         return b;
182     }
183 
onRemove()184     protected void onRemove() {
185     }
186 
187     @Override
toString()188     public String toString() {
189         return mUri.toString();
190     }
191 }
192