2022-10-02 23:06:56 +02:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
|
|
|
|
#include "defines.h"
|
|
|
|
|
#include "util.h"
|
|
|
|
|
|
2023-08-28 20:03:32 +02:00
|
|
|
#include "../sk_area/include/c/sk_data.h"
|
|
|
|
|
#include "../sk_area/include/c/sk_image.h"
|
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
#include "generated_headers/android_graphics_Bitmap.h"
|
|
|
|
|
|
2023-08-28 20:03:32 +02:00
|
|
|
/*
|
|
|
|
|
* We use a GdkPixbuf as the backing for a bitmap.
|
|
|
|
|
* We additionally create a view into it as a skia image,
|
|
|
|
|
* so we can pass it to skia functions.
|
|
|
|
|
*/
|
2022-10-02 23:06:56 +02:00
|
|
|
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1bitmap_1from_1path(JNIEnv *env, jobject this, jobject path)
|
|
|
|
|
{
|
|
|
|
|
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(_CSTRING(path), NULL);
|
2023-09-06 17:42:24 +02:00
|
|
|
android_log_printf(ANDROID_LOG_VERBOSE, "["__FILE__"]", ">>> made pixbuf from path: >%s<, >%p<\n", _CSTRING(path), pixbuf);
|
2023-08-28 20:03:32 +02:00
|
|
|
|
|
|
|
|
sk_imageinfo_t info = {
|
|
|
|
|
.width = gdk_pixbuf_get_width(pixbuf),
|
|
|
|
|
.height = gdk_pixbuf_get_height(pixbuf),
|
|
|
|
|
.colorType = RGBA_8888_SK_COLORTYPE, // is this correct?
|
|
|
|
|
.alphaType = PREMUL_SK_ALPHATYPE,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void *pixbuf_pixels = gdk_pixbuf_get_pixels(pixbuf);
|
|
|
|
|
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
|
|
|
|
|
size_t pixbuf_size = rowstride * (info.height - 1)
|
|
|
|
|
+ /* last row: */ info.width * ((gdk_pixbuf_get_n_channels(pixbuf) * gdk_pixbuf_get_bits_per_sample(pixbuf) + 7) / 8);
|
|
|
|
|
/* use the data as-is, and don't ever free it because the pixbuf owns it */
|
|
|
|
|
sk_data_t *pixels = sk_data_new_with_proc(pixbuf_pixels, pixbuf_size, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
sk_image_t *image = sk_image_new_raster_data(&info, pixels, rowstride);
|
|
|
|
|
g_object_set_data(G_OBJECT(pixbuf), "sk_image", image);
|
|
|
|
|
|
2022-10-02 23:06:56 +02:00
|
|
|
g_object_ref(pixbuf);
|
|
|
|
|
return _INTPTR(pixbuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getWidth(JNIEnv *env, jobject this)
|
|
|
|
|
{
|
|
|
|
|
GdkPixbuf *pixbuf = _PTR(_GET_LONG_FIELD(this, "pixbuf"));
|
2024-02-03 23:40:20 +01:00
|
|
|
if (!pixbuf) {
|
|
|
|
|
return 10;
|
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
|
|
|
|
return gdk_pixbuf_get_width(pixbuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_getHeight(JNIEnv *env, jobject this)
|
|
|
|
|
{
|
|
|
|
|
GdkPixbuf *pixbuf = _PTR(_GET_LONG_FIELD(this, "pixbuf"));
|
2024-02-03 23:40:20 +01:00
|
|
|
if (!pixbuf) {
|
|
|
|
|
return 10;
|
|
|
|
|
}
|
2022-10-02 23:06:56 +02:00
|
|
|
|
|
|
|
|
return gdk_pixbuf_get_height(pixbuf);
|
|
|
|
|
}
|
2023-06-18 11:09:52 +02:00
|
|
|
|
|
|
|
|
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);
|
2023-08-28 20:03:32 +02:00
|
|
|
sk_image_t *image = g_object_get_data(G_OBJECT(pixbuf), "sk_image");
|
|
|
|
|
if(!image) {
|
|
|
|
|
fprintf(stderr, "pixbuf doesn't have a skia image associated: %p\n", pixbuf);
|
|
|
|
|
g_object_unref(pixbuf);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
sk_image_unref(image);
|
2023-06-18 11:09:52 +02:00
|
|
|
g_object_unref(pixbuf);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2023-09-01 13:09:04 +02:00
|
|
|
|
|
|
|
|
JNIEXPORT jlong JNICALL Java_android_graphics_Bitmap_native_1copy(JNIEnv *env, jclass, jlong src_ptr) {
|
|
|
|
|
GdkPixbuf *src = _PTR(src_ptr);
|
|
|
|
|
GdkPixbuf *copy = gdk_pixbuf_copy(src);
|
|
|
|
|
return _INTPTR(copy);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JNIEXPORT jint JNICALL Java_android_graphics_Bitmap_nativeRowBytes(JNIEnv *env, jclass, jlong pixbuf_ptr) {
|
|
|
|
|
GdkPixbuf *pixbuf = _PTR(pixbuf_ptr);
|
|
|
|
|
|
|
|
|
|
return gdk_pixbuf_get_rowstride(pixbuf);
|
|
|
|
|
}
|