1 /* Copyright (C) 2005-2011 Fabio Riccardi */
2 
3 typedef unsigned char byte;
4 typedef unsigned short ushort;
5 
6 #include <stdlib.h>
7 #include <math.h>
8 #include <omp.h>
9 #include "../include/mathlz.h"
10 
11 #include <jni.h>
12 
13 #ifndef AUTO_DEP
14 #include "javah/com_lightcrafts_jai_opimage_RGBColorSelectionMaskOpImage.h"
15 #endif
16 
17 template <typename T1, typename T2, typename T1j, typename T2j>
loop(JNIEnv * env,T1j jsrcData,T2j jdstData,jint width,jint height,jintArray jsrcBandOffsets,jint dstOffset,jint srcLineStride,jint dstLineStride,jfloatArray jcolorSelection,jboolean inverted)18 void loop
19 (JNIEnv *env, T1j jsrcData, T2j jdstData,
20  jint width, jint height, jintArray jsrcBandOffsets,
21  jint dstOffset, jint srcLineStride, jint dstLineStride,
22  jfloatArray jcolorSelection, jboolean inverted)
23 {
24     T1 *srcData = (T1 *) env->GetPrimitiveArrayCritical(jsrcData, 0);
25     T2 *dstData = (T2 *) env->GetPrimitiveArrayCritical(jdstData, 0);
26     int *srcBandOffsets = (int *) env->GetPrimitiveArrayCritical(jsrcBandOffsets, 0);
27     float *colorSelection = (float *) env->GetPrimitiveArrayCritical(jcolorSelection, 0);
28 
29     int srcROffset = srcBandOffsets[0];
30     int srcGOffset = srcBandOffsets[1];
31     int srcBOffset = srcBandOffsets[2];
32 
33     float sL                        = colorSelection[0];
34     float sa                        = colorSelection[1];
35     float sb                        = colorSelection[2];
36     float radius                    = colorSelection[3];
37     float luminosityLower           = colorSelection[4];
38     float luminosityLowerFeather    = colorSelection[5];
39     float luminosityUpper           = colorSelection[6];
40     float luminosityUpperFeather    = colorSelection[7];
41 
42 #if _OPENMP < 201307
43 #pragma omp parallel for schedule (guided)
44 #else
45 #pragma omp parallel for simd schedule (guided)
46 #endif
47     for (int row = 0; row < height; row++) {
48         for (int col = 0; col < width; col++) {
49             float L = srcData[3 * col + row * srcLineStride + srcROffset];
50             float a = srcData[3 * col + row * srcLineStride + srcGOffset] / (float) 0xffff;
51             float b = srcData[3 * col + row * srcLineStride + srcBOffset] / (float) 0xffff;
52 
53             float brightnessMask, colorMask;
54 
55             if (radius >= 0) {
56                 const float rmin = 3 * radius / 16;
57                 const float rmax = 5 * radius / 16;
58 
59                 float da = sa - a;
60                 float db = sb - b;
61                 float m = da * da + db * db;
62                 m = m * inv_sqrt(m);
63                 if (m < rmin)
64                     colorMask = 1;
65                 else if (m < rmax)
66                     colorMask = (rmax - m) / (rmax - rmin);
67                 else
68                     colorMask = 0;
69             } else
70                 colorMask = 1;
71 
72             if (luminosityLower > 0 || luminosityUpper < 1) {
73 #if defined(__ppc__)
74 	            float luminosity = log2f(L / 0x100 + 1)/8;
75 #else
76                 float luminosity = fast_log2(L / 256.0F + 1.0F)/8;
77 #endif
78                 if (luminosity > 1)
79                     luminosity = 1;
80 
81                 if (luminosity >= luminosityLower && luminosity <= luminosityUpper)
82                     brightnessMask = 1;
83                 else if (luminosity >= (luminosityLower - luminosityLowerFeather) && luminosity < luminosityLower)
84                     brightnessMask = (luminosity - (luminosityLower - luminosityLowerFeather))/luminosityLowerFeather;
85                 else if (luminosity > luminosityUpper && luminosity <= (luminosityUpper + luminosityUpperFeather))
86                     brightnessMask = (luminosityUpper + luminosityUpperFeather - luminosity)/luminosityUpperFeather;
87                 else
88                     brightnessMask = 0;
89 
90                 colorMask *= brightnessMask;
91             }
92 
93             if (inverted)
94                 colorMask = 1-colorMask;
95 
96             dstData[col + row * dstLineStride + dstOffset] = (T2) (0xff * colorMask);
97         }
98     }
99 
100     env->ReleasePrimitiveArrayCritical(jsrcData, srcData, 0);
101     env->ReleasePrimitiveArrayCritical(jdstData, dstData, 0);
102     env->ReleasePrimitiveArrayCritical(jsrcBandOffsets, srcBandOffsets, 0);
103     env->ReleasePrimitiveArrayCritical(jcolorSelection, colorSelection, 0);
104 }
105 
Java_com_lightcrafts_jai_opimage_RGBColorSelectionMaskOpImage_nativeIntLoop(JNIEnv * env,jobject cls,jintArray jsrcData,jintArray jdstData,jint width,jint height,jintArray jsrcBandOffsets,jint dstOffset,jint srcLineStride,jint dstLineStride,jfloatArray jcolorSelection,jboolean inverted)106 JNIEXPORT void JNICALL Java_com_lightcrafts_jai_opimage_RGBColorSelectionMaskOpImage_nativeIntLoop
107 (JNIEnv *env, jobject cls, jintArray jsrcData, jintArray jdstData,
108  jint width, jint height, jintArray jsrcBandOffsets,
109  jint dstOffset, jint srcLineStride, jint dstLineStride,
110  jfloatArray jcolorSelection, jboolean inverted)
111 {
112     loop<int, int>(env, jsrcData, jdstData,
113             width, height, jsrcBandOffsets,
114             dstOffset, srcLineStride, dstLineStride,
115             jcolorSelection, inverted);
116 }
117 
Java_com_lightcrafts_jai_opimage_RGBColorSelectionMaskOpImage_nativeUshortLoop(JNIEnv * env,jobject cls,jshortArray jsrcData,jbyteArray jdstData,jint width,jint height,jintArray jsrcBandOffsets,jint dstOffset,jint srcLineStride,jint dstLineStride,jfloatArray jcolorSelection,jboolean inverted)118 JNIEXPORT void JNICALL Java_com_lightcrafts_jai_opimage_RGBColorSelectionMaskOpImage_nativeUshortLoop
119 (JNIEnv *env, jobject cls, jshortArray jsrcData, jbyteArray jdstData,
120  jint width, jint height, jintArray jsrcBandOffsets,
121  jint dstOffset, jint srcLineStride, jint dstLineStride,
122  jfloatArray jcolorSelection, jboolean inverted)
123 {
124     loop<ushort, byte>(env, jsrcData, jdstData,
125             width, height, jsrcBandOffsets,
126             dstOffset, srcLineStride, dstLineStride,
127             jcolorSelection, inverted);
128 }
129 
130