diff options
author | Likai Ding <likaid@codeaurora.org> | 2013-08-13 14:07:48 +0800 |
---|---|---|
committer | Xiaojing Zhang <zhangx@codeaurora.org> | 2014-11-04 20:37:39 -0800 |
commit | dcba1c2fbf5eb71b688810434a20298ef8202339 (patch) | |
tree | 42a708baaeb9e59ad9cc7eb1178d76bd6658868a /src/com/android/gallery3d | |
parent | ecd9d2b60c89b32e0e7d99e33a89198e6a790ad2 (diff) | |
download | android_packages_apps_Gallery2-dcba1c2fbf5eb71b688810434a20298ef8202339.tar.gz android_packages_apps_Gallery2-dcba1c2fbf5eb71b688810434a20298ef8202339.tar.bz2 android_packages_apps_Gallery2-dcba1c2fbf5eb71b688810434a20298ef8202339.zip |
Gallery2: support GIF animation
(cherry picked new files from commit
2b133c9747af26701a12d60caef3e7e14cf55536)
Change-Id: I227cef76cbacd66b7e87bc59b4f07d518b70a859
Signed-off-by: Xiaojing Zhang <zhangx@codeaurora.org>
Diffstat (limited to 'src/com/android/gallery3d')
-rwxr-xr-x | src/com/android/gallery3d/util/GIFView.java | 300 | ||||
-rwxr-xr-x | src/com/android/gallery3d/util/GifAction.java | 5 | ||||
-rwxr-xr-x | src/com/android/gallery3d/util/GifDecoder.java | 697 | ||||
-rwxr-xr-x | src/com/android/gallery3d/util/GifFrame.java | 14 | ||||
-rwxr-xr-x | src/com/android/gallery3d/util/ViewGifImage.java | 111 |
5 files changed, 1127 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/util/GIFView.java b/src/com/android/gallery3d/util/GIFView.java new file mode 100755 index 000000000..0e71aa314 --- /dev/null +++ b/src/com/android/gallery3d/util/GIFView.java @@ -0,0 +1,300 @@ +package com.android.gallery3d.util; + +import java.io.InputStream; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.net.Uri; +import android.content.res.AssetManager; +import java.io.FileNotFoundException; +import java.io.IOException; +import android.database.Cursor; +import android.widget.ImageView; +import java.io.FileInputStream; + +import com.android.gallery3d.R; + +import android.content.ContentResolver; +import android.widget.Toast; + +public class GIFView extends ImageView implements GifAction{ + + private static final String TAG = "GIFView"; + + private GifDecoder gifDecoder = null; + + private Bitmap currentImage = null; + + private static boolean isRun = false; + + private static boolean pause = true; + + private int W; + + private int H; + + private DrawThread drawThread = null; + + Uri mUri; + private Context mContext; + + public GIFView(Context context) { + super(context); + mContext=context; + + } + + public boolean setDrawable(Uri uri){ + if (null == uri){ + return false; + } + isRun = true; + pause = false; + mUri = uri; + int mSize = 0; + ContentResolver cr = mContext.getContentResolver(); + InputStream input = null; + try { + input = cr.openInputStream(uri); + + if (input instanceof FileInputStream) { + FileInputStream f = (FileInputStream) input; + mSize = (int) f.getChannel().size(); + } else { + while (-1 != input.read()) { + mSize++; + } + } + + } catch (IOException e) { + + } finally { + + } + //wss , return if file is invalid + if(mSize == 0){ + return false; + } + + if(mSize > 1024*1024){ //gif must be smaller than 1MB + if (null != input) { + try { + input.close(); + } catch (IOException e) { + } + } + Toast.makeText(mContext, R.string.gif_image_too_large, Toast.LENGTH_LONG).show(); + return false; + } + + setGifDecoderImage(input); + + + + android.content.ContentResolver resolver = mContext.getContentResolver(); + Cursor c = resolver.query(uri, new String[]{"_data"}, null, null, null); + +// if ( c != null && 1 == c.getCount()){ +// c.moveToFirst(); +// +// AssetManager am = mContext.getAssets(); +// try{ +// System.out.println(">>>>>>>>>1 "+c.getString(0)); +// setGifDecoderImage(am.open(c.getString(0), AssetManager.ACCESS_RANDOM)); +// }catch(FileNotFoundException e){ +// Log.v(TAG, "e:" + e); +// }catch(IOException e){ +// Log.v(TAG, "e:" + e); +// }finally{ +// c.close(); +// } +// +// return true; +// } +// else{ +// AssetManager am1 = mContext.getAssets(); +// try { +// System.out.println(">>>>>>>>2 "+mUri.getPath()); +// setGifDecoderImage(am1.open(mUri.getPath(), AssetManager.ACCESS_UNKNOWN)); +// } catch (IOException e1) { +// e1.printStackTrace(); +// } +// return true; +// } + return true; + } + + private void setGifDecoderImage(InputStream is){ + if(gifDecoder != null){ + gifDecoder.free(); + gifDecoder= null; + } + gifDecoder = new GifDecoder(is,this); + gifDecoder.start(); + } + + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + //wangmiao add + W = ViewGifImage.dm.widthPixels;//480; + H = ViewGifImage.dm.heightPixels;//800; + //Log.w(TAG,"the width is "+W +"the hight is "+H); + if(gifDecoder == null){ + return; + } + + if(currentImage == null){ + currentImage = gifDecoder.getImage(); + } + if(currentImage == null){ + setImageURI(mUri); // if can not play this gif, we just try to show it as jpg by parsing mUri, bug: T81-4307 + return; + } + setImageURI(null); + int saveCount = canvas.getSaveCount(); + canvas.save(); + canvas.translate(getPaddingLeft(), getPaddingTop()); + //canvas.drawBitmap(currentImage, (W - currentImage.getWidth()) / 2, (H - currentImage.getHeight())/2, null); + Rect sRect = null; + Rect dRect = null; + + int imageHeight = currentImage.getHeight(); + int imageWidth = currentImage.getWidth(); + + //int newHeight = H/2; + int newHeight = H; + int newWidth = W; + + if (newWidth < imageWidth) + { + if (newHeight < imageHeight) + { + //h big, w big; + //Log.w(TAG," h big, w big"); + if (imageHeight*W > imageWidth*H) + { + //too height + //newHeight = H/2; + newWidth = (imageWidth * newHeight)/imageHeight; + //Log.w(TAG," h too big = "+ newHeight+" w big = "+newWidth); + } + else + { + //newWidth = W; + newHeight = (imageHeight * newWidth)/imageWidth; + //Log.w(TAG," h big = "+ newHeight+" w too big = "+newWidth); + } + + //sRect = new Rect(0, 0, currentImage.getWidth(), currentImage.getHeight()); + dRect = new Rect((W - newWidth) / 2, 0, (W + newWidth) / 2, newHeight); + } + else + { + //h small, w big; + newHeight = (imageHeight * newWidth)/imageWidth; + dRect = new Rect(0, 0, newWidth, newHeight); + } + canvas.drawBitmap(currentImage, sRect, dRect, null); + + } + else if (newHeight < imageHeight) + { + //h big, w small; + newWidth = (imageWidth * newHeight)/imageHeight; + dRect = new Rect((W - newWidth) / 2, 0, + (W + newWidth) / 2, newHeight); + canvas.drawBitmap(currentImage, sRect, dRect, null); + } + else + { + //h small, w small; + canvas.drawBitmap(currentImage, (W - imageWidth) / 2, (H - imageHeight) / 2, null); + } + + canvas.restoreToCount(saveCount); + } + + public void parseOk(boolean parseStatus,int frameIndex){ + if(parseStatus){ + if(gifDecoder != null){ + if(frameIndex == -1){ + if(gifDecoder.getFrameCount() > 1){ + if(drawThread == null){ + drawThread = new DrawThread(); + } else{ + drawThread = null; + drawThread = new DrawThread(); + } + drawThread.start(); + } + } + } + }else{ + Log.e("gif","parse error"); + } + } + + private Handler redrawHandler = new Handler(){ + public void handleMessage(Message msg) { + invalidate(); + } + }; + + private class DrawThread extends Thread{ + public void run(){ + if(gifDecoder == null){ + return; + } + + while(isRun){ + if(pause == false){ + if(!isShown()){ + isRun = false; + pause = true; + break; + } + GifFrame frame = gifDecoder.next(); + currentImage = frame.image; + long sp = frame.delay; + if(sp == 0) sp = 200; //wangmiao add merge from T92 + if(redrawHandler != null){ + Message msg = redrawHandler.obtainMessage(); + redrawHandler.sendMessage(msg); + try{ + Thread.sleep(sp); + } catch(InterruptedException e){} + }else{ + break; + } + } else{ + break; + } + } + isRun = true; + pause = false; + } + } + public void freeMemory() + { + isRun = false; + pause = true; + if (drawThread != null) + { + //drawThread.isStop = true; + drawThread = null; + } + if (gifDecoder != null) + { + Log.w(TAG," free"); + gifDecoder.free(); + gifDecoder = null; + } + } +} + + + diff --git a/src/com/android/gallery3d/util/GifAction.java b/src/com/android/gallery3d/util/GifAction.java new file mode 100755 index 000000000..b273a1768 --- /dev/null +++ b/src/com/android/gallery3d/util/GifAction.java @@ -0,0 +1,5 @@ +package com.android.gallery3d.util; + +public interface GifAction { + public void parseOk(boolean parseStatus,int frameIndex); +} diff --git a/src/com/android/gallery3d/util/GifDecoder.java b/src/com/android/gallery3d/util/GifDecoder.java new file mode 100755 index 000000000..60bc1980b --- /dev/null +++ b/src/com/android/gallery3d/util/GifDecoder.java @@ -0,0 +1,697 @@ +package com.android.gallery3d.util; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; + +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.util.Log; + +public class GifDecoder extends Thread{ + + public static final int STATUS_PARSING = 0; + public static final int STATUS_FORMAT_ERROR = 1; + public static final int STATUS_OPEN_ERROR = 2; + public static final int STATUS_FINISH = -1; + + private InputStream in; + private int status; + + public int width; // full image width + public int height; // full image height + private boolean gctFlag; // global color table used + private int gctSize; // size of global color table + private int loopCount = 1; // iterations; 0 = repeat forever + + private int[] gct; // global color table + private int[] lct; // local color table + private int[] act; // active color table + + private int bgIndex; // background color index + private int bgColor; // background color + private int lastBgColor; // previous bg color + private int pixelAspect; // pixel aspect ratio + + private boolean lctFlag; // local color table flag + private boolean interlace; // interlace flag + private int lctSize; // local color table size + + private int ix, iy, iw, ih; // current image rectangle + private int lrx, lry, lrw, lrh; + private Bitmap image; // current frame + private Bitmap lastImage; // previous frame + private GifFrame currentFrame = null; + + private boolean isShow = false; + + + private byte[] block = new byte[256]; // current data block + private int blockSize = 0; // block size + private int dispose = 0; + private int lastDispose = 0; + private boolean transparency = false; // use transparent color + private int delay = 0; // delay in milliseconds + private int transIndex; // transparent color index + + private static final int MaxStackSize = 4096; + // max decoder pixel stack size + + // LZW decoder working arrays + private short[] prefix; + private byte[] suffix; + private byte[] pixelStack; + private byte[] pixels; + + private GifFrame gifFrame; // frames read from current file + private int frameCount; + + private GifAction action = null; + + + private byte[] gifData = null; + + + public GifDecoder(byte[] data,GifAction act){ + gifData = data; + action = act; + } + + public GifDecoder(InputStream is,GifAction act){ + in = is; + action = act; + } + + public void run(){ + if(in != null){ + readStream(); + }else if(gifData != null){ + readByte(); + } + } + + public void free(){ + GifFrame fg = gifFrame; + while(fg != null){ + if (fg.image != null) { + fg.image.recycle(); + } + fg.image = null; + fg = null; + gifFrame = gifFrame.nextFrame; + fg = gifFrame; + } + if(in != null){ + try{ + in.close(); + }catch(Exception ex){} + in = null; + } + gifData = null; + if (image != null) + { + image.recycle(); + image = null; + } + if (lastImage != null) + { + lastImage.recycle(); + lastImage = null; + } + } + + public int getStatus(){ + return status; + } + + public boolean parseOk(){ + return status == STATUS_FINISH; + } + + public int getDelay(int n) { + delay = -1; + if ((n >= 0) && (n < frameCount)) { + GifFrame f = getFrame(n); + if (f != null) + delay = f.delay; + } + return delay; + } + + public int[] getDelays(){ + GifFrame f = gifFrame; + int[] d = new int[frameCount]; + int i = 0; + while(f != null && i < frameCount){ + d[i] = f.delay; + f = f.nextFrame; + i++; + } + return d; + } + + public int getFrameCount() { + return frameCount; + } + + public Bitmap getImage() { + return getFrameImage(0); + } + + public int getLoopCount() { + return loopCount; + } + + private void setPixels() { + int[] dest = new int[width * height]; + // fill in starting image contents based on last image's dispose code + if (lastDispose > 0) { + if (lastDispose == 3) { + // use image before last + int n = frameCount - 2; + if (n > 0) { + lastImage = getFrameImage(n - 1); + } else { + lastImage = null; + } + } + if (lastImage != null) { + lastImage.getPixels(dest, 0, width, 0, 0, width, height); + // copy pixels + if (lastDispose == 2) { + // fill last image rect area with background color + int c = 0; + if (!transparency) { + c = lastBgColor; + } + for (int i = 0; i < lrh; i++) { + int n1 = (lry + i) * width + lrx; + int n2 = n1 + lrw; + for (int k = n1; k < n2; k++) { + dest[k] = c; + } + } + } + } + } + + // copy each source line to the appropriate place in the destination + int pass = 1; + int inc = 8; + int iline = 0; + for (int i = 0; i < ih; i++) { + int line = i; + if (interlace) { + if (iline >= ih) { + pass++; + switch (pass) { + case 2: + iline = 4; + break; + case 3: + iline = 2; + inc = 4; + break; + case 4: + iline = 1; + inc = 2; + } + } + line = iline; + iline += inc; + } + line += iy; + if (line < height) { + int k = line * width; + int dx = k + ix; // start of line in dest + int dlim = dx + iw; // end of dest line + if ((k + width) < dlim) { + dlim = k + width; // past dest edge + } + int sx = i * iw; // start of line in source + while (dx < dlim) { + // map color and insert in destination + int index = ((int) pixels[sx++]) & 0xff; + int c = act[index]; + if (c != 0) { + dest[dx] = c; + } + dx++; + } + } + } + image = Bitmap.createBitmap(dest, width, height, Config.ARGB_4444); + } + + public Bitmap getFrameImage(int n) { + GifFrame frame = getFrame(n); + if (frame == null) + return null; + else + return frame.image; + } + + public GifFrame getCurrentFrame(){ + return currentFrame; + } + + public GifFrame getFrame(int n) { + GifFrame frame = gifFrame; + int i = 0; + while (frame != null) { + if (i == n) { + return frame; + } else { + frame = frame.nextFrame; + } + i++; + } + return null; + } + + public void reset(){ + currentFrame = gifFrame; + } + + public GifFrame next() { + if(isShow == false){ + isShow = true; + return gifFrame; + }else{ + if(status == STATUS_PARSING){ + if(currentFrame.nextFrame != null) + currentFrame = currentFrame.nextFrame; + //currentFrame = gifFrame; + }else{ + currentFrame = currentFrame.nextFrame; + if (currentFrame == null) { + currentFrame = gifFrame; + } + } + return currentFrame; + } + } + + private int readByte(){ + in = new ByteArrayInputStream(gifData); + gifData = null; + return readStream(); + } + + private int readStream(){ + init(); + if(in != null){ + readHeader(); + if(!err()){ + readContents(); + if(frameCount < 0){ + status = STATUS_FORMAT_ERROR; + action.parseOk(false,-1); + }else{ + status = STATUS_FINISH; + action.parseOk(true,-1); + } + } + try { + in.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + }else { + status = STATUS_OPEN_ERROR; + action.parseOk(false,-1); + } + return status; + } + + private void decodeImageData() { + int NullCode = -1; + int npix = iw * ih; + int available, clear, code_mask, code_size, end_of_information, in_code, old_code, bits, code, count, i, datum, data_size, first, top, bi, pi; + + if ((pixels == null) || (pixels.length < npix)) { + pixels = new byte[npix]; // allocate new pixel array + } + if (prefix == null) { + prefix = new short[MaxStackSize]; + } + if (suffix == null) { + suffix = new byte[MaxStackSize]; + } + if (pixelStack == null) { + pixelStack = new byte[MaxStackSize + 1]; + } + // Initialize GIF data stream decoder. + data_size = read(); + clear = 1 << data_size; + end_of_information = clear + 1; + available = clear + 2; + old_code = NullCode; + code_size = data_size + 1; + code_mask = (1 << code_size) - 1; + for (code = 0; code < clear; code++) { + prefix[code] = 0; + suffix[code] = (byte) code; + } + + // Decode GIF pixel stream. + datum = bits = count = first = top = pi = bi = 0; + for (i = 0; i < npix;) { + if (top == 0) { + if (bits < code_size) { + // Load bytes until there are enough bits for a code. + if (count == 0) { + // Read a new data block. + count = readBlock(); + if (count <= 0) { + break; + } + bi = 0; + } + datum += (((int) block[bi]) & 0xff) << bits; + bits += 8; + bi++; + count--; + continue; + } + // Get the next code. + code = datum & code_mask; + datum >>= code_size; + bits -= code_size; + + // Interpret the code + if ((code > available) || (code == end_of_information)) { + break; + } + if (code == clear) { + // Reset decoder. + code_size = data_size + 1; + code_mask = (1 << code_size) - 1; + available = clear + 2; + old_code = NullCode; + continue; + } + if (old_code == NullCode) { + pixelStack[top++] = suffix[code]; + old_code = code; + first = code; + continue; + } + in_code = code; + if (code == available) { + pixelStack[top++] = (byte) first; + code = old_code; + } + while (code > clear) { + pixelStack[top++] = suffix[code]; + code = prefix[code]; + } + first = ((int) suffix[code]) & 0xff; + // Add a new string to the string table, + if (available >= MaxStackSize) { + break; + } + pixelStack[top++] = (byte) first; + prefix[available] = (short) old_code; + suffix[available] = (byte) first; + available++; + if (((available & code_mask) == 0) + && (available < MaxStackSize)) { + code_size++; + code_mask += available; + } + old_code = in_code; + } + + // Pop a pixel off the pixel stack. + top--; + pixels[pi++] = pixelStack[top]; + i++; + } + for (i = pi; i < npix; i++) { + pixels[i] = 0; // clear missing pixels + } + } + + private boolean err() { + return status != STATUS_PARSING; + } + + private void init() { + status = STATUS_PARSING; + frameCount = 0; + gifFrame = null; + gct = null; + lct = null; + } + + private int read() { + int curByte = 0; + try { + + curByte = in.read(); + } catch (Exception e) { + status = STATUS_FORMAT_ERROR; + } + return curByte; + } + + private int readBlock() { + blockSize = read(); + int n = 0; + if (blockSize > 0) { + try { + int count = 0; + while (n < blockSize) { + count = in.read(block, n, blockSize - n); + if (count == -1) { + break; + } + n += count; + } + } catch (Exception e) { + e.printStackTrace(); + } + if (n < blockSize) { + status = STATUS_FORMAT_ERROR; + } + } + return n; + } + + private int[] readColorTable(int ncolors) { + int nbytes = 3 * ncolors; + int[] tab = null; + byte[] c = new byte[nbytes]; + int n = 0; + try { + n = in.read(c); + } catch (Exception e) { + e.printStackTrace(); + } + if (n < nbytes) { + status = STATUS_FORMAT_ERROR; + } else { + tab = new int[256]; // max size to avoid bounds checks + int i = 0; + int j = 0; + while (i < ncolors) { + int r = ((int) c[j++]) & 0xff; + int g = ((int) c[j++]) & 0xff; + int b = ((int) c[j++]) & 0xff; + tab[i++] = 0xff000000 | (r << 16) | (g << 8) | b; + } + } + return tab; + } + + private void readContents() { + // read GIF file content blocks + boolean done = false; + while (!(done || err())) { + int code = read(); + switch (code) { + case 0x2C: // image separator + readImage(); + break; + case 0x21: // extension + code = read(); + switch (code) { + case 0xf9: // graphics control extension + readGraphicControlExt(); + break; + case 0xff: // application extension + readBlock(); + String app = ""; + for (int i = 0; i < 11; i++) { + app += (char) block[i]; + } + if (app.equals("NETSCAPE2.0")) { + readNetscapeExt(); + } else { + skip(); // don't care + } + break; + default: // uninteresting extension + skip(); + } + break; + case 0x3b: // terminator + done = true; + break; + case 0x00: // bad byte, but keep going and see what happens + break; + default: + status = STATUS_FORMAT_ERROR; + } + } + } + + private void readGraphicControlExt() { + read(); // block size + int packed = read(); // packed fields + dispose = (packed & 0x1c) >> 2; // disposal method + if (dispose == 0) { + dispose = 1; // elect to keep old image if discretionary + } + transparency = (packed & 1) != 0; + delay = readShort() * 10; // delay in milliseconds + transIndex = read(); // transparent color index + read(); // block terminator + } + + private void readHeader() { + String id = ""; + for (int i = 0; i < 6; i++) { + id += (char) read(); + } + if (!id.startsWith("GIF")) { + status = STATUS_FORMAT_ERROR; + return; + } + readLSD(); + if (gctFlag && !err()) { + gct = readColorTable(gctSize); + bgColor = gct[bgIndex]; + } + } + + private void readImage() { + ix = readShort(); // (sub)image position & size + iy = readShort(); + iw = readShort(); + ih = readShort(); + int packed = read(); + lctFlag = (packed & 0x80) != 0; // 1 - local color table flag + interlace = (packed & 0x40) != 0; // 2 - interlace flag + // 3 - sort flag + // 4-5 - reserved + lctSize = 2 << (packed & 7); // 6-8 - local color table size + if (lctFlag) { + lct = readColorTable(lctSize); // read table + act = lct; // make local table active + } else { + act = gct; // make global table active + if (bgIndex == transIndex) { + bgColor = 0; + } + } + int save = 0; + if (transparency) { + save = act[transIndex]; + act[transIndex] = 0; // set transparent color if specified + } + if (act == null) { + status = STATUS_FORMAT_ERROR; // no color table defined + } + if (err()) { + return; + } + try { + decodeImageData(); // decode pixel data + skip(); + if (err()) { + return; + } + frameCount++; + // create new image to receive frame data + image = Bitmap.createBitmap(width, height, Config.ARGB_4444); + // createImage(width, height); + setPixels(); // transfer pixel data to image + if (gifFrame == null) { + gifFrame = new GifFrame(image, delay); + currentFrame = gifFrame; + } else { + GifFrame f = gifFrame; + while(f.nextFrame != null){ + f = f.nextFrame; + } + f.nextFrame = new GifFrame(image, delay); + } + // frames.addElement(new GifFrame(image, delay)); // add image to frame + // list + if (transparency) { + act[transIndex] = save; + } + resetFrame(); + action.parseOk(true, frameCount); + }catch (OutOfMemoryError e) { + Log.e("GifDecoder", ">>> log : " + e.toString()); + e.printStackTrace(); + } + } + + private void readLSD() { + // logical screen size + width = readShort(); + height = readShort(); + // packed fields + int packed = read(); + gctFlag = (packed & 0x80) != 0; // 1 : global color table flag + // 2-4 : color resolution + // 5 : gct sort flag + gctSize = 2 << (packed & 7); // 6-8 : gct size + bgIndex = read(); // background color index + pixelAspect = read(); // pixel aspect ratio + } + + private void readNetscapeExt() { + do { + readBlock(); + if (block[0] == 1) { + // loop count sub-block + int b1 = ((int) block[1]) & 0xff; + int b2 = ((int) block[2]) & 0xff; + loopCount = (b2 << 8) | b1; + } + } while ((blockSize > 0) && !err()); + } + + private int readShort() { + // read 16-bit value, LSB first + return read() | (read() << 8); + } + + private void resetFrame() { + lastDispose = dispose; + lrx = ix; + lry = iy; + lrw = iw; + lrh = ih; + lastImage = image; + lastBgColor = bgColor; + dispose = 0; + transparency = false; + delay = 0; + lct = null; + } + + /** + * Skips variable length blocks up to and including next zero length block. + */ + private void skip() { + do { + readBlock(); + } while ((blockSize > 0) && !err()); + } +} diff --git a/src/com/android/gallery3d/util/GifFrame.java b/src/com/android/gallery3d/util/GifFrame.java new file mode 100755 index 000000000..926ed57b4 --- /dev/null +++ b/src/com/android/gallery3d/util/GifFrame.java @@ -0,0 +1,14 @@ +package com.android.gallery3d.util; + +import android.graphics.Bitmap; + +public class GifFrame { + public GifFrame(Bitmap im, int del) { + image = im; + delay = del; + } + + public Bitmap image; + public int delay; + public GifFrame nextFrame = null; +} diff --git a/src/com/android/gallery3d/util/ViewGifImage.java b/src/com/android/gallery3d/util/ViewGifImage.java new file mode 100755 index 000000000..b157e2f3b --- /dev/null +++ b/src/com/android/gallery3d/util/ViewGifImage.java @@ -0,0 +1,111 @@ +/** + * File property dialog + * + * @Author wangxuguang + * + * caozhe add this file, for displya gif image, 2011.3.28 + */ + +package com.android.gallery3d.util; + + +import android.app.Activity; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.widget.ImageView; + +import com.android.gallery3d.R; +import android.net.Uri; + +import android.view.ViewGroup.LayoutParams; +import android.widget.LinearLayout; +import android.util.DisplayMetrics; +import android.content.res.Configuration; + +public class ViewGifImage extends Activity +{ + public static final String TAG = "ViewGifImage"; + private String mFileDir; + public static DisplayMetrics dm; + ImageView gifView; + + static final int WIDTH = 320; + static final int HEIGHT = 480; + + + private Handler mHandler = new Handler() { + public void handleMessage(Message msg) + { + super.handleMessage(msg); + } + }; + + @Override + public void onCreate(Bundle savedInstanceState) + { + //android.util.Log.d(TAG, "=== onCreate() ==="); + super.onCreate(savedInstanceState); + setContentView(R.layout.view_gif_image); + dm = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(dm); + //add end + if(getIntent().getAction() != null + && getIntent().getAction().equals("hisense.view_gif_image")){ + // i am called by gallery3D or other apps who want to show a gif image + Uri gifUri = getIntent().getData(); + showGifPicture(gifUri); + + return; + } + + mFileDir = getIntent().getStringExtra("file_dir"); + Uri gifUri = getIntent().getData(); + + + showGifPicture(gifUri); + + + } + + @Override + public void onResume() + { + super.onResume(); + } + + @Override + protected void onStop() + { + super.onStop(); + finish(); + } + + @Override + protected void onDestroy() { + if (gifView != null){ + if (gifView instanceof GIFView) + { + ((GIFView)gifView).freeMemory(); + gifView = null; + } + } + super.onDestroy(); + } + + private void showGifPicture(Uri gifUri){ + gifView = new GIFView(this); + ((LinearLayout)findViewById(R.id.image_absoluteLayout)).addView(gifView, new LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + if(!((GIFView)gifView).setDrawable(gifUri)) + finish(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + getWindowManager().getDefaultDisplay().getMetrics(dm); + super.onConfigurationChanged(newConfig); + } + + +} |