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