1c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu/* 2c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Copyright (C) 2013 The Android Open Source Project 3c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * 4c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Licensed under the Apache License, Version 2.0 (the "License"); 5c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * you may not use this file except in compliance with the License. 6c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * You may obtain a copy of the License at 7c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * 8c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * http://www.apache.org/licenses/LICENSE-2.0 9c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * 10c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * Unless required by applicable law or agreed to in writing, software 11c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * distributed under the License is distributed on an "AS IS" BASIS, 12c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * See the License for the specific language governing permissions and 14c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu * limitations under the License. 15c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu */ 16c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 17c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescupackage com.android.gallery3d.ingest.data; 18c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 19c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.content.Context; 20c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.graphics.Bitmap; 21c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.graphics.BitmapFactory; 22c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.mtp.MtpDevice; 23c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.mtp.MtpObjectInfo; 24c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.util.DisplayMetrics; 25c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescuimport android.view.WindowManager; 26c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 27723bf81990245a07739146ac10357703c9839de1Sascha Haeberlingimport com.android.gallery3d.data.Exif; 28f52ceba89962829aa12f5caba131580e8da85880Bobby Georgescuimport com.android.photos.data.GalleryBitmapPool; 29c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 30c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescupublic class MtpBitmapFetch { 31c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu private static int sMaxSize = 0; 32c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 33c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static void recycleThumbnail(Bitmap b) { 34c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (b != null) { 35f52ceba89962829aa12f5caba131580e8da85880Bobby Georgescu GalleryBitmapPool.getInstance().put(b); 36c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 37c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 38c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 39c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static Bitmap getThumbnail(MtpDevice device, MtpObjectInfo info) { 40c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu byte[] imageBytes = device.getThumbnail(info.getObjectHandle()); 416058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu if (imageBytes == null) { 426058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return null; 436058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } 44c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu BitmapFactory.Options o = new BitmapFactory.Options(); 45c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inJustDecodeBounds = true; 46c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o); 476058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu if (o.outWidth == 0 || o.outHeight == 0) { 486058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return null; 496058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } 50f52ceba89962829aa12f5caba131580e8da85880Bobby Georgescu o.inBitmap = GalleryBitmapPool.getInstance().get(o.outWidth, o.outHeight); 51c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inMutable = true; 52c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inJustDecodeBounds = false; 53c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inSampleSize = 1; 546058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu try { 556058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o); 566058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } catch (IllegalArgumentException e) { 576058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu // BitmapFactory throws an exception rather than returning null 586058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu // when image decoding fails and an existing bitmap was supplied 596058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu // for recycling, even if the failure was not caused by the use 606058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu // of that bitmap. 616058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); 626058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } 63c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 64c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 65c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info) { 66c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return getFullsize(device, info, sMaxSize); 67c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 68c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 69c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info, int maxSide) { 70c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu byte[] imageBytes = device.getObject(info.getObjectHandle(), info.getCompressedSize()); 716058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu if (imageBytes == null) { 726058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return null; 736058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } 74c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu Bitmap created; 75c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu if (maxSide > 0) { 76c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu BitmapFactory.Options o = new BitmapFactory.Options(); 77c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inJustDecodeBounds = true; 78c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o); 79c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu int w = o.outWidth; 80c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu int h = o.outHeight; 81c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu int comp = Math.max(h, w); 82c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu int sampleSize = 1; 83c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu while ((comp >> 1) >= maxSide) { 84c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu comp = comp >> 1; 85c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu sampleSize++; 86c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 87c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inSampleSize = sampleSize; 88c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu o.inJustDecodeBounds = false; 89c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o); 90c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } else { 91c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); 92c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 936058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu if (created == null) { 946058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu return null; 956058af443b087ba50741cc3e61ec70e830e498faBobby Georgescu } 96c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 97c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu return new BitmapWithMetadata(created, Exif.getOrientation(imageBytes)); 98c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 99c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu 100c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu public static void configureForContext(Context context) { 101c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu DisplayMetrics metrics = new DisplayMetrics(); 102c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 103c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu wm.getDefaultDisplay().getMetrics(metrics); 104c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu sMaxSize = Math.max(metrics.heightPixels, metrics.widthPixels); 105c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu } 106c8a9e86919dca8938948f97efc3dcbe143e806bfBobby Georgescu} 107