8027841: Enhance pixel manipulations
authorbae
Mon, 25 Nov 2013 12:51:16 +0400
changeset 23910 eadc1dc64a74
parent 23909 1ba74cd2a357
child 23911 f93d74f7d6fe
8027841: Enhance pixel manipulations Reviewed-by: prr, vadim, mschoene
jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
--- a/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Mon Jan 13 14:53:06 2014 -0800
+++ b/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c	Mon Nov 25 12:51:16 2013 +0400
@@ -228,6 +228,49 @@
     }
 }
 
+/*
+ * We have to make sure that awt_setPixels can be safely applied to the given pair of
+ * raster and mlib image.
+ *
+ * In particular, make sure that
+ *  - dimension is the same
+ *  - number of channels in mlib image corresponds to the number of bands in the raster
+ *  - sample size in image and raster are the same.
+ *
+ * Returns:
+ *  -1 to indicate failure,
+ *   1 to indicate success
+ */
+static int setPixelsFormMlibImage(JNIEnv *env, RasterS_t *rasterP, mlib_image* img) {
+    if (rasterP->width != img->width || rasterP->height != img->height) {
+        /* dimension does not match */
+        return -1;
+    }
+
+    if (rasterP->numBands != img->channels) {
+        /* number of bands does not match */
+        return -1;
+    }
+
+    switch (rasterP->dataType) {
+    case BYTE_DATA_TYPE:
+        if (img->type != MLIB_BYTE) {
+            return -1;
+        }
+        break;
+    case SHORT_DATA_TYPE:
+        if (img->type != MLIB_SHORT && img->type != MLIB_USHORT) {
+            return -1;
+        }
+        break;
+    default:
+        /* awt_setPixels does not support such rasters */
+        return -1;
+    }
+
+    return awt_setPixels(env, rasterP, mlib_ImageGetData(img));
+}
+
 /***************************************************************************
  *                          External Functions                             *
  ***************************************************************************/
@@ -700,7 +743,9 @@
 
     /* Means that we couldn't write directly into the destination buffer */
     if (ddata == NULL) {
-        retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
+        if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
+            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
+        }
     }
 
     /* Release the pinned memory */
@@ -1107,7 +1152,7 @@
         /* Need to store it back into the array */
         if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
             (*env)->ExceptionClear(env); // Could not store the array, try another way
-            retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
+            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
         }
     }
 
@@ -1433,6 +1478,14 @@
         retStatus = 0;
     }
 
+   /* Release the LUT */
+    for (i=0; i < lut_nbands; i++) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
+            (jbyte *) jtable[i].table, JNI_ABORT);
+    }
+    free ((void *) jtable);
+    free ((void *) tbl);
+
     /*
      * Means that we couldn't write directly into
      * the destination buffer
@@ -1446,13 +1499,6 @@
         }
     }
 
-    /* Release the LUT */
-    for (i=0; i < lut_nbands; i++) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
-            (jbyte *) jtable[i].table, JNI_ABORT);
-    }
-    free ((void *) jtable);
-    free ((void *) tbl);
 
     /* Release the pinned memory */
     freeArray(env, srcImageP, src, sdata, dstImageP, dst, ddata);
@@ -1670,18 +1716,20 @@
         retStatus = 0;
     }
 
+    /* Release the LUT */
+    for (i=0; i < lut_nbands; i++) {
+        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
+                                              (jbyte *) jtable[i].table, JNI_ABORT);
+    }
+
     /*
      * Means that we couldn't write directly into
      * the destination buffer
      */
     if (ddata == NULL) {
-        retStatus = awt_setPixels(env, dstRasterP, mlib_ImageGetData(dst));
-    }
-
-    /* Release the LUT */
-    for (i=0; i < lut_nbands; i++) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jtable[i].jArray,
-                                              (jbyte *) jtable[i].table, JNI_ABORT);
+        if (storeRasterArray(env, srcRasterP, dstRasterP, dst) < 0) {
+            retStatus = setPixelsFormMlibImage(env, dstRasterP, dst);
+        }
     }
 
     /* Release the pinned memory */
@@ -2643,7 +2691,7 @@
             }
         }
         else if (mlibImP->type == MLIB_SHORT) {
-            return awt_setPixels(env, rasterP, mlibImP->data);
+            return setPixelsFormMlibImage(env, rasterP, mlibImP);
         }
     }
     else {