package com.koushikdutta.ion;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.util.Log;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.async.http.ResponseCacheMiddleware;
import com.koushikdutta.async.http.libcore.DiskLruCache;
import com.koushikdutta.ion.bitmap.BitmapInfo;
import com.koushikdutta.ion.bitmap.Transform;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
class TransformBitmap extends BitmapCallback implements FutureCallback<BitmapInfo> {
ArrayList<Transform> transforms;
public static void getBitmapSnapshot(final Ion ion, final String transformKey) {
// don't do this if this is already loading
if (ion.bitmapsPending.tag(transformKey) != null)
return;
final BitmapCallback callback = new LoadBitmapBase(ion, transformKey, true);
Ion.getBitmapLoadExecutorService().execute(new Runnable() {
@Override
public void run() {
if (ion.bitmapsPending.tag(transformKey) != callback) {
// Log.d("IonBitmapLoader", "Bitmap cache load cancelled (no longer needed)");
return;
}
try {
File file = ion.responseCache.getDiskLruCache().getFile(transformKey, 0);
Bitmap bitmap = ion.getBitmapCache().loadBitmap(file, null);
if (bitmap == null)
throw new Exception("Bitmap failed to load");
Point size = new Point(bitmap.getWidth(), bitmap.getHeight());
BitmapInfo info = new BitmapInfo(transformKey, "image/jpeg", new Bitmap[] { bitmap }, size);
info.loadedFrom = Loader.LoaderEmitter.LOADED_FROM_CACHE;
callback.report(null, info);
}
catch (OutOfMemoryError e) {
callback.report(new Exception(e), null);
}
catch (Exception e) {
callback.report(e, null);
try {
ion.responseCache.getDiskLruCache().remove(transformKey);
} catch (Exception ex) {
}
}
}
});
}
String downloadKey;
public TransformBitmap(Ion ion, String transformKey, String downloadKey, ArrayList<Transform> transforms) {
super(ion, transformKey, true);
this.transforms = transforms;
this.downloadKey = downloadKey;
}
@Override
public void onCompleted(Exception e, final BitmapInfo result) {
if (e != null) {
report(e, null);
return;
}
if (ion.bitmapsPending.tag(key) != this) {
// Log.d("IonBitmapLoader", "Bitmap transform cancelled (no longer needed)");
return;
}
Ion.getBitmapLoadExecutorService().execute(new Runnable() {
@Override
public void run() {
if (ion.bitmapsPending.tag(key) != TransformBitmap.this) {
// Log.d("IonBitmapLoader", "Bitmap transform cancelled (no longer needed)");
return;
}
BitmapInfo info;
try {
Point size = null;
Bitmap bitmaps[] = new Bitmap[result.bitmaps.length];
for (int i = 0; i < result.bitmaps.length; i++) {
for (Transform transform : transforms) {
Bitmap bitmap = transform.transform(result.bitmaps[i]);
if (bitmap == null)
throw new Exception("failed to transform bitmap");
bitmaps[i] = bitmap;
if (size == null)
size = new Point(bitmap.getWidth(), bitmap.getHeight());
}
}
info = new BitmapInfo(key, result.mimeType, bitmaps, size);
info.delays = result.delays;
info.loadedFrom = result.loadedFrom;
report(null, info);
}
catch (OutOfMemoryError e) {
report(new Exception(e), null);
return;
}
catch (Exception e) {
report(e, null);
return;
}
// the transformed bitmap was successfully load it, let's toss it into
// the disk lru cache.
// but don't persist gifs...
if (info.bitmaps.length > 1)
return;
try {
DiskLruCache cache = ion.responseCache.getDiskLruCache();
if (cache == null)
return;
DiskLruCache.Editor editor = cache.edit(key);
if (editor == null)
return;
try {
for (int i = 1; i < ResponseCacheMiddleware.ENTRY_COUNT; i++) {
editor.set(i, key);
}
OutputStream out = editor.newOutputStream(0);
Bitmap.CompressFormat format = info.bitmaps[0].hasAlpha() ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG;
info.bitmaps[0].compress(format, 100, out);
out.close();
editor.commit();
} catch (Exception ex) {
editor.abort();
}
}
catch (Exception e) {
}
}
});
}
}