1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <android/bitmap.h>
18 #include <jni.h>
19
20 #include <cmath>
21 #include <cstdlib>
22 #include <cstring>
23
24 #include "utils.h"
25 #include "_jni.h"
26
27 using android::apps::photoeditor::utils::clamp;
28 using android::apps::photoeditor::utils::LockBitmaps;
29 using android::apps::photoeditor::utils::pixel32_t;
30 using android::apps::photoeditor::utils::UnlockBitmaps;
31
32 namespace {
33
34 // Array of approximated CDF of normal distribution.
35 // 1024 Entries in total. The array is approximated by sigmoid function and
36 // the exact command in "octave" is:
37 // x = [2/1029:1/1029:1025/1029];
38 // y = (-1/11.5*log(1./x-0.9999)+0.5)*766*0.9+766*0.05;
39 const int kCDFEntries = 1024;
40 const uint32_t normal_cdf[] = {
41 9, 33, 50, 64, 75, 84, 92, 99, 106, 112, 117, 122, 126, 130, 134, 138, 142,
42 145, 148, 150, 154, 157, 159, 162, 164, 166, 169, 170, 173, 175, 177, 179,
43 180, 182, 184, 186, 188, 189, 190, 192, 194, 195, 197, 198, 199, 200, 202,
44 203, 205, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218, 219,
45 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 229, 230, 231, 232, 233,
46 234, 235, 236, 236, 237, 238, 239, 239, 240, 240, 242, 242, 243, 244, 245,
47 245, 246, 247, 247, 248, 249, 249, 250, 250, 251, 252, 253, 253, 254, 255,
48 255, 256, 256, 257, 258, 258, 259, 259, 259, 260, 261, 262, 262, 263, 263,
49 264, 264, 265, 265, 266, 267, 267, 268, 268, 269, 269, 269, 270, 270, 271,
50 272, 272, 273, 273, 274, 274, 275, 275, 276, 276, 277, 277, 277, 278, 278,
51 279, 279, 279, 280, 280, 281, 282, 282, 282, 283, 283, 284, 284, 285, 285,
52 285, 286, 286, 287, 287, 288, 288, 288, 289, 289, 289, 290, 290, 290, 291,
53 292, 292, 292, 293, 293, 294, 294, 294, 295, 295, 296, 296, 296, 297, 297,
54 297, 298, 298, 298, 299, 299, 299, 299, 300, 300, 301, 301, 302, 302, 302,
55 303, 303, 304, 304, 304, 305, 305, 305, 306, 306, 306, 307, 307, 307, 308,
56 308, 308, 309, 309, 309, 309, 310, 310, 310, 310, 311, 312, 312, 312, 313,
57 313, 313, 314, 314, 314, 315, 315, 315, 315, 316, 316, 316, 317, 317, 317,
58 318, 318, 318, 319, 319, 319, 319, 319, 320, 320, 320, 321, 321, 322, 322,
59 322, 323, 323, 323, 323, 324, 324, 324, 325, 325, 325, 325, 326, 326, 326,
60 327, 327, 327, 327, 328, 328, 328, 329, 329, 329, 329, 329, 330, 330, 330,
61 330, 331, 331, 332, 332, 332, 333, 333, 333, 333, 334, 334, 334, 334, 335,
62 335, 335, 336, 336, 336, 336, 337, 337, 337, 337, 338, 338, 338, 339, 339,
63 339, 339, 339, 339, 340, 340, 340, 340, 341, 341, 342, 342, 342, 342, 343,
64 343, 343, 344, 344, 344, 344, 345, 345, 345, 345, 346, 346, 346, 346, 347,
65 347, 347, 347, 348, 348, 348, 348, 349, 349, 349, 349, 349, 349, 350, 350,
66 350, 350, 351, 351, 352, 352, 352, 352, 353, 353, 353, 353, 354, 354, 354,
67 354, 355, 355, 355, 355, 356, 356, 356, 356, 357, 357, 357, 357, 358, 358,
68 358, 358, 359, 359, 359, 359, 359, 359, 359, 360, 360, 360, 360, 361, 361,
69 362, 362, 362, 362, 363, 363, 363, 363, 364, 364, 364, 364, 365, 365, 365,
70 365, 366, 366, 366, 366, 366, 367, 367, 367, 367, 368, 368, 368, 368, 369,
71 369, 369, 369, 369, 369, 370, 370, 370, 370, 370, 371, 371, 372, 372, 372,
72 372, 373, 373, 373, 373, 374, 374, 374, 374, 374, 375, 375, 375, 375, 376,
73 376, 376, 376, 377, 377, 377, 377, 378, 378, 378, 378, 378, 379, 379, 379,
74 379, 379, 379, 380, 380, 380, 380, 381, 381, 381, 382, 382, 382, 382, 383,
75 383, 383, 383, 384, 384, 384, 384, 385, 385, 385, 385, 385, 386, 386, 386,
76 386, 387, 387, 387, 387, 388, 388, 388, 388, 388, 389, 389, 389, 389, 389,
77 389, 390, 390, 390, 390, 391, 391, 392, 392, 392, 392, 392, 393, 393, 393,
78 393, 394, 394, 394, 394, 395, 395, 395, 395, 396, 396, 396, 396, 396, 397,
79 397, 397, 397, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, 400, 400,
80 400, 400, 400, 401, 401, 402, 402, 402, 402, 403, 403, 403, 403, 404, 404,
81 404, 404, 405, 405, 405, 405, 406, 406, 406, 406, 406, 407, 407, 407, 407,
82 408, 408, 408, 408, 409, 409, 409, 409, 409, 409, 410, 410, 410, 410, 411,
83 411, 412, 412, 412, 412, 413, 413, 413, 413, 414, 414, 414, 414, 415, 415,
84 415, 415, 416, 416, 416, 416, 417, 417, 417, 417, 418, 418, 418, 418, 419,
85 419, 419, 419, 419, 419, 420, 420, 420, 420, 421, 421, 422, 422, 422, 422,
86 423, 423, 423, 423, 424, 424, 424, 425, 425, 425, 425, 426, 426, 426, 426,
87 427, 427, 427, 427, 428, 428, 428, 429, 429, 429, 429, 429, 429, 430, 430,
88 430, 430, 431, 431, 432, 432, 432, 433, 433, 433, 433, 434, 434, 434, 435,
89 435, 435, 435, 436, 436, 436, 436, 437, 437, 437, 438, 438, 438, 438, 439,
90 439, 439, 439, 439, 440, 440, 440, 441, 441, 442, 442, 442, 443, 443, 443,
91 443, 444, 444, 444, 445, 445, 445, 446, 446, 446, 446, 447, 447, 447, 448,
92 448, 448, 449, 449, 449, 449, 449, 450, 450, 450, 451, 451, 452, 452, 452,
93 453, 453, 453, 454, 454, 454, 455, 455, 455, 456, 456, 456, 457, 457, 457,
94 458, 458, 458, 459, 459, 459, 459, 460, 460, 460, 461, 461, 462, 462, 462,
95 463, 463, 463, 464, 464, 465, 465, 465, 466, 466, 466, 467, 467, 467, 468,
96 468, 469, 469, 469, 469, 470, 470, 470, 471, 472, 472, 472, 473, 473, 474,
97 474, 474, 475, 475, 476, 476, 476, 477, 477, 478, 478, 478, 479, 479, 479,
98 480, 480, 480, 481, 482, 482, 483, 483, 484, 484, 484, 485, 485, 486, 486,
99 487, 487, 488, 488, 488, 489, 489, 489, 490, 490, 491, 492, 492, 493, 493,
100 494, 494, 495, 495, 496, 496, 497, 497, 498, 498, 499, 499, 499, 500, 501,
101 502, 502, 503, 503, 504, 504, 505, 505, 506, 507, 507, 508, 508, 509, 509,
102 510, 510, 511, 512, 513, 513, 514, 515, 515, 516, 517, 517, 518, 519, 519,
103 519, 520, 521, 522, 523, 524, 524, 525, 526, 526, 527, 528, 529, 529, 530,
104 531, 532, 533, 534, 535, 535, 536, 537, 538, 539, 539, 540, 542, 543, 544,
105 545, 546, 547, 548, 549, 549, 550, 552, 553, 554, 555, 556, 558, 559, 559,
106 561, 562, 564, 565, 566, 568, 569, 570, 572, 574, 575, 577, 578, 579, 582,
107 583, 585, 587, 589, 590, 593, 595, 597, 599, 602, 604, 607, 609, 612, 615,
108 618, 620, 624, 628, 631, 635, 639, 644, 649, 654, 659, 666, 673, 680, 690,
109 700, 714};
110
Java_com_android_photoeditor_filters_ImageUtils_nativeHEQ(JNIEnv * env,jobject obj,jobject src_bitmap,jobject dst_bitmap,jfloat scale)111 extern "C" JNIEXPORT void JNICALL Java_com_android_photoeditor_filters_ImageUtils_nativeHEQ(
112 JNIEnv *env, jobject obj, jobject src_bitmap, jobject dst_bitmap, jfloat scale) {
113 pHEQType f = (pHEQType)JNIFunc[JNI_HEQ].func_ptr;
114 return f(env, obj, src_bitmap, dst_bitmap, scale);
115 }
116
HEQ(JNIEnv * env,jobject obj,jobject src_bitmap,jobject dst_bitmap,jfloat scale)117 extern "C" void HEQ(
118 JNIEnv *env, jobject obj, jobject src_bitmap, jobject dst_bitmap, jfloat scale) {
119 AndroidBitmapInfo src_info;
120 AndroidBitmapInfo dst_info;
121 void* src_pixels;
122 void* dst_pixels;
123
124 int ret = LockBitmaps(
125 env, src_bitmap, dst_bitmap, &src_info, &dst_info, &src_pixels, &dst_pixels);
126 if (ret < 0) {
127 LOGE("LockBitmaps in HEQ failed, error=%d", ret);
128 return;
129 }
130
131 const int kEnergyLevels = 766; // 255 * 3 + 1
132
133 // The energy has the range of [0, kEnergyLevels]
134 int accumulated_histogram[kEnergyLevels];
135 memset(accumulated_histogram, 0, sizeof(accumulated_histogram));
136
137 // Store all the energy in the dst_pixels
138 pixel32_t* dst = reinterpret_cast<pixel32_t*>(dst_pixels);
139 pixel32_t const* src = reinterpret_cast<pixel32_t const*>(src_pixels);
140 pixel32_t const* src_end = reinterpret_cast<pixel32_t const*>(
141 reinterpret_cast<char const*>(src) + src_info.stride * src_info.height);
142 while (src < src_end) {
143 dst->rgba32 = src->rgba8[0] + src->rgba8[1] + src->rgba8[2];
144 ++src;
145 ++dst;
146 }
147
148 // Build up the accumulated histogram table by ignoring borders (1/20 = 5% width).
149 float border_thickness_ratio = 0.05;
150 int y_border_thickness = dst_info.height * border_thickness_ratio;
151 pixel32_t* dst_line = reinterpret_cast<pixel32_t*>(
152 reinterpret_cast<char*>(dst_pixels) + dst_info.stride * y_border_thickness);
153 pixel32_t* dst_line_end = reinterpret_cast<pixel32_t*>(
154 reinterpret_cast<char*>(dst_pixels) + dst_info.stride *
155 (dst_info.height - y_border_thickness));
156 int x_border_thickness = dst_info.width * border_thickness_ratio;
157 int x_border_end = dst_info.width - x_border_thickness;
158 while (dst_line < dst_line_end) {
159 pixel32_t* dp = dst_line + x_border_thickness;
160 pixel32_t* dp_end = dst_line + x_border_end;
161 while (dp < dp_end) {
162 ++accumulated_histogram[dp->rgba32];
163 ++dp;
164 }
165 dst_line = reinterpret_cast<pixel32_t*>(
166 reinterpret_cast<char*>(dst_line) + dst_info.stride);
167 }
168
169 for (int i = 1; i < kEnergyLevels; i++) {
170 accumulated_histogram[i] += accumulated_histogram[i - 1];
171 }
172
173 uint32_t const* src_line =
174 reinterpret_cast<uint32_t const*>(src_pixels);
175 dst_line = reinterpret_cast<pixel32_t*>(dst_pixels);
176 dst_line_end = reinterpret_cast<pixel32_t*>(reinterpret_cast<char*>(dst_line) +
177 dst_info.height * dst_info.stride);
178 // The whole process is done by apply the HEQ result with a mask.
179 // The mask is a curve segmented by the energy_middle which could be tuned
180 // based on each bitmap. For the lower part, the mask tries to make the change
181 // significant for greater energy. For the smaller part, the mask does the
182 // contrary. The two curve should be continuous on the energy_middle so the
183 // final result is more natural. In this implementation, what I defined is two
184 // curve based on the energy 'e', for the smaller part, e^2 is used. For the
185 // greater part, e^1.5 is used. That is, for pixel with energy 'e', the mask
186 // is obtained by:
187 // if e > energy_middle
188 // (e - energy_middle)^1.5 / (765 - energy_middle)^1.5
189 // else
190 // (e - energy_middle)^2 / (energy_middle)^2
191 const int kShiftBits = 10;
192 const int kShiftValue = (1 << kShiftBits);
193 const int scale_shifted = scale * kShiftValue;
194 const int normalization_scale_shifted = (1.0 - scale) * kShiftValue;
195 const int energy_middle = 382; // 765 / 2 = 382.5
196 const int normalization_low = 7481; // (765 - 382.5)^1.5
197 const int normalization_high = 146307; // 382.5^2
198 int total_pixels = accumulated_histogram[kEnergyLevels - 1];
199 while (dst_line < dst_line_end) {
200 pixel32_t const* sp = reinterpret_cast<pixel32_t const*>(src_line);
201 pixel32_t* dp = dst_line;
202 pixel32_t* dp_end = dp + dst_info.width;
203 while (dp < dp_end) {
204 if (!dp->rgba32) { // the energy is 0, no changes will be made.
205 dp->rgba32 = sp->rgba32;
206 } else {
207 uint32_t energy = dp->rgba32;
208 int mask_normalization;
209 int mask_value = energy - energy_middle;
210
211 if (mask_value > 0) {
212 mask_value = mask_value * sqrt(mask_value);
213 mask_normalization = normalization_low;
214 } else {
215 mask_value *= mask_value;
216 mask_normalization = normalization_high;
217 }
218 mask_value = ((mask_value * scale_shifted) +
219 (mask_normalization * (normalization_scale_shifted))) >> kShiftBits;
220 // The final picture is masked by the original energy.
221 // Assumption: Lower energy can result in low-confidence information and
222 // higher energy indicates good confidence.
223 // Therefore, pixels with low and high confidence should not be changed
224 // greatly.
225 uint32_t dst_energy = normal_cdf[
226 kCDFEntries * accumulated_histogram[energy] / total_pixels];
227 dst_energy = (energy * mask_value + dst_energy * (mask_normalization - mask_value)) /
228 mask_normalization;
229
230 // Ensure there is no RGB value will be greater than 255.
231 uint32_t max_energy = energy * 255 / MAX3(sp->rgba8[0], sp->rgba8[1], sp->rgba8[2]);
232 if (dst_energy > max_energy) {
233 dst_energy = max_energy;
234 }
235
236 dst_energy = (dst_energy << kShiftBits) / energy;
237 uint32_t dst_red = (sp->rgba8[0] * dst_energy) >> kShiftBits;
238 uint32_t dst_green = (sp->rgba8[1] * dst_energy) >> kShiftBits;
239 uint32_t dst_blue = (sp->rgba8[2] * dst_energy) >> kShiftBits;
240 dp->rgba32 = (sp->rgba8[3] << 24) | (dst_blue << 16) | (dst_green << 8) | dst_red;
241 }
242 dp++;
243 sp++;
244 }
245 src_line = reinterpret_cast<uint32_t const*>(
246 reinterpret_cast<char const*>(src_line) + src_info.stride);
247 dst_line = reinterpret_cast<pixel32_t*>(
248 reinterpret_cast<char*>(dst_line) + dst_info.stride);
249 }
250
251 UnlockBitmaps(env, src_bitmap, dst_bitmap);
252 }
253
254 } // namespace
255