Logo Search packages:      
Sourcecode: jmagick version File versions  Download package

jmagick.c

#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 class\n");
      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 class\n");
      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 string\n");
#endif
      return;
    }

    jdescription = (*env)->NewStringUTF(env, exception->description);
    if (jdescription == NULL) {
#ifdef DIAGNOSTIC
      fprintf(stderr,
            "throwMagickApiException: "
            "Unable to create description string\n");
#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 object\n");
#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 handle\n");
#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;
}

Generated by  Doxygen 1.6.0   Back to index