Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
1 /*
2 * Copyright (C) 2014 Square, Inc.
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.squareup.picasso;
18 import android.content.ContentResolver;
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.graphics.Bitmap;
22 import android.graphics.BitmapFactory;
23 import android.net.Uri;
24 import android.provider.MediaStore;
25 import java.io.IOException;
27 import static android.content.ContentUris.parseId;
28 import static android.provider.MediaStore.Images.Thumbnails.FULL_SCREEN_KIND;
29 import static android.provider.MediaStore.Images.Thumbnails.MICRO_KIND;
30 import static android.provider.MediaStore.Images.Thumbnails.MINI_KIND;
31 import static android.provider.MediaStore.Images.Thumbnails.getThumbnail;
32 import static com.squareup.picasso.MediaStoreBitmapHunter.PicassoKind.FULL;
33 import static com.squareup.picasso.MediaStoreBitmapHunter.PicassoKind.MICRO;
34 import static com.squareup.picasso.MediaStoreBitmapHunter.PicassoKind.MINI;
36 class MediaStoreBitmapHunter extends ContentStreamBitmapHunter {
37 private static final String[] CONTENT_ORIENTATION = new String[] {
38 MediaStore.Images.ImageColumns.ORIENTATION
39 };
41 MediaStoreBitmapHunter(Context context, Picasso picasso, Dispatcher dispatcher, Cache cache,
42 Stats stats, Action action) {
43 super(context, picasso, dispatcher, cache, stats, action);
44 }
46 @Override Bitmap decode(Request data) throws IOException {
47 ContentResolver contentResolver = context.getContentResolver();
48 setExifRotation(getExitOrientation(contentResolver, data.uri));
50 if (data.hasSize()) {
51 PicassoKind picassoKind = getPicassoKind(data.targetWidth, data.targetHeight);
52 if (picassoKind == FULL) {
53 return super.decode(data);
54 }
56 long id = parseId(data.uri);
58 BitmapFactory.Options options = new BitmapFactory.Options();
59 options.inJustDecodeBounds = true;
61 calculateInSampleSize(data.targetWidth, data.targetHeight, picassoKind.width,
62 picassoKind.height, options);
64 Bitmap result = getThumbnail(contentResolver, id, picassoKind.androidKind, options);
66 if (result != null) {
67 return result;
68 }
69 }
71 return super.decode(data);
72 }
74 static PicassoKind getPicassoKind(int targetWidth, int targetHeight) {
75 if (targetWidth <= MICRO.width && targetHeight <= MICRO.height) {
76 return MICRO;
77 } else if (targetWidth <= MINI.width && targetHeight <= MINI.height) {
78 return MINI;
79 }
80 return FULL;
81 }
83 static int getExitOrientation(ContentResolver contentResolver, Uri uri) {
84 Cursor cursor = null;
85 try {
86 cursor = contentResolver.query(uri, CONTENT_ORIENTATION, null, null, null);
87 if (cursor == null || !cursor.moveToFirst()) {
88 return 0;
89 }
90 return cursor.getInt(0);
91 } catch (RuntimeException ignored) {
92 // If the orientation column doesn't exist, assume no rotation.
93 return 0;
94 } finally {
95 if (cursor != null) {
96 cursor.close();
97 }
98 }
99 }
101 enum PicassoKind {
102 MICRO(MICRO_KIND, 96, 96),
103 MINI(MINI_KIND, 512, 384),
104 FULL(FULL_SCREEN_KIND, -1, -1);
106 final int androidKind;
107 final int width;
108 final int height;
110 PicassoKind(int androidKind, int width, int height) {
111 this.androidKind = androidKind;
112 this.width = width;
113 this.height = height;
114 }
115 }
116 }