jmagick.c
上传用户:qingzhou
上传日期:2013-04-21
资源大小:733k
文件大小:21k
- #include <jni.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <magick/api.h>
- #include "jmagick.h"
- /*
- * Convenience function to help throw an MagickException.
- */
- void throwMagickException(JNIEnv *env, const char *mesg)
- {
- jclass magickExceptionClass;
- magickExceptionClass = (*env)->FindClass(env, "magick/MagickException");
- if (magickExceptionClass == 0) {
- fprintf(stderr, "Cannot find MagickException classn");
- return;
- }
- (*env)->ThrowNew(env, magickExceptionClass, mesg);
- }
- /*
- * Convenience function to help throw an MagickApiException.
- *
- * Input:
- * mesg JMagick message
- * exception points to a ImageMagick ExceptionInfo structure
- */
- void throwMagickApiException(JNIEnv *env,
- const char *mesg,
- const ExceptionInfo *exception)
- {
- jclass magickApiExceptionClass;
- jmethodID consMethodID = 0;
- jobject newObj;
- jstring jreason, jdescription;
- int result;
- /* Find the class ID */
- magickApiExceptionClass =
- (*env)->FindClass(env, "magick/MagickApiException");
- if (magickApiExceptionClass == 0) {
- fprintf(stderr, "Cannot find MagickApiException classn");
- return;
- }
- /* Find the constructor ID */
- consMethodID =
- (*env)->GetMethodID(env, magickApiExceptionClass,
- "<init>",
- "(ILjava/lang/String;Ljava/lang/String;)V");
- if (consMethodID == 0) {
- return;
- }
- /* Obtain the string objects */
- jreason = (*env)->NewStringUTF(env, exception->reason);
- if (jreason == NULL) {
- #ifdef DIAGNOSTIC
- fprintf(stderr,
- "throwMagickApiException: "
- "Unable to create reason stringn");
- #endif
- return;
- }
- jdescription = (*env)->NewStringUTF(env, exception->description);
- if (jdescription == NULL) {
- #ifdef DIAGNOSTIC
- fprintf(stderr,
- "throwMagickApiException: "
- "Unable to create description stringn");
- #endif
- return;
- }
- /* Create the MagickApiException object */
- newObj = (*env)->NewObject(env, magickApiExceptionClass, consMethodID,
- exception->severity,
- jreason, jdescription);
- if (newObj == NULL) {
- #ifdef DIAGNOSTIC
- fprintf(stderr,
- "throwMagickApiException: "
- "Unable to create MagickApiException objectn");
- #endif
- return;
- }
- /* Throw the exception. */
- result = (*env)->Throw(env, newObj);
- #ifdef DIAGNOSTIC
- if (result != 0) {
- fprintf(stderr,
- "throwMagickApiException: "
- "Fail to throw MagickApiException");
- }
- #endif
- }
- /*
- * Convenience function to retreive a handle from an object.
- *
- * Input:
- * env Java VM environment
- * obj Java object for which handle is to be retrieved
- * handleName name of the handle in the object
- * fieldId if non-null, contains the field ID. 0 to request retrieval.
- *
- * Output:
- * fieldId if non-null, will contain field ID of the handle on output.
- */
- void *getHandle(JNIEnv *env,
- jobject obj,
- const char *handleName,
- jfieldID *fieldId)
- {
- jclass objClass;
- jfieldID handleFid;
- /* Retrieve the field ID of the handle */
- if (fieldId == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- handleFid = (*env)->GetFieldID(env, objClass, handleName, "J");
- }
- else if (*fieldId == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- handleFid = *fieldId =
- (*env)->GetFieldID(env, objClass, handleName, "J");
- }
- else {
- handleFid = *fieldId;
- }
- return (void*) (*env)->GetLongField(env, obj, handleFid);
- }
- /*
- * Convenience function to set a handle in an object.
- *
- * Input:
- * env Java VM environment
- * obj Java object for which handle is to be retrieved
- * handleName name of the handle in the object
- * fieldId if non-null, contains the field ID. 0 to request retrieval.
- *
- * Output:
- * fieldId if non-null, will contain field ID of the handle on output.
- *
- * Return:
- * non-zero if successful
- * zero if failure
- */
- int setHandle(JNIEnv *env,
- jobject obj,
- const char *handleName,
- void *handle,
- jfieldID *fieldId)
- {
- jclass objClass;
- jfieldID handleFid;
- /* Retrieve the field ID of the handle */
- if (fieldId == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- handleFid = (*env)->GetFieldID(env, objClass, handleName, "J");
- }
- else if (fieldId == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- handleFid = *fieldId =
- (*env)->GetFieldID(env, objClass, handleName, "J");
- }
- else {
- handleFid = *fieldId;
- }
- if (handleFid == 0) {
- return 0;
- }
- (*env)->SetLongField(env, obj, handleFid, (jlong) handle);
- return 1;
- }
- /*
- * Retrieve the int value of the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- *
- * Output:
- * iRect to be initilised by values in jRect.
- * fieldID if non-null, will contain the field ID.
- * value to contain the retrieved value. Must not be null.
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int getIntFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID,
- jint *value)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "I");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "I");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return 0;
- }
- *value = (*env)->GetIntField(env, obj, objFieldID);
- return 1;
- }
- /*
- * Store the int value of the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- * value to contain the value to be stored.
- *
- * Output:
- * fieldID if non-null, will contain the field ID.
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int setIntFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID,
- jint value)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "I");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "I");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return 0;
- }
- (*env)->SetIntField(env, obj, objFieldID, value);
- return 1;
- }
- /*
- * Retrieve the byte value of the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- *
- * Output:
- * iRect to be initilised by values in jRect.
- * fieldID if non-null, will contain the field ID.
- * value to contain the retrieved value. Must not be null.
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int getByteFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID,
- jbyte *value)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "B");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "B");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return 0;
- }
- *value = (*env)->GetByteField(env, obj, objFieldID);
- return 1;
- }
- /*
- * Retrieve the short value of the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- *
- * Output:
- * iRect to be initilised by values in jRect.
- * fieldID if non-null, will contain the field ID.
- * value to contain the retrieved value. Must not be null.
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int getShortFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID,
- jshort *value)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "S");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return 0;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "S");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return 0;
- }
- *value = (*env)->GetShortField(env, obj, objFieldID);
- return 1;
- }
- /*
- * Retrieve the string value of the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- *
- * Output:
- * fieldID if non-null, will contain the field ID.
- *
- * Return:
- * The string value requested. The caller is responsible for
- * deallocating this string.
- */
- char* getStringFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- jobject stringObj = 0;
- char *stringVal = NULL;
- char *stringCpy = NULL;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- objFieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "Ljava/lang/String;");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "Ljava/lang/String;");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return NULL;
- }
- stringObj = (*env)->GetObjectField(env, obj, objFieldID);
- if (stringObj == NULL) {
- return NULL;
- }
- stringVal = (char *) (*env)->GetStringUTFChars(env, stringObj, 0);
- stringCpy = (char *) AcquireString(stringVal);
- (*env)->ReleaseStringUTFChars(env, stringObj, stringVal);
- return stringCpy;
- }
- /*
- * Retrieve the byte array from the specified field.
- *
- * Input:
- * env Java VM environment.
- * obj Java object for which the value is to be retrieved.
- * fieldName name of the field to be retrieved.
- * fieldID if non-null, points to field ID. 0 to request retrieval.
- *
- * Output:
- * fieldID if non-null, will contain the field ID.
- * size the size of the array is returned here. Must not be NULL.
- *
- * Return:
- * The byte array requested. The caller is responsible for
- * deallocating this byte array.
- */
- unsigned char* getByteArrayFieldValue(JNIEnv *env,
- jobject obj,
- const char *fieldName,
- jfieldID *fieldID,
- int *size)
- {
- jclass objClass = 0;
- jfieldID objFieldID = 0;
- jobject byteArrayObj = 0;
- unsigned char *byteArray = NULL;
- char *byteArrayCpy = NULL;
- if (fieldID == NULL) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- objFieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "[B");
- }
- else if (*fieldID == 0) {
- objClass = (*env)->GetObjectClass(env, obj);
- if (objClass == 0) {
- return NULL;
- }
- objFieldID = *fieldID =
- (*env)->GetFieldID(env, objClass, fieldName, "[B");
- }
- else {
- objFieldID = *fieldID;
- }
- if (objFieldID == 0) {
- return NULL;
- }
- /* Get the array object */
- byteArrayObj = (*env)->GetObjectField(env, obj, objFieldID);
- if (byteArrayObj == NULL) {
- return NULL;
- }
- /* Determine the size of the array */
- *size = (*env)->GetArrayLength(env, byteArrayObj);
- if (*size == 0) {
- return NULL;
- }
- /* Get and copy the array elements */
- byteArray = (jbyte *) (*env)->GetByteArrayElements(env, byteArrayObj, 0);
- byteArrayCpy = (unsigned char *) AcquireMemory(*size);
- if (byteArray == NULL) {
- return NULL;
- }
- memcpy(byteArrayCpy, byteArray, *size);
- (*env)->ReleaseByteArrayElements(env, byteArrayObj, byteArray, JNI_ABORT);
- return byteArrayCpy;
- }
- /*
- * From a java.awt.Rectangle object, construct a ImageMagick
- * RectangleInfo, as passed in from the parameter.
- *
- * Input:
- * env Java VM environment
- * jRect an instance of java.awt.Rectangle
- *
- * Output:
- * iRect to be initilised by values in jRect
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int getRectangle(JNIEnv *env, jobject jRect, RectangleInfo *iRect)
- {
- jint width, height, x, y;
- int retVal =
- getIntFieldValue(env, jRect, "width", NULL, (jint *) &width) &&
- getIntFieldValue(env, jRect, "height", NULL, (jint *) &height) &&
- getIntFieldValue(env, jRect, "x", NULL, (jint *) &x) &&
- getIntFieldValue(env, jRect, "y", NULL, (jint *) &y);
- if (retVal) {
- iRect->width = width;
- iRect->height = height;
- iRect->x = x;
- iRect->y = y;
- }
- return retVal;
- }
- /*
- * From a magick.PixelPacket object, construct a ImageMagick
- * PixelPacket, as passed in from the parameter.
- *
- * Input:
- * env Java VM environment
- * jPixelPacket an instance of magick.PixelPacket
- *
- * Output:
- * iPixelPacket to be initilised by values in jPixelPacket
- *
- * Return:
- * non-zero if successful
- * zero if failed
- */
- int getPixelPacket(JNIEnv *env,
- jobject jPixelPacket,
- PixelPacket *iPixelPacket)
- {
- jint red, green, blue, opacity;
- int successful =
- getIntFieldValue(env, jPixelPacket, "red", NULL,
- &red) &&
- getIntFieldValue(env, jPixelPacket, "green", NULL,
- &green) &&
- getIntFieldValue(env, jPixelPacket, "blue", NULL,
- &blue) &&
- getIntFieldValue(env, jPixelPacket, "opacity", NULL,
- &opacity);
- if (!successful) {
- return successful;
- }
- iPixelPacket->red = (Quantum) red;
- iPixelPacket->green = (Quantum) green;
- iPixelPacket->blue = (Quantum) blue;
- iPixelPacket->opacity = (Quantum) opacity;
- return successful;
- }
- /*
- * Construct a new Java magick.MagickImage object and set the
- * handle.
- *
- * Input:
- * env Java VM environment
- * image ImageMagick image handle
- *
- * Return:
- * A new instance of magick.MagickImage object.
- *
- */
- jobject newImageObject(JNIEnv *env, Image* image)
- {
- jclass magickImageClass = 0;
- jmethodID consMethodID = 0;
- jobject newObj;
- magickImageClass = (*env)->FindClass(env, "magick/MagickImage");
- if (magickImageClass == 0) {
- return NULL;
- }
- consMethodID = (*env)->GetMethodID(env, magickImageClass,
- "<init>", "()V");
- if (consMethodID == 0) {
- return NULL;
- }
- newObj = (*env)->NewObject(env, magickImageClass, consMethodID);
- if (newObj == NULL) {
- return NULL;
- }
- if (!setHandle(env, newObj, "magickImageHandle", (void*) image, NULL)) {
- #ifdef DIAGNOSTIC
- fprintf(stderr, "newImageObject: Unable to set handlen");
- #endif
- return NULL;
- }
- return newObj;
- }
- /*
- * Set a attribute in a generic handle to string.
- *
- * Input:
- * env Java VM environment
- * attribVar points to a C string so as to set the value
- * jstr Java string for which to set the attrib
- *
- * Output:
- * attribVar points to a new C string with content from jstr
- */
- void setHandleAttribute(JNIEnv *env, char **attribVar, jstring jstr)
- {
- const char *cstr = NULL;
- if (*attribVar != NULL) {
- LiberateMemory((void**)attribVar);
- }
- cstr = (*env)->GetStringUTFChars(env, jstr, 0);
- *attribVar = (char *) AcquireString(cstr);
- (*env)->ReleaseStringUTFChars(env, jstr, cstr);
- }
- /*
- * Given the C ProfileInfo structure and the Java ProfileInfo object,
- * acquire the contents of the Java ProfileInfo object and store it in
- * the C ProfileInfo structure.
- *
- * Input:
- * env JNI environment
- * profileObj Java ProfileInfo object for which field values are to be
- * obtain to store into the C ProfileInfo structure
- * Output:
- * profileInfo C ProfileINfo structure to store field values
- */
- void setProfileInfo(JNIEnv *env, ProfileInfo *profileInfo, jobject profileObj)
- {
- char *name;
- unsigned char *info;
- int infoSize = 0;
- if (profileObj == NULL) {
- throwMagickException(env, "ProfileInfo cannot be null");
- return;
- }
- name = getStringFieldValue(env, profileObj, "name", NULL);
- info = getByteArrayFieldValue(env, profileObj, "info", NULL, &infoSize);
- if (profileInfo->name != NULL) {
- LiberateMemory((void**) &profileInfo->name);
- }
- profileInfo->name = name;
- if (profileInfo->info != NULL) {
- LiberateMemory((void**) &profileInfo->info);
- }
- profileInfo->info = info;
- profileInfo->length = infoSize;
- }
- /*
- * Given the C ProfileInfo structure, construct a Java ProfileInfo
- * object with values obtained from the C ProfileInfo structure.
- * Input:
- * env JNI environment
- * profileInfo C ProfileInfo structure
- * Return:
- * Java ProfileInfo object
- */
- jobject getProfileInfo(JNIEnv *env, ProfileInfo *profileInfo)
- {
- jclass profileInfoClass;
- jmethodID consMethodID;
- jobject profileObject;
- jstring name;
- jbyteArray byteArray;
- unsigned char *byteElements;
- /* Get the ProfileInfo class ID */
- profileInfoClass = (*env)->FindClass(env, "magick/ProfileInfo");
- if (profileInfoClass == 0) {
- throwMagickException(env, "Unable to locate class "
- "magick.ProfileInfo");
- return NULL;
- }
- /* Get the constructor method ID */
- consMethodID = (*env)->GetMethodID(env, profileInfoClass,
- "<init>", "(Ljava/lang/String;[B)V");
- if (consMethodID == 0) {
- throwMagickException(env, "Unable to locate constructor "
- "ProfileInfo(String, byte[])");
- return NULL;
- }
- /* Construct the name */
- if (profileInfo->name != NULL) {
- name = (*env)->NewStringUTF(env, profileInfo->name);
- if (name == NULL) {
- throwMagickException(env, "Unable to allocate Java String "
- "for profile name");
- return NULL;
- }
- }
- else {
- name = NULL;
- }
- /* Construct the byte array */
- if (profileInfo->length > 0) {
- byteArray = (*env)->NewByteArray(env, profileInfo->length);
- if (byteArray == NULL) {
- throwMagickException(env, "Unable to allocate byte array "
- "for profile info");
- return NULL;
- }
- byteElements =
- (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
- if (byteElements == NULL) {
- throwMagickException(env, "Unable to obtain byte array elements "
- "for profile info");
- return NULL;
- }
- memcpy(byteElements,
- profileInfo->info,
- profileInfo->length);
- (*env)->ReleaseByteArrayElements(env, byteArray, byteElements, 0);
- }
- else {
- byteArray = NULL;
- }
- /* Construct the ProfileInfo object */
- profileObject = (*env)->NewObject(env, profileInfoClass, consMethodID,
- name, byteArray);
- if (profileObject == NULL) {
- throwMagickException(env, "Unable to construct ProfileInfo object");
- return NULL;
- }
- return profileObject;
- }