1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#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;
}
|