jmagick.c
上传用户:qingzhou
上传日期:2013-04-21
资源大小:733k
文件大小:21k
源码类别:

破解

开发平台:

Java

  1. #include <jni.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <time.h>
  6. #include <sys/types.h>
  7. #include <magick/api.h>
  8. #include "jmagick.h"
  9. /*
  10.  * Convenience function to help throw an MagickException.
  11.  */
  12. void throwMagickException(JNIEnv *env, const char *mesg)
  13. {
  14.     jclass magickExceptionClass;
  15.     magickExceptionClass = (*env)->FindClass(env, "magick/MagickException");
  16.     if (magickExceptionClass == 0) {
  17. fprintf(stderr, "Cannot find MagickException classn");
  18. return;
  19.     }
  20.     (*env)->ThrowNew(env, magickExceptionClass, mesg);
  21. }
  22. /*
  23.  * Convenience function to help throw an MagickApiException.
  24.  *
  25.  * Input:
  26.  *   mesg       JMagick message
  27.  *   exception  points to a ImageMagick ExceptionInfo structure
  28.  */
  29. void throwMagickApiException(JNIEnv *env,
  30.      const char *mesg,
  31.      const ExceptionInfo *exception)
  32. {
  33.     jclass magickApiExceptionClass;
  34.     jmethodID consMethodID = 0;
  35.     jobject newObj;
  36.     jstring jreason, jdescription;
  37.     int result;
  38.     /* Find the class ID */
  39.     magickApiExceptionClass =
  40. (*env)->FindClass(env, "magick/MagickApiException");
  41.     if (magickApiExceptionClass == 0) {
  42. fprintf(stderr, "Cannot find MagickApiException classn");
  43. return;
  44.     }
  45.     /* Find the constructor ID */
  46.     consMethodID =
  47. (*env)->GetMethodID(env, magickApiExceptionClass,
  48.     "<init>",
  49.     "(ILjava/lang/String;Ljava/lang/String;)V");
  50.     if (consMethodID == 0) {
  51. return;
  52.     }
  53.     /* Obtain the string objects */
  54.     jreason = (*env)->NewStringUTF(env, exception->reason);
  55.     if (jreason == NULL) {
  56. #ifdef DIAGNOSTIC
  57. fprintf(stderr,
  58. "throwMagickApiException: "
  59. "Unable to create reason stringn");
  60. #endif
  61. return;
  62.     }
  63.     jdescription = (*env)->NewStringUTF(env, exception->description);
  64.     if (jdescription == NULL) {
  65. #ifdef DIAGNOSTIC
  66. fprintf(stderr,
  67. "throwMagickApiException: "
  68. "Unable to create description stringn");
  69. #endif
  70. return;
  71.     }
  72.     /* Create the MagickApiException object */
  73.     newObj = (*env)->NewObject(env, magickApiExceptionClass, consMethodID,
  74.        exception->severity,
  75.                                jreason, jdescription);
  76.     if (newObj == NULL) {
  77. #ifdef DIAGNOSTIC
  78. fprintf(stderr,
  79. "throwMagickApiException: "
  80. "Unable to create MagickApiException objectn");
  81. #endif
  82. return;
  83.     }
  84.     /* Throw the exception. */
  85.     result = (*env)->Throw(env, newObj);
  86. #ifdef DIAGNOSTIC
  87.     if (result != 0) {
  88. fprintf(stderr,
  89. "throwMagickApiException: "
  90. "Fail to throw MagickApiException");
  91.     }
  92. #endif
  93. }
  94. /*
  95.  * Convenience function to retreive a handle from an object.
  96.  *
  97.  * Input:
  98.  *   env         Java VM environment
  99.  *   obj         Java object for which handle is to be retrieved
  100.  *   handleName  name of the handle in the object
  101.  *   fieldId     if non-null, contains the field ID. 0 to request retrieval.
  102.  *
  103.  * Output:
  104.  *   fieldId     if non-null, will contain field ID of the handle on output.
  105.  */
  106. void *getHandle(JNIEnv *env,
  107. jobject obj,
  108. const char *handleName,
  109. jfieldID *fieldId)
  110. {
  111.     jclass objClass;
  112.     jfieldID handleFid;
  113.     /* Retrieve the field ID of the handle */
  114.     if (fieldId == NULL) {
  115. objClass = (*env)->GetObjectClass(env, obj);
  116. if (objClass == 0) {
  117.     return NULL;
  118. }
  119. handleFid = (*env)->GetFieldID(env, objClass, handleName, "J");
  120.     }
  121.     else if (*fieldId == 0) {
  122. objClass = (*env)->GetObjectClass(env, obj);
  123. if (objClass == 0) {
  124.     return NULL;
  125. }
  126. handleFid = *fieldId =
  127.     (*env)->GetFieldID(env, objClass, handleName, "J");
  128.     }
  129.     else {
  130. handleFid = *fieldId;
  131.     }
  132.     return (void*) (*env)->GetLongField(env, obj, handleFid);
  133. }
  134. /*
  135.  * Convenience function to set a handle in an object.
  136.  *
  137.  * Input:
  138.  *   env         Java VM environment
  139.  *   obj         Java object for which handle is to be retrieved
  140.  *   handleName  name of the handle in the object
  141.  *   fieldId     if non-null, contains the field ID. 0 to request retrieval.
  142.  *
  143.  * Output:
  144.  *   fieldId     if non-null, will contain field ID of the handle on output.
  145.  *
  146.  * Return:
  147.  *   non-zero    if successful
  148.  *   zero        if failure
  149.  */
  150. int setHandle(JNIEnv *env,
  151.       jobject obj,
  152.       const char *handleName,
  153.       void *handle,
  154.       jfieldID *fieldId)
  155. {
  156.     jclass objClass;
  157.     jfieldID handleFid;
  158.     /* Retrieve the field ID of the handle */
  159.     if (fieldId == NULL) {
  160. objClass = (*env)->GetObjectClass(env, obj);
  161. if (objClass == 0) {
  162.     return 0;
  163. }
  164. handleFid = (*env)->GetFieldID(env, objClass, handleName, "J");
  165.     }
  166.     else if (fieldId == 0) {
  167. objClass = (*env)->GetObjectClass(env, obj);
  168. if (objClass == 0) {
  169.     return 0;
  170. }
  171. handleFid = *fieldId =
  172.     (*env)->GetFieldID(env, objClass, handleName, "J");
  173.     }
  174.     else {
  175. handleFid = *fieldId;
  176.     }
  177.     if (handleFid == 0) {
  178. return 0;
  179.     }
  180.     (*env)->SetLongField(env, obj, handleFid, (jlong) handle);
  181.     return 1;
  182. }
  183. /*
  184.  * Retrieve the int value of the specified field.
  185.  *
  186.  * Input:
  187.  *   env        Java VM environment.
  188.  *   obj        Java object for which the value is to be retrieved.
  189.  *   fieldName  name of the field to be retrieved.
  190.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  191.  *
  192.  * Output:
  193.  *   iRect      to be initilised by values in jRect.
  194.  *   fieldID    if non-null, will contain the field ID.
  195.  *   value      to contain the retrieved value. Must not be null.
  196.  *
  197.  * Return:
  198.  *   non-zero   if successful
  199.  *   zero       if failed
  200.  */
  201. int getIntFieldValue(JNIEnv *env,
  202.      jobject obj,
  203.      const char *fieldName,
  204.      jfieldID *fieldID,
  205.      jint *value)
  206. {
  207.     jclass objClass = 0;
  208.     jfieldID objFieldID = 0;
  209.     if (fieldID == NULL) {
  210. objClass = (*env)->GetObjectClass(env, obj);
  211. if (objClass == 0) {
  212.     return 0;
  213. }
  214. objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "I");
  215.     }
  216.     else if (*fieldID == 0) {
  217. objClass = (*env)->GetObjectClass(env, obj);
  218. if (objClass == 0) {
  219.     return 0;
  220. }
  221. objFieldID = *fieldID =
  222.     (*env)->GetFieldID(env, objClass, fieldName, "I");
  223.     }
  224.     else {
  225. objFieldID = *fieldID;
  226.     }
  227.     if (objFieldID == 0) {
  228. return 0;
  229.     }
  230.     *value = (*env)->GetIntField(env, obj, objFieldID);
  231.     return 1;
  232. }
  233. /*
  234.  * Store the int value of the specified field.
  235.  *
  236.  * Input:
  237.  *   env        Java VM environment.
  238.  *   obj        Java object for which the value is to be retrieved.
  239.  *   fieldName  name of the field to be retrieved.
  240.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  241.  *   value      to contain the value to be stored.
  242.  *
  243.  * Output:
  244.  *   fieldID    if non-null, will contain the field ID.
  245.  *
  246.  * Return:
  247.  *   non-zero   if successful
  248.  *   zero       if failed
  249.  */
  250. int setIntFieldValue(JNIEnv *env,
  251.                      jobject obj,
  252.                      const char *fieldName,
  253.                      jfieldID *fieldID,
  254.                      jint value)
  255. {
  256.     jclass objClass = 0;
  257.     jfieldID objFieldID = 0;
  258.     if (fieldID == NULL) {
  259. objClass = (*env)->GetObjectClass(env, obj);
  260. if (objClass == 0) {
  261.     return 0;
  262. }
  263. objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "I");
  264.     }
  265.     else if (*fieldID == 0) {
  266. objClass = (*env)->GetObjectClass(env, obj);
  267. if (objClass == 0) {
  268.     return 0;
  269. }
  270. objFieldID = *fieldID =
  271.     (*env)->GetFieldID(env, objClass, fieldName, "I");
  272.     }
  273.     else {
  274. objFieldID = *fieldID;
  275.     }
  276.     if (objFieldID == 0) {
  277. return 0;
  278.     }
  279.     (*env)->SetIntField(env, obj, objFieldID, value);
  280.     return 1;
  281. }
  282. /*
  283.  * Retrieve the byte value of the specified field.
  284.  *
  285.  * Input:
  286.  *   env        Java VM environment.
  287.  *   obj        Java object for which the value is to be retrieved.
  288.  *   fieldName  name of the field to be retrieved.
  289.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  290.  *
  291.  * Output:
  292.  *   iRect      to be initilised by values in jRect.
  293.  *   fieldID    if non-null, will contain the field ID.
  294.  *   value      to contain the retrieved value. Must not be null.
  295.  *
  296.  * Return:
  297.  *   non-zero   if successful
  298.  *   zero       if failed
  299.  */
  300. int getByteFieldValue(JNIEnv *env,
  301.       jobject obj,
  302.       const char *fieldName,
  303.       jfieldID *fieldID,
  304.       jbyte *value)
  305. {
  306.     jclass objClass = 0;
  307.     jfieldID objFieldID = 0;
  308.     if (fieldID == NULL) {
  309. objClass = (*env)->GetObjectClass(env, obj);
  310. if (objClass == 0) {
  311.     return 0;
  312. }
  313. objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "B");
  314.     }
  315.     else if (*fieldID == 0) {
  316. objClass = (*env)->GetObjectClass(env, obj);
  317. if (objClass == 0) {
  318.     return 0;
  319. }
  320. objFieldID = *fieldID =
  321.     (*env)->GetFieldID(env, objClass, fieldName, "B");
  322.     }
  323.     else {
  324. objFieldID = *fieldID;
  325.     }
  326.     if (objFieldID == 0) {
  327. return 0;
  328.     }
  329.     *value = (*env)->GetByteField(env, obj, objFieldID);
  330.     return 1;
  331. }
  332. /*
  333.  * Retrieve the short value of the specified field.
  334.  *
  335.  * Input:
  336.  *   env        Java VM environment.
  337.  *   obj        Java object for which the value is to be retrieved.
  338.  *   fieldName  name of the field to be retrieved.
  339.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  340.  *
  341.  * Output:
  342.  *   iRect      to be initilised by values in jRect.
  343.  *   fieldID    if non-null, will contain the field ID.
  344.  *   value      to contain the retrieved value. Must not be null.
  345.  *
  346.  * Return:
  347.  *   non-zero   if successful
  348.  *   zero       if failed
  349.  */
  350. int getShortFieldValue(JNIEnv *env,
  351.        jobject obj,
  352.        const char *fieldName,
  353.        jfieldID *fieldID,
  354.        jshort *value)
  355. {
  356.     jclass objClass = 0;
  357.     jfieldID objFieldID = 0;
  358.     if (fieldID == NULL) {
  359. objClass = (*env)->GetObjectClass(env, obj);
  360. if (objClass == 0) {
  361.     return 0;
  362. }
  363. objFieldID = (*env)->GetFieldID(env, objClass, fieldName, "S");
  364.     }
  365.     else if (*fieldID == 0) {
  366. objClass = (*env)->GetObjectClass(env, obj);
  367. if (objClass == 0) {
  368.     return 0;
  369. }
  370. objFieldID = *fieldID =
  371.     (*env)->GetFieldID(env, objClass, fieldName, "S");
  372.     }
  373.     else {
  374. objFieldID = *fieldID;
  375.     }
  376.     if (objFieldID == 0) {
  377. return 0;
  378.     }
  379.     *value = (*env)->GetShortField(env, obj, objFieldID);
  380.     return 1;
  381. }
  382. /*
  383.  * Retrieve the string value of the specified field.
  384.  *
  385.  * Input:
  386.  *   env        Java VM environment.
  387.  *   obj        Java object for which the value is to be retrieved.
  388.  *   fieldName  name of the field to be retrieved.
  389.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  390.  *
  391.  * Output:
  392.  *   fieldID    if non-null, will contain the field ID.
  393.  *
  394.  * Return:
  395.  *   The string value requested. The caller is responsible for
  396.  *   deallocating this string.
  397.  */
  398. char* getStringFieldValue(JNIEnv *env,
  399.                           jobject obj,
  400.                           const char *fieldName,
  401.                           jfieldID *fieldID)
  402. {
  403.     jclass objClass = 0;
  404.     jfieldID objFieldID = 0;
  405.     jobject stringObj = 0;
  406.     char *stringVal = NULL;
  407.     char *stringCpy = NULL;
  408.     if (fieldID == NULL) {
  409. objClass = (*env)->GetObjectClass(env, obj);
  410. if (objClass == 0) {
  411.     return NULL;
  412. }
  413. objFieldID =
  414.             (*env)->GetFieldID(env, objClass, fieldName, "Ljava/lang/String;");
  415.     }
  416.     else if (*fieldID == 0) {
  417. objClass = (*env)->GetObjectClass(env, obj);
  418. if (objClass == 0) {
  419.     return NULL;
  420. }
  421. objFieldID = *fieldID =
  422.     (*env)->GetFieldID(env, objClass, fieldName, "Ljava/lang/String;");
  423.     }
  424.     else {
  425. objFieldID = *fieldID;
  426.     }
  427.     if (objFieldID == 0) {
  428. return NULL;
  429.     }
  430.     stringObj = (*env)->GetObjectField(env, obj, objFieldID);
  431.     if (stringObj == NULL) {
  432.         return NULL;
  433.     }
  434.     stringVal = (char *) (*env)->GetStringUTFChars(env, stringObj, 0);
  435.     stringCpy = (char *) AcquireString(stringVal);
  436.     (*env)->ReleaseStringUTFChars(env, stringObj, stringVal);
  437.     return stringCpy;
  438. }
  439. /*
  440.  * Retrieve the byte array from the specified field.
  441.  *
  442.  * Input:
  443.  *   env        Java VM environment.
  444.  *   obj        Java object for which the value is to be retrieved.
  445.  *   fieldName  name of the field to be retrieved.
  446.  *   fieldID    if non-null, points to field ID. 0 to request retrieval.
  447.  *
  448.  * Output:
  449.  *   fieldID    if non-null, will contain the field ID.
  450.  *   size       the size of the array is returned here. Must not be NULL.
  451.  *
  452.  * Return:
  453.  *   The byte array requested. The caller is responsible for
  454.  *   deallocating this byte array.
  455.  */
  456. unsigned char* getByteArrayFieldValue(JNIEnv *env,
  457.                                       jobject obj,
  458.                                       const char *fieldName,
  459.                                       jfieldID *fieldID,
  460.                                       int *size)
  461. {
  462.     jclass objClass = 0;
  463.     jfieldID objFieldID = 0;
  464.     jobject byteArrayObj = 0;
  465.     unsigned char *byteArray = NULL;
  466.     char *byteArrayCpy = NULL;
  467.     if (fieldID == NULL) {
  468. objClass = (*env)->GetObjectClass(env, obj);
  469. if (objClass == 0) {
  470.     return NULL;
  471. }
  472. objFieldID =
  473.             (*env)->GetFieldID(env, objClass, fieldName, "[B");
  474.     }
  475.     else if (*fieldID == 0) {
  476. objClass = (*env)->GetObjectClass(env, obj);
  477. if (objClass == 0) {
  478.     return NULL;
  479. }
  480. objFieldID = *fieldID =
  481.     (*env)->GetFieldID(env, objClass, fieldName, "[B");
  482.     }
  483.     else {
  484. objFieldID = *fieldID;
  485.     }
  486.     if (objFieldID == 0) {
  487. return NULL;
  488.     }
  489.     /* Get the array object */
  490.     byteArrayObj = (*env)->GetObjectField(env, obj, objFieldID);
  491.     if (byteArrayObj == NULL) {
  492.         return NULL;
  493.     }
  494.     /* Determine the size of the array */
  495.     *size = (*env)->GetArrayLength(env, byteArrayObj);
  496.     if (*size == 0) {
  497.         return NULL;
  498.     }
  499.     /* Get and copy the array elements */
  500.     byteArray = (jbyte *) (*env)->GetByteArrayElements(env, byteArrayObj, 0);
  501.     byteArrayCpy = (unsigned char *) AcquireMemory(*size);
  502.     if (byteArray == NULL) {
  503.         return NULL;
  504.     }
  505.     memcpy(byteArrayCpy, byteArray, *size);
  506.     (*env)->ReleaseByteArrayElements(env, byteArrayObj, byteArray, JNI_ABORT);
  507.     return byteArrayCpy;
  508. }
  509. /*
  510.  * From a java.awt.Rectangle object, construct a ImageMagick
  511.  * RectangleInfo, as passed in from the parameter.
  512.  *
  513.  * Input:
  514.  *   env        Java VM environment
  515.  *   jRect      an instance of java.awt.Rectangle
  516.  *
  517.  * Output:
  518.  *   iRect      to be initilised by values in jRect
  519.  *
  520.  * Return:
  521.  *   non-zero   if successful
  522.  *   zero       if failed
  523.  */
  524. int getRectangle(JNIEnv *env, jobject jRect, RectangleInfo *iRect)
  525. {
  526. jint width, height, x, y;
  527.     int retVal =
  528. getIntFieldValue(env, jRect, "width", NULL, (jint *) &width) &&
  529. getIntFieldValue(env, jRect, "height", NULL, (jint *) &height) &&
  530. getIntFieldValue(env, jRect, "x", NULL, (jint *) &x) &&
  531. getIntFieldValue(env, jRect, "y", NULL, (jint *) &y);
  532. if (retVal) {
  533. iRect->width = width;
  534. iRect->height = height;
  535. iRect->x = x;
  536. iRect->y = y;
  537. }
  538. return retVal;
  539. }
  540. /*
  541.  * From a magick.PixelPacket object, construct a ImageMagick
  542.  * PixelPacket, as passed in from the parameter.
  543.  *
  544.  * Input:
  545.  *   env           Java VM environment
  546.  *   jPixelPacket  an instance of magick.PixelPacket
  547.  *
  548.  * Output:
  549.  *   iPixelPacket  to be initilised by values in jPixelPacket
  550.  *
  551.  * Return:
  552.  *   non-zero   if successful
  553.  *   zero       if failed
  554.  */
  555. int getPixelPacket(JNIEnv *env,
  556.    jobject jPixelPacket,
  557.    PixelPacket *iPixelPacket)
  558. {
  559.   jint red, green, blue, opacity;
  560.   int successful =
  561. getIntFieldValue(env, jPixelPacket, "red", NULL,
  562.                          &red) &&
  563. getIntFieldValue(env, jPixelPacket, "green", NULL,
  564.                          &green) &&
  565.         getIntFieldValue(env, jPixelPacket, "blue", NULL,
  566.                          &blue) &&
  567. getIntFieldValue(env, jPixelPacket, "opacity", NULL,
  568.                          &opacity);
  569.   if (!successful) {
  570.       return successful;
  571.   }
  572.   iPixelPacket->red = (Quantum) red;
  573.   iPixelPacket->green = (Quantum) green;
  574.   iPixelPacket->blue = (Quantum) blue;
  575.   iPixelPacket->opacity = (Quantum) opacity;
  576.   return successful;
  577. }
  578. /*
  579.  * Construct a new Java magick.MagickImage object and set the
  580.  * handle.
  581.  *
  582.  * Input:
  583.  *   env     Java VM environment
  584.  *   image   ImageMagick image handle
  585.  *
  586.  * Return:
  587.  *   A new instance of magick.MagickImage object.
  588.  *
  589.  */
  590. jobject newImageObject(JNIEnv *env, Image* image)
  591. {
  592.     jclass magickImageClass = 0;
  593.     jmethodID consMethodID = 0;
  594.     jobject newObj;
  595.     magickImageClass = (*env)->FindClass(env, "magick/MagickImage");
  596.     if (magickImageClass == 0) {
  597. return NULL;
  598.     }
  599.     consMethodID = (*env)->GetMethodID(env, magickImageClass,
  600.        "<init>", "()V");
  601.     if (consMethodID == 0) {
  602. return NULL;
  603.     }
  604.     newObj = (*env)->NewObject(env, magickImageClass, consMethodID);
  605.     if (newObj == NULL) {
  606. return NULL;
  607.     }
  608.     if (!setHandle(env, newObj, "magickImageHandle", (void*) image, NULL)) {
  609. #ifdef DIAGNOSTIC
  610. fprintf(stderr, "newImageObject: Unable to set handlen");
  611. #endif
  612. return NULL;
  613.     }
  614.     return newObj;
  615. }
  616. /*
  617.  * Set a attribute in a generic handle to string.
  618.  *
  619.  * Input:
  620.  *   env        Java VM environment
  621.  *   attribVar  points to a C string so as to set the value
  622.  *   jstr       Java string for which to set the attrib
  623.  *
  624.  * Output:
  625.  *   attribVar  points to a new C string with content from jstr
  626.  */
  627. void setHandleAttribute(JNIEnv *env, char **attribVar, jstring jstr)
  628. {
  629.     const char *cstr = NULL;
  630.     if (*attribVar != NULL) {
  631. LiberateMemory((void**)attribVar);
  632.     }
  633.     cstr = (*env)->GetStringUTFChars(env, jstr, 0);
  634.     *attribVar = (char *) AcquireString(cstr);
  635.     (*env)->ReleaseStringUTFChars(env, jstr, cstr);
  636. }
  637. /*
  638.  * Given the C ProfileInfo structure and the Java ProfileInfo object,
  639.  * acquire the contents of the Java ProfileInfo object and store it in
  640.  * the C ProfileInfo structure.
  641.  * 
  642.  * Input:
  643.  *   env            JNI environment
  644.  *   profileObj     Java ProfileInfo object for which field values are to be
  645.  *                  obtain to store into the C ProfileInfo structure
  646.  * Output:
  647.  *   profileInfo    C ProfileINfo structure to store field values
  648.  */
  649. void setProfileInfo(JNIEnv *env, ProfileInfo *profileInfo, jobject profileObj)
  650. {
  651.     char *name;
  652.     unsigned char *info;
  653.     int infoSize = 0;
  654.     if (profileObj == NULL) {
  655.         throwMagickException(env, "ProfileInfo cannot be null");
  656.         return;
  657.     }
  658.     name = getStringFieldValue(env, profileObj, "name", NULL);
  659.     info = getByteArrayFieldValue(env, profileObj, "info", NULL, &infoSize);
  660.     if (profileInfo->name != NULL) {
  661.         LiberateMemory((void**) &profileInfo->name);
  662.     }
  663.     profileInfo->name = name;
  664.     if (profileInfo->info != NULL) {
  665.         LiberateMemory((void**) &profileInfo->info);
  666.     }
  667.     profileInfo->info = info;
  668.     profileInfo->length = infoSize;
  669. }
  670. /*
  671.  * Given the C ProfileInfo structure, construct a Java ProfileInfo
  672.  * object with values obtained from the C ProfileInfo structure.
  673.  * Input:
  674.  *   env           JNI environment
  675.  *   profileInfo   C ProfileInfo structure
  676.  * Return:
  677.  *   Java ProfileInfo object
  678.  */
  679. jobject getProfileInfo(JNIEnv *env, ProfileInfo *profileInfo)
  680. {
  681.     jclass profileInfoClass;
  682.     jmethodID consMethodID;
  683.     jobject profileObject;
  684.     jstring name;
  685.     jbyteArray byteArray;
  686.     unsigned char *byteElements;
  687.     /* Get the ProfileInfo class ID */
  688.     profileInfoClass = (*env)->FindClass(env, "magick/ProfileInfo");
  689.     if (profileInfoClass == 0) {
  690.         throwMagickException(env, "Unable to locate class "
  691.                                    "magick.ProfileInfo");
  692.         return NULL;
  693.     }
  694.     /* Get the constructor method ID */
  695.     consMethodID = (*env)->GetMethodID(env, profileInfoClass,
  696.                                        "<init>", "(Ljava/lang/String;[B)V");
  697.     if (consMethodID == 0) {
  698.         throwMagickException(env, "Unable to locate constructor "
  699.                                   "ProfileInfo(String, byte[])");
  700.         return NULL;
  701.     }
  702.     /* Construct the name */
  703.     if (profileInfo->name != NULL) {
  704.         name = (*env)->NewStringUTF(env, profileInfo->name);
  705.         if (name == NULL) {
  706.             throwMagickException(env, "Unable to allocate Java String "
  707.                                       "for profile name");
  708.             return NULL;
  709.         }
  710.     }
  711.     else {
  712.         name = NULL;
  713.     }
  714.     /* Construct the byte array */
  715.     if (profileInfo->length > 0) {
  716.         byteArray = (*env)->NewByteArray(env, profileInfo->length);
  717.         if (byteArray == NULL) {
  718.             throwMagickException(env, "Unable to allocate byte array "
  719.                                       "for profile info");
  720.             return NULL;
  721.         }
  722.         byteElements =
  723.             (*env)->GetByteArrayElements(env, byteArray, JNI_FALSE);
  724.         if (byteElements == NULL) {
  725.             throwMagickException(env, "Unable to obtain byte array elements "
  726.                                       "for profile info");
  727.             return NULL;
  728.         }
  729.         memcpy(byteElements,
  730.                profileInfo->info,
  731.                profileInfo->length);
  732.         (*env)->ReleaseByteArrayElements(env, byteArray, byteElements, 0);
  733.     }
  734.     else {
  735.         byteArray = NULL;
  736.     }
  737.     /* Construct the ProfileInfo object */
  738.     profileObject = (*env)->NewObject(env, profileInfoClass, consMethodID,
  739.                                       name, byteArray);
  740.     if (profileObject == NULL) {
  741.         throwMagickException(env, "Unable to construct ProfileInfo object");
  742.         return NULL;
  743.     }
  744.     return profileObject;
  745. }