1/*
2 * Copyright (C) 2010 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
17package com.android.gallery3d.data;
18
19import android.graphics.Bitmap;
20import android.graphics.BitmapFactory;
21
22import com.android.gallery3d.app.GalleryApp;
23import com.android.gallery3d.common.BitmapUtils;
24import com.android.gallery3d.data.BytesBufferPool.BytesBuffer;
25import com.android.gallery3d.util.ThreadPool.Job;
26import com.android.gallery3d.util.ThreadPool.JobContext;
27
28abstract class ImageCacheRequest implements Job<Bitmap> {
29    private static final String TAG = "ImageCacheRequest";
30
31    protected GalleryApp mApplication;
32    private Path mPath;
33    private int mType;
34    private int mTargetSize;
35    private long mTimeModified;
36
37    public ImageCacheRequest(GalleryApp application,
38            Path path, long timeModified, int type, int targetSize) {
39        mApplication = application;
40        mPath = path;
41        mType = type;
42        mTargetSize = targetSize;
43        mTimeModified = timeModified;
44    }
45
46    private String debugTag() {
47        return mPath + "," + mTimeModified + "," +
48                ((mType == MediaItem.TYPE_THUMBNAIL) ? "THUMB" :
49                (mType == MediaItem.TYPE_MICROTHUMBNAIL) ? "MICROTHUMB" : "?");
50    }
51
52    @Override
53    public Bitmap run(JobContext jc) {
54        ImageCacheService cacheService = mApplication.getImageCacheService();
55
56        BytesBuffer buffer = MediaItem.getBytesBufferPool().get();
57        try {
58            boolean found = cacheService.getImageData(mPath, mTimeModified, mType, buffer);
59            if (jc.isCancelled()) return null;
60            if (found) {
61                BitmapFactory.Options options = new BitmapFactory.Options();
62                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
63                Bitmap bitmap;
64                if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
65                    bitmap = DecodeUtils.decodeUsingPool(jc,
66                            buffer.data, buffer.offset, buffer.length, options);
67                } else {
68                    bitmap = DecodeUtils.decodeUsingPool(jc,
69                            buffer.data, buffer.offset, buffer.length, options);
70                }
71                if (bitmap == null && !jc.isCancelled()) {
72                    Log.w(TAG, "decode cached failed " + debugTag());
73                }
74                return bitmap;
75            }
76        } finally {
77            MediaItem.getBytesBufferPool().recycle(buffer);
78        }
79        Bitmap bitmap = onDecodeOriginal(jc, mType);
80        if (jc.isCancelled()) return null;
81
82        if (bitmap == null) {
83            Log.w(TAG, "decode orig failed " + debugTag());
84            return null;
85        }
86
87        if (mType == MediaItem.TYPE_MICROTHUMBNAIL) {
88            bitmap = BitmapUtils.resizeAndCropCenter(bitmap, mTargetSize, true);
89        } else {
90            bitmap = BitmapUtils.resizeDownBySideLength(bitmap, mTargetSize, true);
91        }
92        if (jc.isCancelled()) return null;
93
94        byte[] array = BitmapUtils.compressToBytes(bitmap);
95        if (jc.isCancelled()) return null;
96
97        cacheService.putImageData(mPath, mTimeModified, mType, array);
98        return bitmap;
99    }
100
101    public abstract Bitmap onDecodeOriginal(JobContext jc, int targetSize);
102}
103