diff options
Diffstat (limited to 'src/com/android/photos/drawables/AutoThumbnailDrawable.java')
-rw-r--r-- | src/com/android/photos/drawables/AutoThumbnailDrawable.java | 309 |
1 files changed, 0 insertions, 309 deletions
diff --git a/src/com/android/photos/drawables/AutoThumbnailDrawable.java b/src/com/android/photos/drawables/AutoThumbnailDrawable.java deleted file mode 100644 index b51b6709f..000000000 --- a/src/com/android/photos/drawables/AutoThumbnailDrawable.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.photos.drawables; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.util.Log; - -import com.android.photos.data.GalleryBitmapPool; - -import java.io.InputStream; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public abstract class AutoThumbnailDrawable<T> extends Drawable { - - private static final String TAG = "AutoThumbnailDrawable"; - - private static ExecutorService sThreadPool = Executors.newSingleThreadExecutor(); - private static GalleryBitmapPool sBitmapPool = GalleryBitmapPool.getInstance(); - private static byte[] sTempStorage = new byte[64 * 1024]; - - // UI thread only - private Paint mPaint = new Paint(); - private Matrix mDrawMatrix = new Matrix(); - - // Decoder thread only - private BitmapFactory.Options mOptions = new BitmapFactory.Options(); - - // Shared, guarded by mLock - private Object mLock = new Object(); - private Bitmap mBitmap; - protected T mData; - private boolean mIsQueued; - private int mImageWidth, mImageHeight; - private Rect mBounds = new Rect(); - private int mSampleSize = 1; - - public AutoThumbnailDrawable() { - mPaint.setAntiAlias(true); - mPaint.setFilterBitmap(true); - mDrawMatrix.reset(); - mOptions.inTempStorage = sTempStorage; - } - - protected abstract byte[] getPreferredImageBytes(T data); - protected abstract InputStream getFallbackImageStream(T data); - protected abstract boolean dataChangedLocked(T data); - - public void setImage(T data, int width, int height) { - if (!dataChangedLocked(data)) return; - synchronized (mLock) { - mImageWidth = width; - mImageHeight = height; - mData = data; - setBitmapLocked(null); - refreshSampleSizeLocked(); - } - invalidateSelf(); - } - - private void setBitmapLocked(Bitmap b) { - if (b == mBitmap) { - return; - } - if (mBitmap != null) { - sBitmapPool.put(mBitmap); - } - mBitmap = b; - } - - @Override - protected void onBoundsChange(Rect bounds) { - super.onBoundsChange(bounds); - synchronized (mLock) { - mBounds.set(bounds); - if (mBounds.isEmpty()) { - mBitmap = null; - } else { - refreshSampleSizeLocked(); - updateDrawMatrixLocked(); - } - } - invalidateSelf(); - } - - @Override - public void draw(Canvas canvas) { - if (mBitmap != null) { - canvas.save(); - canvas.clipRect(mBounds); - canvas.concat(mDrawMatrix); - canvas.drawBitmap(mBitmap, 0, 0, mPaint); - canvas.restore(); - } else { - // TODO: Draw placeholder...? - } - } - - private void updateDrawMatrixLocked() { - if (mBitmap == null || mBounds.isEmpty()) { - mDrawMatrix.reset(); - return; - } - - float scale; - float dx = 0, dy = 0; - - int dwidth = mBitmap.getWidth(); - int dheight = mBitmap.getHeight(); - int vwidth = mBounds.width(); - int vheight = mBounds.height(); - - // Calculates a matrix similar to ScaleType.CENTER_CROP - if (dwidth * vheight > vwidth * dheight) { - scale = (float) vheight / (float) dheight; - dx = (vwidth - dwidth * scale) * 0.5f; - } else { - scale = (float) vwidth / (float) dwidth; - dy = (vheight - dheight * scale) * 0.5f; - } - if (scale < .8f) { - Log.w(TAG, "sample size was too small! Overdrawing! " + scale + ", " + mSampleSize); - } else if (scale > 1.5f) { - Log.w(TAG, "Potential quality loss! " + scale + ", " + mSampleSize); - } - - mDrawMatrix.setScale(scale, scale); - mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f)); - } - - private int calculateSampleSizeLocked(int dwidth, int dheight) { - float scale; - - int vwidth = mBounds.width(); - int vheight = mBounds.height(); - - // Inverse of updateDrawMatrixLocked - if (dwidth * vheight > vwidth * dheight) { - scale = (float) dheight / (float) vheight; - } else { - scale = (float) dwidth / (float) vwidth; - } - int result = Math.round(scale); - return result > 0 ? result : 1; - } - - private void refreshSampleSizeLocked() { - if (mBounds.isEmpty() || mImageWidth == 0 || mImageHeight == 0) { - return; - } - - int sampleSize = calculateSampleSizeLocked(mImageWidth, mImageHeight); - if (sampleSize != mSampleSize || mBitmap == null) { - mSampleSize = sampleSize; - loadBitmapLocked(); - } - } - - private void loadBitmapLocked() { - if (!mIsQueued && !mBounds.isEmpty()) { - unscheduleSelf(mUpdateBitmap); - sThreadPool.execute(mLoadBitmap); - mIsQueued = true; - } - } - - public float getAspectRatio() { - return (float) mImageWidth / (float) mImageHeight; - } - - @Override - public int getIntrinsicWidth() { - return -1; - } - - @Override - public int getIntrinsicHeight() { - return -1; - } - - @Override - public int getOpacity() { - Bitmap bm = mBitmap; - return (bm == null || bm.hasAlpha() || mPaint.getAlpha() < 255) ? - PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; - } - - @Override - public void setAlpha(int alpha) { - int oldAlpha = mPaint.getAlpha(); - if (alpha != oldAlpha) { - mPaint.setAlpha(alpha); - invalidateSelf(); - } - } - - @Override - public void setColorFilter(ColorFilter cf) { - mPaint.setColorFilter(cf); - invalidateSelf(); - } - - private final Runnable mLoadBitmap = new Runnable() { - @Override - public void run() { - T data; - synchronized (mLock) { - data = mData; - } - int preferredSampleSize = 1; - byte[] preferred = getPreferredImageBytes(data); - boolean hasPreferred = (preferred != null && preferred.length > 0); - if (hasPreferred) { - mOptions.inJustDecodeBounds = true; - BitmapFactory.decodeByteArray(preferred, 0, preferred.length, mOptions); - mOptions.inJustDecodeBounds = false; - } - int sampleSize, width, height; - synchronized (mLock) { - if (dataChangedLocked(data)) { - return; - } - width = mImageWidth; - height = mImageHeight; - if (hasPreferred) { - preferredSampleSize = calculateSampleSizeLocked( - mOptions.outWidth, mOptions.outHeight); - } - sampleSize = calculateSampleSizeLocked(width, height); - mIsQueued = false; - } - Bitmap b = null; - InputStream is = null; - try { - if (hasPreferred) { - mOptions.inSampleSize = preferredSampleSize; - mOptions.inBitmap = sBitmapPool.get( - mOptions.outWidth / preferredSampleSize, - mOptions.outHeight / preferredSampleSize); - b = BitmapFactory.decodeByteArray(preferred, 0, preferred.length, mOptions); - if (mOptions.inBitmap != null && b != mOptions.inBitmap) { - sBitmapPool.put(mOptions.inBitmap); - mOptions.inBitmap = null; - } - } - if (b == null) { - is = getFallbackImageStream(data); - mOptions.inSampleSize = sampleSize; - mOptions.inBitmap = sBitmapPool.get(width / sampleSize, height / sampleSize); - b = BitmapFactory.decodeStream(is, null, mOptions); - if (mOptions.inBitmap != null && b != mOptions.inBitmap) { - sBitmapPool.put(mOptions.inBitmap); - mOptions.inBitmap = null; - } - } - } catch (Exception e) { - Log.d(TAG, "Failed to fetch bitmap", e); - return; - } finally { - try { - if (is != null) { - is.close(); - } - } catch (Exception e) {} - if (b != null) { - synchronized (mLock) { - if (!dataChangedLocked(data)) { - setBitmapLocked(b); - scheduleSelf(mUpdateBitmap, 0); - } - } - } - } - } - }; - - private final Runnable mUpdateBitmap = new Runnable() { - @Override - public void run() { - synchronized (AutoThumbnailDrawable.this) { - updateDrawMatrixLocked(); - invalidateSelf(); - } - } - }; - -} |