1/*
2 * Copyright (C) 2015 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#pragma version(1)
18#pragma rs java_package_name(com.android.example.cannylive)
19#pragma rs_fp_relaxed
20
21rs_allocation gCurrentFrame;     // yuv
22rs_allocation gCurrentRGBFrame;  // RGB
23rs_allocation blurImage;         // uchar
24rs_allocation edgeImage;         // uchar
25
26ushort __attribute__((kernel)) black_ushort() { return 0; }
27uchar __attribute__((kernel)) black_uchar() { return 0; }
28uchar4 __attribute__((kernel)) black_uchar4() { return 0; }
29
30uchar4 __attribute__((kernel)) toRGB(uint32_t x, uint32_t y) {
31  ushort v = rsGetElementAt_uchar(edgeImage, x, y);
32
33  if (true) {
34    uchar charv = clamp(v * 10, 0, 255);
35    uchar4 out = {charv, charv, charv, 255};
36    return out;
37  }
38}
39uchar4 __attribute__((kernel)) toWhiteRGB(uint32_t x, uint32_t y) {
40  ushort v = rsGetElementAt_uchar(edgeImage, x, y);
41
42  uchar charv = 255 - clamp(v * 10, 0, 255);
43  uchar4 out = {charv, charv, charv, 255};
44  return out;
45}
46uchar4 __attribute__((kernel)) toRGBfuzz(uint32_t x, uint32_t y) {
47  ushort v = rsGetElementAt_uchar(blurImage, x, y);
48
49  if (true) {
50    uchar charv = clamp(v * 10, 0, 255);
51    uchar4 out = {charv, charv, charv, 255};
52    return out;
53  }
54}
55uchar4 __attribute__((kernel)) toWhiteRGBfuzz(uint32_t x, uint32_t y) {
56  ushort v = rsGetElementAt_uchar(blurImage, x, y);
57
58  uchar charv = 255 - clamp(v * 10, 0, 255);
59  uchar4 out = {charv, charv, charv, 255};
60  return out;
61}
62
63uchar4 __attribute__((kernel)) toRGBCartoon(uchar4 in, uint32_t x, uint32_t y) {
64  ushort v = rsGetElementAt_uchar(blurImage, x, y);
65
66  return in - (uchar)(v * 10);
67}
68
69uchar4 __attribute__((kernel)) toCartoon(uint32_t x, uint32_t y) {
70  ushort v = rsGetElementAt_uchar(blurImage, x, y);
71
72  uchar4 yuv;
73  yuv.r =
74      clamp(rsGetElementAtYuv_uchar_Y(gCurrentFrame, x, y) - v * 10, 0, 255);
75
76  yuv.g = rsGetElementAtYuv_uchar_U(gCurrentFrame, x, y);
77  yuv.b = rsGetElementAtYuv_uchar_V(gCurrentFrame, x, y);
78  yuv.a = 255;
79
80  int4 rgb;
81  rgb.r = yuv.r + yuv.b * 1436 / 1024 - 179;
82  rgb.g = yuv.r - yuv.g * 46549 / 131072 + 44 - yuv.b * 93604 / 131072 + 91;
83  rgb.b = yuv.r + yuv.g * 1814 / 1024 - 227;
84  rgb.a = 255;
85
86  // Write out merged HDR result
87  uchar4 out = convert_uchar4(clamp(rgb, 0, 255));
88  return out;
89}
90
91static ushort getY(rs_allocation a, int x, int y) {
92  ushort3 v = convert_ushort3(rsGetElementAt_uchar4(a, x, y).xyz);
93  return v.x + v.y + v.z;
94}
95
96uchar __attribute__((kernel)) getLum(uchar4 in) {
97  return (in.x + in.y + in.z) / 3;
98}
99
100uchar __attribute__((kernel)) getyuv_y(uint32_t x, uint32_t y) {
101  return rsGetElementAtYuv_uchar_Y(gCurrentFrame, x, y);
102}
103
104uchar __attribute__((kernel)) blur_uchar(uint32_t x, uint32_t y) {
105  ushort sum = 0;
106  int x1 = x - 2;
107  int y1 = y - 2;
108  sum += 2 * rsGetElementAt_uchar(edgeImage, x1++, y1);
109  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
110  sum += 5 * rsGetElementAt_uchar(edgeImage, x1++, y1);
111  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
112  sum += 2 * rsGetElementAt_uchar(edgeImage, x1++, y1);
113  x1 = x - 2;
114  y1++;
115  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
116  sum += 9 * rsGetElementAt_uchar(edgeImage, x1++, y1);
117  sum += 12 * rsGetElementAt_uchar(edgeImage, x1++, y1);
118  sum += 9 * rsGetElementAt_uchar(edgeImage, x1++, y1);
119  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
120
121  x1 = x - 2;
122  y1++;
123  sum += 5 * rsGetElementAt_uchar(edgeImage, x1++, y1);
124  sum += 12 * rsGetElementAt_uchar(edgeImage, x1++, y1);
125  sum += 15 * rsGetElementAt_uchar(edgeImage, x1++, y1);
126  sum += 12 * rsGetElementAt_uchar(edgeImage, x1++, y1);
127  sum += 5 * rsGetElementAt_uchar(edgeImage, x1++, y1);
128
129  x1 = x - 2;
130  y1++;
131  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
132  sum += 9 * rsGetElementAt_uchar(edgeImage, x1++, y1);
133  sum += 12 * rsGetElementAt_uchar(edgeImage, x1++, y1);
134  sum += 9 * rsGetElementAt_uchar(edgeImage, x1++, y1);
135  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
136
137  x1 = x - 2;
138  y1++;
139  sum += 2 * rsGetElementAt_uchar(edgeImage, x1++, y1);
140  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
141  sum += 5 * rsGetElementAt_uchar(edgeImage, x1++, y1);
142  sum += 4 * rsGetElementAt_uchar(edgeImage, x1++, y1);
143  sum += 2 * rsGetElementAt_uchar(edgeImage, x1++, y1);
144
145  return (uchar)(sum / 159);
146}
147
148ushort __attribute__((kernel)) blurRGB(uint32_t x, uint32_t y) {
149  ushort sum = 0;
150  int x1 = x - 2;
151  int y1 = y - 2;
152  sum += 2 * getY(gCurrentRGBFrame, x1++, y1);
153  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
154  sum += 5 * getY(gCurrentRGBFrame, x1++, y1);
155  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
156  sum += 2 * getY(gCurrentRGBFrame, x1++, y1);
157  x1 = x - 2;
158  y1++;
159  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
160  sum += 9 * getY(gCurrentRGBFrame, x1++, y1);
161  sum += 12 * getY(gCurrentRGBFrame, x1++, y1);
162  sum += 9 * getY(gCurrentRGBFrame, x1++, y1);
163  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
164
165  x1 = x - 2;
166  y1++;
167  sum += 5 * getY(gCurrentRGBFrame, x1++, y1);
168  sum += 12 * getY(gCurrentRGBFrame, x1++, y1);
169  sum += 15 * getY(gCurrentRGBFrame, x1++, y1);
170  sum += 12 * getY(gCurrentRGBFrame, x1++, y1);
171  sum += 5 * getY(gCurrentRGBFrame, x1++, y1);
172
173  x1 = x - 2;
174  y1++;
175  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
176  sum += 9 * getY(gCurrentRGBFrame, x1++, y1);
177  sum += 12 * getY(gCurrentRGBFrame, x1++, y1);
178  sum += 9 * getY(gCurrentRGBFrame, x1++, y1);
179  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
180
181  x1 = x - 2;
182  y1++;
183  sum += 2 * getY(gCurrentRGBFrame, x1++, y1);
184  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
185  sum += 5 * getY(gCurrentRGBFrame, x1++, y1);
186  sum += 4 * getY(gCurrentRGBFrame, x1++, y1);
187  sum += 2 * getY(gCurrentRGBFrame, x1++, y1);
188
189  return sum / 159;
190}
191
192ushort __attribute__((kernel)) blur(uint32_t x, uint32_t y) {
193  ushort sum = 0;
194  int x1 = x - 2;
195  int y1 = y - 2;
196  sum += 2 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
197  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
198  sum += 5 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
199  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
200  sum += 2 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
201  x1 = x - 2;
202  y1++;
203  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
204  sum += 9 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
205  sum += 12 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
206  sum += 9 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
207  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
208
209  x1 = x - 2;
210  y1++;
211  sum += 5 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
212  sum += 12 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
213  sum += 15 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
214  sum += 12 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
215  sum += 5 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
216
217  x1 = x - 2;
218  y1++;
219  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
220  sum += 9 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
221  sum += 12 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
222  sum += 9 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
223  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
224
225  x1 = x - 2;
226  y1++;
227  sum += 2 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
228  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
229  sum += 5 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
230  sum += 4 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
231  sum += 2 * rsGetElementAtYuv_uchar_Y(gCurrentFrame, x1++, y1);
232
233  return sum / 159;
234}
235
236uchar __attribute__((kernel)) edge(uint32_t x, uint32_t y) {
237  int sum_h = 0;
238  int x1 = x - 1;
239  int y1 = y - 1;
240  sum_h += -rsGetElementAt_uchar(blurImage, x1, y1);
241  x += 2;
242  sum_h += rsGetElementAt_uchar(blurImage, x1, y1);
243  x1 = x - 1;
244  y1++;
245
246  sum_h += -2 * rsGetElementAt_uchar(blurImage, x1, y1);
247  x1 += 2;
248  sum_h += 2 * rsGetElementAt_uchar(blurImage, x1, y1);
249  x1 = x - 1;
250  y1++;
251
252  sum_h += -rsGetElementAt_uchar(blurImage, x1, y1);
253  x1 += 2;
254  sum_h += rsGetElementAt_uchar(blurImage, x1, y1);
255  int sum_v = 0;
256
257  x1 = x - 1;
258  y1 = y - 1;
259  sum_v += -rsGetElementAt_uchar(blurImage, x1++, y1);
260  sum_v += -2 * rsGetElementAt_uchar(blurImage, x1++, y1);
261  sum_v += -rsGetElementAt_uchar(blurImage, x1++, y1);
262
263  x1 = x - 1;
264  y1 += 2;
265  sum_v += rsGetElementAt_uchar(blurImage, x1++, y1);
266  sum_v += 2 * rsGetElementAt_uchar(blurImage, x1++, y1);
267  sum_v += rsGetElementAt_uchar(blurImage, x1++, y1);
268  int v = (int)native_hypot((float)sum_v, (float)sum_h);
269  v = v & (~3);
270  int dir = (int)(4 * native_atan2pi((float)sum_v, (float)sum_h) + 8.5f);
271
272  return (uchar)(v + (dir & 0x3));
273}
274
275uchar __attribute__((kernel)) thin(uint32_t x, uint32_t y) {
276  int value = rsGetElementAt_uchar(edgeImage, x, y);
277
278  int dir = value & 0x3;
279  int dx[4] = {1, 1, 0, 1};
280  int dy[4] = {0, 1, 1, -1};
281  if (value < rsGetElementAt_uchar(edgeImage, x + dx[dir], y + dy[dir])) {
282    return 0;
283  }
284  if (value < rsGetElementAt_uchar(edgeImage, x - dx[dir], y - dy[dir])) {
285    return 0;
286  }
287  return value >> 2;
288}
289
290static const short dark_line = 4;
291static const short bright_line = 16;
292#define q_add(v)                 \
293  {                              \
294    if (q_size < 64) {           \
295      queue[q_start & 0x3F] = v; \
296      q_start++;                 \
297      q_size++;                  \
298    }                            \
299  }
300#define q_peak() (queue[q_peek_pos & 0x3F])
301#define q_pop() (q_size--, q_tmp = queue[q_end], q_end++, q_tmp)
302
303uchar __attribute__((kernel)) hysteresis(uchar in, uint32_t x, uint32_t y) {
304  short3 queue[64];
305  int q_start = 0;
306  int q_end = 0;
307  int q_size = 0;
308  short3 q_tmp;
309  int q_peek_pos = 0;
310  int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1};
311  int dy[] = {-1, -1, -1, 0, 0, 1, 1, 1};
312  if (in < dark_line) {
313    return 0;
314  }
315  if (in >= bright_line) {
316    return in;
317  }
318  short3 p = {0, 0, 1};
319  q_add(p);
320
321  while (q_peek_pos != q_start) {
322    if (q_size > 60) {
323      return 0;
324    }
325    p = q_peak();
326    q_peek_pos++;
327    short cdx = p[0];
328    short cdy = p[1];
329
330    int p_dist = p.z;
331    short v;
332    while (queue[q_end & 0x3F].z < p_dist - 1) {
333      q_pop();
334    }
335    for (int i = 0; i < 8; i++) {
336      int tx = cdx + dx[i];
337      int ty = cdy + dy[i];
338      bool skip = false;
339      for (int k = q_end; k < q_start; k++) {
340        short3 tq = queue[k & 0x3F];
341        if (tq.x == tx && tq.y == ty) {
342          skip = true;
343          break;
344        }
345      }
346      if (!(tx + x >= -5 && tx <= 5 && ty >= -5 && ty <= 5)) {
347        skip = true;
348      }
349      if (skip) continue;
350
351      v = rsGetElementAt_uchar(edgeImage, tx + x, ty + y);
352      if (v >= bright_line) {
353        return in;
354      }
355      if (v >= dark_line) {
356        short3 tmp = {tx, ty, p_dist + 1};
357        q_add(tmp);
358      }
359      q_peek_pos = (q_peek_pos + 1) & 0x3F;
360    }
361  }
362  return 0;
363}
364
365rs_allocation hough_output;  // width * height
366
367static inline float2 cos_sin(int n) {
368  float2 cs[] = {{1.0f,0.0f},
369                                  {0.9999619f,0.008726535f},{0.9998477f,0.017452406f},{0.99965733f,0.026176948f},
370                                  {0.99939084f,0.034899496f},{0.99904823f,0.043619387f},{0.9986295f,0.052335955f},
371                                  {0.9981348f,0.06104854f},{0.9975641f,0.06975647f},{0.9969173f,0.0784591f},
372                                  {0.9961947f,0.087155744f},{0.9953962f,0.09584575f},{0.9945219f,0.104528464f},
373                                  {0.9935719f,0.11320321f},{0.99254614f,0.12186934f},{0.9914449f,0.13052619f},
374                                  {0.99026805f,0.1391731f},{0.9890159f,0.14780942f},{0.98768836f,0.15643446f},
375                                  {0.9862856f,0.1650476f},{0.9848077f,0.17364818f},{0.9832549f,0.18223552f},
376                                  {0.98162717f,0.190809f},{0.9799247f,0.19936794f},{0.9781476f,0.20791169f},
377                                  {0.976296f,0.21643962f},{0.97437006f,0.22495106f},{0.9723699f,0.23344536f},
378                                  {0.9702957f,0.2419219f},{0.96814764f,0.25038f},{0.9659258f,0.25881904f},
379                                  {0.96363044f,0.26723838f},{0.9612617f,0.27563736f},{0.95881975f,0.28401536f},
380                                  {0.9563047f,0.2923717f},{0.95371693f,0.3007058f},{0.95105654f,0.309017f},
381                                  {0.94832367f,0.31730467f},{0.94551855f,0.32556817f},{0.9426415f,0.33380687f},
382                                  {0.9396926f,0.34202015f},{0.9366722f,0.3502074f},{0.9335804f,0.35836795f},
383                                  {0.9304176f,0.3665012f},{0.92718387f,0.37460658f},{0.9238795f,0.38268343f},
384                                  {0.92050487f,0.39073113f},{0.9170601f,0.39874908f},{0.9135454f,0.40673664f},
385                                  {0.9099613f,0.41469324f},{0.9063078f,0.42261827f},{0.90258527f,0.4305111f},
386                                  {0.89879405f,0.43837115f},{0.89493436f,0.4461978f},{0.8910065f,0.4539905f},
387                                  {0.8870108f,0.4617486f},{0.88294756f,0.46947157f},{0.87881714f,0.47715876f},
388                                  {0.8746197f,0.4848096f},{0.8703557f,0.49242356f},{0.8660254f,0.5f},
389                                  {0.8616292f,0.5075384f},{0.8571673f,0.5150381f},{0.85264015f,0.52249855f},
390                                  {0.8480481f,0.52991927f},{0.8433914f,0.53729963f},{0.83867055f,0.54463905f},
391                                  {0.83388585f,0.551937f},{0.82903755f,0.5591929f},{0.8241262f,0.56640625f},
392                                  {0.81915206f,0.57357645f},{0.8141155f,0.58070296f},{0.809017f,0.58778524f},
393                                  {0.80385685f,0.59482276f},{0.7986355f,0.60181504f},{0.7933533f,0.6087614f},
394                                  {0.7880108f,0.6156615f},{0.78260815f,0.62251467f},{0.777146f,0.6293204f},
395                                  {0.77162457f,0.63607824f},{0.76604444f,0.64278764f},{0.76040596f,0.64944804f},
396                                  {0.7547096f,0.656059f},{0.7489557f,0.66262007f},{0.7431448f,0.6691306f},
397                                  {0.7372773f,0.6755902f},{0.7313537f,0.6819984f},{0.7253744f,0.68835455f},
398                                  {0.7193398f,0.6946584f},{0.71325046f,0.70090926f},{0.70710677f,0.70710677f},
399                                  {0.70090926f,0.71325046f},{0.6946584f,0.7193398f},{0.68835455f,0.7253744f},
400                                  {0.6819984f,0.7313537f},{0.6755902f,0.7372773f},{0.6691306f,0.7431448f},
401                                  {0.66262007f,0.7489557f},{0.656059f,0.7547096f},{0.64944804f,0.76040596f},
402                                  {0.64278764f,0.76604444f},{0.63607824f,0.77162457f},{0.6293204f,0.777146f},
403                                  {0.62251467f,0.78260815f},{0.6156615f,0.7880108f},{0.6087614f,0.7933533f},
404                                  {0.60181504f,0.7986355f},{0.59482276f,0.80385685f},{0.58778524f,0.809017f},
405                                  {0.58070296f,0.8141155f},{0.57357645f,0.81915206f},{0.56640625f,0.8241262f},
406                                  {0.5591929f,0.82903755f},{0.551937f,0.83388585f},{0.54463905f,0.83867055f},
407                                  {0.53729963f,0.8433914f},{0.52991927f,0.8480481f},{0.52249855f,0.85264015f},
408                                  {0.5150381f,0.8571673f},{0.5075384f,0.8616292f},{0.5f,0.8660254f},
409                                  {0.49242356f,0.8703557f},{0.4848096f,0.8746197f},{0.47715876f,0.87881714f},
410                                  {0.46947157f,0.88294756f},{0.4617486f,0.8870108f},{0.4539905f,0.8910065f},
411                                  {0.4461978f,0.89493436f},{0.43837115f,0.89879405f},{0.4305111f,0.90258527f},
412                                  {0.42261827f,0.9063078f},{0.41469324f,0.9099613f},{0.40673664f,0.9135454f},
413                                  {0.39874908f,0.9170601f},{0.39073113f,0.92050487f},{0.38268343f,0.9238795f},
414                                  {0.37460658f,0.92718387f},{0.3665012f,0.9304176f},{0.35836795f,0.9335804f},
415                                  {0.3502074f,0.9366722f},{0.34202015f,0.9396926f},{0.33380687f,0.9426415f},
416                                  {0.32556817f,0.94551855f},{0.31730467f,0.94832367f},{0.309017f,0.95105654f},
417                                  {0.3007058f,0.95371693f},{0.2923717f,0.9563047f},{0.28401536f,0.95881975f},
418                                  {0.27563736f,0.9612617f},{0.26723838f,0.96363044f},{0.25881904f,0.9659258f},
419                                  {0.25038f,0.96814764f},{0.2419219f,0.9702957f},{0.23344536f,0.9723699f},
420                                  {0.22495106f,0.97437006f},{0.21643962f,0.976296f},{0.20791169f,0.9781476f},
421                                  {0.19936794f,0.9799247f},{0.190809f,0.98162717f},{0.18223552f,0.9832549f},
422                                  {0.17364818f,0.9848077f},{0.1650476f,0.9862856f},{0.15643446f,0.98768836f},
423                                  {0.14780942f,0.9890159f},{0.1391731f,0.99026805f},{0.13052619f,0.9914449f},
424                                  {0.12186934f,0.99254614f},{0.11320321f,0.9935719f},{0.104528464f,0.9945219f},
425                                  {0.09584575f,0.9953962f},{0.087155744f,0.9961947f},{0.0784591f,0.9969173f},
426                                  {0.06975647f,0.9975641f},{0.06104854f,0.9981348f},{0.052335955f,0.9986295f},
427                                  {0.043619387f,0.99904823f},{0.034899496f,0.99939084f},{0.026176948f,0.99965733f},
428                                  {0.017452406f,0.9998477f},{0.008726535f,0.9999619f},{6.123234E-17f,1.0f},
429                                  {-0.008726535f,0.9999619f},{-0.017452406f,0.9998477f},{-0.026176948f,0.99965733f},
430                                  {-0.034899496f,0.99939084f},{-0.043619387f,0.99904823f},{-0.052335955f,0.9986295f},
431                                  {-0.06104854f,0.9981348f},{-0.06975647f,0.9975641f},{-0.0784591f,0.9969173f},
432                                  {-0.087155744f,0.9961947f},{-0.09584575f,0.9953962f},{-0.104528464f,0.9945219f},
433                                  {-0.11320321f,0.9935719f},{-0.12186934f,0.99254614f},{-0.13052619f,0.9914449f},
434                                  {-0.1391731f,0.99026805f},{-0.14780942f,0.9890159f},{-0.15643446f,0.98768836f},
435                                  {-0.1650476f,0.9862856f},{-0.17364818f,0.9848077f},{-0.18223552f,0.9832549f},
436                                  {-0.190809f,0.98162717f},{-0.19936794f,0.9799247f},{-0.20791169f,0.9781476f},
437                                  {-0.21643962f,0.976296f},{-0.22495106f,0.97437006f},{-0.23344536f,0.9723699f},
438                                  {-0.2419219f,0.9702957f},{-0.25038f,0.96814764f},{-0.25881904f,0.9659258f},
439                                  {-0.26723838f,0.96363044f},{-0.27563736f,0.9612617f},{-0.28401536f,0.95881975f},
440                                  {-0.2923717f,0.9563047f},{-0.3007058f,0.95371693f},{-0.309017f,0.95105654f},
441                                  {-0.31730467f,0.94832367f},{-0.32556817f,0.94551855f},{-0.33380687f,0.9426415f},
442                                  {-0.34202015f,0.9396926f},{-0.3502074f,0.9366722f},{-0.35836795f,0.9335804f},
443                                  {-0.3665012f,0.9304176f},{-0.37460658f,0.92718387f},{-0.38268343f,0.9238795f},
444                                  {-0.39073113f,0.92050487f},{-0.39874908f,0.9170601f},{-0.40673664f,0.9135454f},
445                                  {-0.41469324f,0.9099613f},{-0.42261827f,0.9063078f},{-0.4305111f,0.90258527f},
446                                  {-0.43837115f,0.89879405f},{-0.4461978f,0.89493436f},{-0.4539905f,0.8910065f},
447                                  {-0.4617486f,0.8870108f},{-0.46947157f,0.88294756f},{-0.47715876f,0.87881714f},
448                                  {-0.4848096f,0.8746197f},{-0.49242356f,0.8703557f},{-0.5f,0.8660254f},
449                                  {-0.5075384f,0.8616292f},{-0.5150381f,0.8571673f},{-0.52249855f,0.85264015f},
450                                  {-0.52991927f,0.8480481f},{-0.53729963f,0.8433914f},{-0.54463905f,0.83867055f},
451                                  {-0.551937f,0.83388585f},{-0.5591929f,0.82903755f},{-0.56640625f,0.8241262f},
452                                  {-0.57357645f,0.81915206f},{-0.58070296f,0.8141155f},{-0.58778524f,0.809017f},
453                                  {-0.59482276f,0.80385685f},{-0.60181504f,0.7986355f},{-0.6087614f,0.7933533f},
454                                  {-0.6156615f,0.7880108f},{-0.62251467f,0.78260815f},{-0.6293204f,0.777146f},
455                                  {-0.63607824f,0.77162457f},{-0.64278764f,0.76604444f},{-0.64944804f,0.76040596f},
456                                  {-0.656059f,0.7547096f},{-0.66262007f,0.7489557f},{-0.6691306f,0.7431448f},
457                                  {-0.6755902f,0.7372773f},{-0.6819984f,0.7313537f},{-0.68835455f,0.7253744f},
458                                  {-0.6946584f,0.7193398f},{-0.70090926f,0.71325046f},{-0.70710677f,0.70710677f},
459                                  {-0.71325046f,0.70090926f},{-0.7193398f,0.6946584f},{-0.7253744f,0.68835455f},
460                                  {-0.7313537f,0.6819984f},{-0.7372773f,0.6755902f},{-0.7431448f,0.6691306f},
461                                  {-0.7489557f,0.66262007f},{-0.7547096f,0.656059f},{-0.76040596f,0.64944804f},
462                                  {-0.76604444f,0.64278764f},{-0.77162457f,0.63607824f},{-0.777146f,0.6293204f},
463                                  {-0.78260815f,0.62251467f},{-0.7880108f,0.6156615f},{-0.7933533f,0.6087614f},
464                                  {-0.7986355f,0.60181504f},{-0.80385685f,0.59482276f},{-0.809017f,0.58778524f},
465                                  {-0.8141155f,0.58070296f},{-0.81915206f,0.57357645f},{-0.8241262f,0.56640625f},
466                                  {-0.82903755f,0.5591929f},{-0.83388585f,0.551937f},{-0.83867055f,0.54463905f},
467                                  {-0.8433914f,0.53729963f},{-0.8480481f,0.52991927f},{-0.85264015f,0.52249855f},
468                                  {-0.8571673f,0.5150381f},{-0.8616292f,0.5075384f},{-0.8660254f,0.5f},
469                                  {-0.8703557f,0.49242356f},{-0.8746197f,0.4848096f},{-0.87881714f,0.47715876f},
470                                  {-0.88294756f,0.46947157f},{-0.8870108f,0.4617486f},{-0.8910065f,0.4539905f},
471                                  {-0.89493436f,0.4461978f},{-0.89879405f,0.43837115f},{-0.90258527f,0.4305111f},
472                                  {-0.9063078f,0.42261827f},{-0.9099613f,0.41469324f},{-0.9135454f,0.40673664f},
473                                  {-0.9170601f,0.39874908f},{-0.92050487f,0.39073113f},{-0.9238795f,0.38268343f},
474                                  {-0.92718387f,0.37460658f},{-0.9304176f,0.3665012f},{-0.9335804f,0.35836795f},
475                                  {-0.9366722f,0.3502074f},{-0.9396926f,0.34202015f},{-0.9426415f,0.33380687f},
476                                  {-0.94551855f,0.32556817f},{-0.94832367f,0.31730467f},{-0.95105654f,0.309017f},
477                                  {-0.95371693f,0.3007058f},{-0.9563047f,0.2923717f},{-0.95881975f,0.28401536f},
478                                  {-0.9612617f,0.27563736f},{-0.96363044f,0.26723838f},{-0.9659258f,0.25881904f},
479                                  {-0.96814764f,0.25038f},{-0.9702957f,0.2419219f},{-0.9723699f,0.23344536f},
480                                  {-0.97437006f,0.22495106f},{-0.976296f,0.21643962f},{-0.9781476f,0.20791169f},
481                                  {-0.9799247f,0.19936794f},{-0.98162717f,0.190809f},{-0.9832549f,0.18223552f},
482                                  {-0.9848077f,0.17364818f},{-0.9862856f,0.1650476f},{-0.98768836f,0.15643446f},
483                                  {-0.9890159f,0.14780942f},{-0.99026805f,0.1391731f},{-0.9914449f,0.13052619f},
484                                  {-0.99254614f,0.12186934f},{-0.9935719f,0.11320321f},{-0.9945219f,0.104528464f},
485                                  {-0.9953962f,0.09584575f},{-0.9961947f,0.087155744f},{-0.9969173f,0.0784591f},
486                                  {-0.9975641f,0.06975647f},{-0.9981348f,0.06104854f},{-0.9986295f,0.052335955f},
487                                  {-0.99904823f,0.043619387f},{-0.99939084f,0.034899496f},{-0.99965733f,0.026176948f},
488                                  {-0.9998477f,0.017452406f},{-0.9999619f,0.008726535f},};
489  return cs[n];
490}
491
492uchar4 __attribute__((kernel)) hough_map(uint32_t x, uint32_t y) {
493  int w = rsAllocationGetDimX(hough_output);
494  int h = rsAllocationGetDimY(hough_output);
495  int ix = clamp((int)x, 0, w - 1);
496  int iy = clamp((int)y, 0, h - 1);
497  int v = rsGetElementAt_uchar(hough_output, ix, iy);
498  uchar4 out = {clamp(v * 5, 0, 255), clamp(v, 0, 255), clamp(v, 0, 255), 255};
499  return out;
500}
501
502/* input is the range of angles to cover */
503void __attribute__((kernel)) hough(int2 in) {
504  int max_pos = rsAllocationGetDimX(hough_output);
505  int pos_shift = max_pos >> 1;
506  int start = in.x;
507  int end = in.y;
508  int width = rsAllocationGetDimX(edgeImage);
509  int height = rsAllocationGetDimY(edgeImage);
510  float half_height = height >> 1;
511  float half_width = width >> 1;
512  for (int iy = 0; iy < height; iy++) {
513    for (int ix = 0; ix < width; ix++) {
514      if (rsGetElementAt_uchar(edgeImage, ix, iy) > 20) {
515        float2 pos = {ix - half_width, iy - half_height};
516        for (int ang = start; ang < end; ang++) {
517          int r = pos_shift + (int)dot(pos, cos_sin(ang));
518          if (r >= 0 && r < max_pos) {
519            ushort tmp = rsGetElementAt_uchar(hough_output, r, ang);
520            rsSetElementAt_uchar(hough_output, tmp + 1, r, ang);
521          }
522        }
523      }
524    }
525  }
526}
527
528uchar __attribute__((kernel)) hough_thin(uchar in, int x, int y) {
529  short tmp = rsGetElementAt_ushort(hough_output, x - 1, y - 1);
530  if (tmp > in) return 0;
531  tmp = rsGetElementAt_uchar(hough_output, x + 1, y + 1);
532  if (tmp > in) return 0;
533
534  tmp = rsGetElementAt_uchar(hough_output, x, y - 1);
535  if (tmp > in) return 0;
536  tmp = rsGetElementAt_uchar(hough_output, x + 1, y - 1);
537  if (tmp > in) return 0;
538
539  tmp = rsGetElementAt_uchar(hough_output, x - 1, y);
540  if (tmp > in) return 0;
541
542  tmp = rsGetElementAt_uchar(hough_output, x + 1, y);
543  if (tmp > in) return 0;
544
545  tmp = rsGetElementAt_uchar(hough_output, x - 1, y + 1);
546  if (tmp > in) return 0;
547  tmp = rsGetElementAt_uchar(hough_output, x, y + 1);
548  if (tmp > in) return 0;
549  return in;
550}
551