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