blob: f8e1ec9c0c900ae9f0532f31f09eea0a0cb6002b [file] [log] [blame]
package com.android.gallery3d.util;
import com.android.gallery3d.R;
import android.content.Context;
import android.content.ContentResolver;
import android.content.res.AssetManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.IOException;
public class GIFView extends ImageView implements GifAction {
private static final String TAG = "GIFView";
private static final float SCALE_LIMIT = 4;
private static final long FRAME_DELAY = 200; //milliseconds
private GifDecoder mGifDecoder = null;
private Bitmap mCurrentImage = null;
private DrawThread mDrawThread = null;
private Uri mUri;
private Context mContext;
public GIFView(Context context) {
super(context);
mContext = context;
}
public boolean setDrawable(Uri uri) {
if (null == uri) {
return false;
}
mUri = uri;
InputStream is = getInputStream(uri);
if (is == null || (getFileSize (is) == 0)) {
return false;
}
startDecode(is);
return true;
}
private int getFileSize (InputStream is) {
if(is == null) return 0;
int size = 0;
try {
if (is instanceof FileInputStream) {
FileInputStream f = (FileInputStream) is;
size = (int) f.getChannel().size();
} else {
while (-1 != is.read()) {
size++;
}
}
} catch (IOException e) {
Log.e(TAG, "catch exception:" + e);
}
return size;
}
private InputStream getInputStream (Uri uri) {
ContentResolver cr = mContext.getContentResolver();
InputStream input = null;
try {
input = cr.openInputStream(uri);
} catch (IOException e) {
Log.e(TAG, "catch exception:" + e);
}
return input;
}
private void startDecode(InputStream is) {
freeGifDecoder();
mGifDecoder = new GifDecoder(is, this);
mGifDecoder.start();
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mGifDecoder == null) {
return;
}
if (mCurrentImage == null) {
mCurrentImage = mGifDecoder.getImage();
}
if (mCurrentImage == null) {
// if this gif can not be displayed, just try to show it as jpg by parsing mUri
setImageURI(mUri);
return;
}
setImageURI(null);
int saveCount = canvas.getSaveCount();
canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
Rect sRect = null;
Rect dRect = null;
int imageHeight = mCurrentImage.getHeight();
int imageWidth = mCurrentImage.getWidth();
int displayHeight = ViewGifImage.mDM.heightPixels;
int displayWidth = ViewGifImage.mDM.widthPixels;
int width, height;
if (imageWidth >= displayWidth || imageHeight >= displayHeight) {
// scale-down the image
if (imageWidth * displayHeight > displayWidth * imageHeight) {
width = displayWidth;
height = (imageHeight * width) / imageWidth;
} else {
height = displayHeight;
width = (imageWidth * height) / imageHeight;
}
} else {
// scale-up the image
float scale = Math.min(SCALE_LIMIT, Math.min(displayWidth / (float) imageWidth,
displayHeight / (float) imageHeight));
width = (int) (imageWidth * scale);
height = (int) (imageHeight * scale);
}
dRect = new Rect((displayWidth - width) / 2, (displayHeight - height) / 2,
(displayWidth + width) / 2, (displayHeight + height) / 2);
canvas.drawBitmap(mCurrentImage, sRect, dRect, null);
canvas.restoreToCount(saveCount);
}
public void parseOk(boolean parseStatus, int frameIndex) {
if (parseStatus) {
//indicates the start of a new GIF
if (mGifDecoder != null && frameIndex == -1
&& mGifDecoder.getFrameCount() > 1) {
if (mDrawThread != null) {
mDrawThread = null;
}
mDrawThread = new DrawThread();
mDrawThread.start();
}
} else {
Log.e(TAG, "parse error");
}
}
private Handler mRedrawHandler = new Handler() {
public void handleMessage(Message msg) {
invalidate();
}
};
private class DrawThread extends Thread {
public void run() {
while (true) {
if (mGifDecoder == null || !isShown() || mRedrawHandler == null) {
break;
}
GifFrame frame = mGifDecoder.next();
mCurrentImage = frame.mImage;
Message msg = mRedrawHandler.obtainMessage();
mRedrawHandler.sendMessage(msg);
try {
Thread.sleep(getDelay(frame));
} catch (InterruptedException e) {
Log.e(TAG, "catch exception:" + e);
}
}
}
}
private long getDelay (GifFrame frame) {
//in milliseconds
return frame.mDelayInMs == 0 ? FRAME_DELAY : frame.mDelayInMs;
}
private void freeGifDecoder () {
if (mGifDecoder != null) {
mGifDecoder.free();
mGifDecoder = null;
}
}
public void freeMemory() {
if (mDrawThread != null) {
mDrawThread = null;
}
freeGifDecoder();
}
}