Bitmap: implement decodeStream, getPixels and recycle

This commit is contained in:
Julian Winkler
2023-06-18 11:09:52 +02:00
parent 0454dcbfd5
commit 58ec3733d3
5 changed files with 41 additions and 13 deletions

View File

@@ -26,3 +26,29 @@ JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getHeight(JNIEnv *env, jobje
return gdk_pixbuf_get_height(pixbuf); return gdk_pixbuf_get_height(pixbuf);
} }
JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels(JNIEnv *env, jclass, jlong bitmapHandle, jintArray pixelArray, jint offset, jint stride, jint x, jint y, jint width, jint height, jboolean premultiplied) {
int i,j;
GdkPixbuf *pixbuf = _PTR(bitmapHandle);
g_assert(gdk_pixbuf_get_n_channels(pixbuf) == 4);
g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB);
jint *dst = (*env)->GetIntArrayElements(env, pixelArray, NULL);
jint *d = dst + offset;
const guint8 *src = gdk_pixbuf_read_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
src += y * rowstride + x;
for (i=0; i<height; i++) {
for (j=0; j<width; j++) {
d[j] = src[4*j+3] << 24 | src[4*j+0] << 16 | src[4*j+1] << 8 | src[4*j+2];
}
d += stride;
src += rowstride;
}
(*env)->ReleaseIntArrayElements(env, pixelArray, dst, 0);
}
JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle(JNIEnv *env, jclass, jlong bitmapHandle) {
GdkPixbuf *pixbuf = _PTR(bitmapHandle);
g_object_unref(pixbuf);
return true;
}

View File

@@ -54,10 +54,10 @@ JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeDestructor
/* /*
* Class: android_graphics_Bitmap * Class: android_graphics_Bitmap
* Method: nativeRecycle * Method: nativeRecycle
* Signature: (I)Z * Signature: (J)Z
*/ */
JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle JNIEXPORT jboolean JNICALL Java_android_graphics_Bitmap_nativeRecycle
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jlong);
/* /*
* Class: android_graphics_Bitmap * Class: android_graphics_Bitmap
@@ -110,10 +110,10 @@ JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_nativeGetPixel
/* /*
* Class: android_graphics_Bitmap * Class: android_graphics_Bitmap
* Method: nativeGetPixels * Method: nativeGetPixels
* Signature: (I[IIIIIIIZ)V * Signature: (J[IIIIIIIZ)V
*/ */
JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels JNIEXPORT void JNICALL Java_android_graphics_Bitmap_nativeGetPixels
(JNIEnv *, jclass, jint, jintArray, jint, jint, jint, jint, jint, jint, jboolean); (JNIEnv *, jclass, jlong, jintArray, jint, jint, jint, jint, jint, jint, jboolean);
/* /*
* Class: android_graphics_Bitmap * Class: android_graphics_Bitmap

View File

@@ -319,7 +319,7 @@ public final class AssetManager {
} }
asset = openAsset(fileName, accessMode); asset = openAsset(fileName, accessMode);
if (asset >= 0) { if (asset >= 0) {
AssetInputStream res = new AssetInputStream(asset); AssetInputStream res = new AssetInputStream(asset, "/assets/" + fileName);
incRefsLocked(res.hashCode()); incRefsLocked(res.hashCode());
return res; return res;
} }
@@ -413,7 +413,7 @@ public final class AssetManager {
} }
asset = openNonAssetNative(cookie, fileName, accessMode); asset = openNonAssetNative(cookie, fileName, accessMode);
if (asset >= 0) { if (asset >= 0) {
AssetInputStream res = new AssetInputStream(asset); AssetInputStream res = new AssetInputStream(asset, fileName);
incRefsLocked(res.hashCode()); incRefsLocked(res.hashCode());
return res; return res;
} }
@@ -554,10 +554,11 @@ public final class AssetManager {
public final int getAssetInt() { public final int getAssetInt() {
return mAsset; return mAsset;
} }
private AssetInputStream(int asset) private AssetInputStream(int asset, String fileName)
{ {
mAsset = asset; mAsset = asset;
mLength = getAssetLength(asset); mLength = getAssetLength(asset);
this.fileName = fileName;
} }
public final int read() throws IOException { public final int read() throws IOException {
return readAssetChar(mAsset); return readAssetChar(mAsset);
@@ -609,6 +610,7 @@ public final class AssetManager {
private int mAsset; private int mAsset;
private long mLength; private long mLength;
private long mMarkPos; private long mMarkPos;
public String fileName;
} }
/** /**

View File

@@ -334,7 +334,7 @@ public final class Bitmap {
*/ */
public void recycle() { public void recycle() {
if (!mRecycled) { if (!mRecycled) {
if (nativeRecycle(mNativeBitmap)) { if (nativeRecycle(pixbuf)) {
// return value indicates whether native pixel object was actually recycled. // return value indicates whether native pixel object was actually recycled.
// false indicates that it is still in use at the native level and these // false indicates that it is still in use at the native level and these
// objects should not be collected now. They will be collected later when the // objects should not be collected now. They will be collected later when the
@@ -1352,7 +1352,7 @@ public final class Bitmap {
return; // nothing to do return; // nothing to do
} }
checkPixelsAccess(x, y, width, height, offset, stride, pixels); checkPixelsAccess(x, y, width, height, offset, stride, pixels);
nativeGetPixels(mNativeBitmap, pixels, offset, stride, nativeGetPixels(pixbuf, pixels, offset, stride,
x, y, width, height, mIsPremultiplied); x, y, width, height, mIsPremultiplied);
} }
@@ -1571,7 +1571,7 @@ public final class Bitmap {
private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig, private static native Bitmap nativeCopy(int srcBitmap, int nativeConfig,
boolean isMutable); boolean isMutable);
private static native void nativeDestructor(int nativeBitmap); private static native void nativeDestructor(int nativeBitmap);
private static native boolean nativeRecycle(int nativeBitmap); private static native boolean nativeRecycle(long nativeBitmap);
private static native void nativeReconfigure(int nativeBitmap, int width, int height, private static native void nativeReconfigure(int nativeBitmap, int width, int height,
int config, int allocSize); int config, int allocSize);
@@ -1584,7 +1584,7 @@ public final class Bitmap {
private static native int nativeGetPixel(int nativeBitmap, int x, int y, private static native int nativeGetPixel(int nativeBitmap, int x, int y,
boolean isPremultiplied); boolean isPremultiplied);
private static native void nativeGetPixels(int nativeBitmap, int[] pixels, private static native void nativeGetPixels(long nativeBitmap, int[] pixels,
int offset, int stride, int x, int y, int offset, int stride, int x, int y,
int width, int height, boolean isPremultiplied); int width, int height, boolean isPremultiplied);

View File

@@ -567,8 +567,8 @@ public class BitmapFactory {
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap"); Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
try { try {
if (is instanceof AssetManager.AssetInputStream) { if (is instanceof AssetManager.AssetInputStream) {
final int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); final String fileName = ((AssetManager.AssetInputStream) is).fileName;
bm = nativeDecodeAsset(asset, outPadding, opts); bm = new Bitmap(fileName);
} else { } else {
bm = decodeStreamInternal(is, outPadding, opts); bm = decodeStreamInternal(is, outPadding, opts);
} }