mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-11-29 12:35:53 +01:00
286f7c643f
When this option is enabled all png images will be converted to PNG-8 (8 bit per pixel).
157 lines
6.4 KiB
C
157 lines
6.4 KiB
C
#include "org/pngquant/PngQuant.h"
|
|
#include "org/pngquant/Image.h"
|
|
#include "org/pngquant/Result.h"
|
|
#include "libimagequant.h"
|
|
#include <stdlib.h>
|
|
|
|
typedef struct {
|
|
liq_image *image;
|
|
jbyte *data;
|
|
} liq_jni_image;
|
|
|
|
static void *handle(JNIEnv *env, jobject obj) {
|
|
jlong h = (*env)->GetLongField(env, obj, (*env)->GetFieldID(env, (*env)->GetObjectClass(env, obj), "handle", "J"));
|
|
return (void*)h;
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_org_pngquant_PngQuant_liq_1attr_1create(JNIEnv *env, jclass class) {
|
|
return (jlong)liq_attr_create();
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_org_pngquant_PngQuant_liq_1attr_1copy(JNIEnv *env, jclass class, jlong attr) {
|
|
return (jlong)liq_attr_copy((liq_attr*)attr);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_pngquant_PngQuant_liq_1attr_1destroy(JNIEnv *env, jclass class, jlong attr) {
|
|
return liq_attr_destroy((liq_attr*)attr);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_PngQuant_setMaxColors(JNIEnv *env, jobject obj, jint colors) {
|
|
return LIQ_OK == liq_set_max_colors(handle(env, obj), colors);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_PngQuant_setSpeed(JNIEnv *env, jobject obj, jint speed) {
|
|
return LIQ_OK == liq_set_speed(handle(env, obj), speed);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_PngQuant_setMinPosterization(JNIEnv *env, jobject obj, jint p) {
|
|
return LIQ_OK == liq_set_min_posterization(handle(env, obj), p);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_PngQuant_setQuality__I(JNIEnv *env, jobject obj, jint q) {
|
|
return LIQ_OK == liq_set_quality(handle(env, obj), q/2, q);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_PngQuant_setQuality__II(JNIEnv *env, jobject obj, jint qmin, jint qmax) {
|
|
return LIQ_OK == liq_set_quality(handle(env, obj), qmin, qmax);
|
|
}
|
|
|
|
static void convert_abgr(liq_color row_out[], int row_index, int width, void* user_info) {
|
|
liq_jni_image *jniimg = user_info;
|
|
int column_index;
|
|
for(column_index=0; column_index < width; column_index++) {
|
|
row_out[column_index].r = jniimg->data[4*(width*row_index + column_index) + 3];
|
|
row_out[column_index].g = jniimg->data[4*(width*row_index + column_index) + 2];
|
|
row_out[column_index].b = jniimg->data[4*(width*row_index + column_index) + 1];
|
|
row_out[column_index].a = jniimg->data[4*(width*row_index + column_index) + 0];
|
|
}
|
|
}
|
|
|
|
static void convert_bgr(liq_color row_out[], int row_index, int width, void* user_info) {
|
|
liq_jni_image *jniimg = user_info;
|
|
int column_index;
|
|
for(column_index=0; column_index < width; column_index++) {
|
|
row_out[column_index].r = jniimg->data[3*(width*row_index + column_index) + 2];
|
|
row_out[column_index].g = jniimg->data[3*(width*row_index + column_index) + 1];
|
|
row_out[column_index].b = jniimg->data[3*(width*row_index + column_index) + 0];
|
|
row_out[column_index].a = 255;
|
|
}
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_org_pngquant_Image_liq_1image_1create(JNIEnv *env, jclass class, jlong attr, jbyteArray bytearray, jint w, jint h, jint components) {
|
|
/* liq_image needs to be wrapped to keep track of allocated buffer */
|
|
liq_jni_image *jniimg = malloc(sizeof(liq_jni_image));
|
|
|
|
/* copying buffer, since ReleaseByteArrayElements was crashing when called from finalize() */
|
|
jsize size = (*env)->GetArrayLength(env, bytearray);
|
|
jniimg->data = malloc(size);
|
|
(*env)->GetByteArrayRegion(env, bytearray, 0, size, jniimg->data);
|
|
|
|
jniimg->image = liq_image_create_custom((liq_attr*)attr, components == 4 ? convert_abgr : convert_bgr, jniimg, w, h, 0);
|
|
|
|
if (!jniimg->image) {
|
|
free(jniimg->data);
|
|
free(jniimg);
|
|
return 0;
|
|
}
|
|
return (jlong)jniimg;
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_Image_addFixedColor(JNIEnv *env, jobject obj, jint r, jint g, jint b, jint a) {
|
|
liq_color c = {r,g,b,a};
|
|
return LIQ_OK == liq_image_add_fixed_color(((liq_jni_image*)handle(env,obj))->image, c);
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_org_pngquant_Image_getWidth(JNIEnv *env, jobject obj) {
|
|
return liq_image_get_width(((liq_jni_image*)handle(env,obj))->image);
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_org_pngquant_Image_getHeight(JNIEnv *env, jobject obj) {
|
|
return liq_image_get_height(((liq_jni_image*)handle(env,obj))->image);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_pngquant_Image_liq_1image_1destroy(JNIEnv *env, jclass class, jlong handle) {
|
|
liq_jni_image *jniimg = (liq_jni_image*)handle;
|
|
liq_image_destroy(jniimg->image);
|
|
free(jniimg->data);
|
|
free(jniimg);
|
|
}
|
|
|
|
JNIEXPORT jlong JNICALL Java_org_pngquant_Result_liq_1quantize_1image(JNIEnv *env, jclass class, jlong attr, jlong handle) {
|
|
return (jlong)liq_quantize_image((liq_attr*)attr, ((liq_jni_image*)handle)->image);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_Result_setDitheringLevel(JNIEnv *env, jobject obj, jfloat l) {
|
|
return LIQ_OK == liq_set_dithering_level(handle(env, obj), l);
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_Result_setGamma(JNIEnv *env, jobject obj, jdouble gamma) {
|
|
return LIQ_OK == liq_set_output_gamma(handle(env, obj), gamma);
|
|
}
|
|
|
|
JNIEXPORT jdouble JNICALL Java_org_pngquant_Result_getGamma(JNIEnv *env, jobject obj) {
|
|
return liq_get_output_gamma(handle(env, obj));
|
|
}
|
|
|
|
JNIEXPORT jboolean JNICALL Java_org_pngquant_Result_liq_1write_1remapped_1image(JNIEnv *env, jclass class, jlong result, jlong image_handle, jbyteArray bytearray) {
|
|
jsize size = (*env)->GetArrayLength(env, bytearray);
|
|
|
|
jbyte *bitmap = (*env)->GetByteArrayElements(env, bytearray, 0);
|
|
liq_error err = liq_write_remapped_image((liq_result*)result, ((liq_jni_image*)image_handle)->image, bitmap, size);
|
|
(*env)->ReleaseByteArrayElements(env, bytearray, bitmap, 0);
|
|
|
|
return LIQ_OK == err;
|
|
}
|
|
|
|
JNIEXPORT jdouble JNICALL Java_org_pngquant_Result_getMeanSquareError(JNIEnv *env, jobject obj) {
|
|
return liq_get_quantization_error(handle(env, obj));
|
|
}
|
|
|
|
JNIEXPORT jint JNICALL Java_org_pngquant_Result_getQuality(JNIEnv *env, jobject obj) {
|
|
return liq_get_quantization_quality(handle(env, obj));
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_org_pngquant_Result_liq_1result_1destroy(JNIEnv *env, jclass class, jlong result) {
|
|
return liq_result_destroy((liq_result*)result);
|
|
}
|
|
|
|
JNIEXPORT jbyteArray JNICALL Java_org_pngquant_Result_liq_1get_1palette(JNIEnv *env, jclass class, jlong result) {
|
|
const liq_palette *pal = liq_get_palette((liq_result*)result);
|
|
jbyteArray arr = (*env)->NewByteArray(env, pal->count * 4);
|
|
int i;
|
|
for(i=0; i < pal->count; i++) {
|
|
(*env)->SetByteArrayRegion(env, arr, i*4, 4, ((jbyte*)&pal->entries[i]));
|
|
}
|
|
return arr;
|
|
}
|