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.example.android.rs.sample) 19 #pragma rs_fp_relaxed 20 21 /** 22 This describes the algorithm that uses the code 23 This takes polygon and image to copy from(src_image) and and image to paste to(dest_image) 24 25 void __attribute__((invoke_cpu)) findBestFit(rs_allocation poly, 26 rs_allocation src_image, 27 rs_allocation dest_image) { 28 int width = rsAllocationGetDimX(src_image); 29 int height = rsAllocationGetDimY(src_image); 30 mask = alloc_uchar(width, height, 0); 31 src = alloc_float3(width height, 0); 32 dest1 = alloc_float3(width height, 0); 33 dest2 = alloc_float3(width height, 0); 34 mask = alloc_uchar(width, height, 0); 35 foreach_convert_to_f(src_image, src); 36 laplace = alloc_float3(width, height, 0); 37 LaunchOptions options; 38 options.setX(1, width-1); 39 options.setY(1, height-1); 40 forEach_laplacian(laplace, options); 41 forEach_copyMasked(mask, dest1); 42 int steps = (int) sqrt(calcMaskArea()); 43 for (int i = 0; i < steps; i++) { 44 forEach_solve1(mask, dest2); 45 forEach_solve2(mask, dest1); 46 } 47 forEach_convert_to_uc(dest1, dest_image); 48 forEach_alphaMask(dest_image, dest_image); 49 } 50 51 52 int calcMaskArea(Allocation mask) { 53 int width = rsAllocationGetDimX(mask); 54 int height = rsAllocationGetDimY(mask); 55 int count = 0; 56 int val = rsGetElementAt_uchar(mask,0,0); 57 for (int y = 0; y < height; y++) { 58 for (int x = 0; x < width; x++) { 59 if (val != rsGetElementAt_uchar(mask, x, y) ) { 60 count++; 61 } 62 } 63 } 64 return count; 65 } 66 67 */ 68 69 typedef rs_allocation AllocationF32_3; 70 71 AllocationF32_3 src; 72 73 float3 __attribute__((kernel)) laplacian( uint32_t x, uint32_t y) { 74 float3 out = 4 * rsGetElementAt_float3(src, x, y); 75 out -= rsGetElementAt_float3(src, x - 1, y); 76 out -= rsGetElementAt_float3(src, x + 1, y); 77 out -= rsGetElementAt_float3(src, x, y -1 ); 78 out -= rsGetElementAt_float3(src, x, y + 1); 79 return out; 80 } 81 82 rs_allocation mask; // uchar 83 AllocationF32_3 laplace; // float3 84 AllocationF32_3 dest1; // float3 85 AllocationF32_3 dest2; // float3 86 87 float3 __attribute__((kernel)) convert_to_f(uchar4 in) { 88 return convert_float3(in.xyz); 89 } 90 91 float3 __attribute__((kernel)) copyMasked(uchar in, uint32_t x, uint32_t y) { 92 return rsGetElementAt_float3((in>0) ? src : dest1, x, y); 93 } 94 95 uchar4 __attribute__((kernel)) convert_to_uc(float3 in) { 96 in = clamp(in, 0.0f, 255.0f); 97 return convert_uchar4((float4){in.x, in.y, in.z, 0xFF}); 98 } 99 100 uchar4 __attribute__((kernel)) alphaMask(uchar4 in, uint32_t x, uint32_t y) { 101 if (rsGetElementAt_uchar(mask,x,y) == 0) { 102 return (uchar4){0, 0, 0, 0}; 103 } 104 105 return in; 106 } 107 108 float3 __attribute__((kernel)) solve1(uchar in, uint32_t x, uint32_t y) { 109 if (in > 0) { 110 float3 k = rsGetElementAt_float3(dest1, x - 1, y); 111 k += rsGetElementAt_float3(dest1, x + 1, y); 112 k += rsGetElementAt_float3(dest1, x, y - 1); 113 k += rsGetElementAt_float3(dest1, x, y + 1); 114 k += rsGetElementAt_float3(laplace, x, y); 115 k /= 4; 116 return k; 117 } 118 return rsGetElementAt_float3(dest1, x, y);; 119 } 120 121 122 float3 __attribute__((kernel)) solve2(uchar in, uint32_t x, uint32_t y) { 123 if (in > 0) { 124 float3 k = rsGetElementAt_float3(dest2, x - 1, y); 125 k += rsGetElementAt_float3(dest2, x + 1, y); 126 k += rsGetElementAt_float3(dest2, x, y - 1); 127 k += rsGetElementAt_float3(dest2, x, y + 1); 128 k += rsGetElementAt_float3(laplace, x, y); 129 k /= 4; 130 return k; 131 } 132 return rsGetElementAt_float3(dest2, x, y);; 133 } 134 135 rs_allocation image; 136 rs_allocation border; // float3 137 rs_allocation border_coords; //int2 138 int borderLength; 139 140 float3 __attribute__((kernel))extractBorder(int2 in) { 141 return convert_float3(rsGetElementAt_uchar4(image, in.x, in.y).xyz); 142 } 143 144 float __attribute__((kernel)) bordercorrelation(uint32_t x, uint32_t y) { 145 float sum = 0; 146 for(int i = 0 ; i < borderLength; i++) { 147 int2 coord = rsGetElementAt_int2(border_coords,i); 148 float3 orig = convert_float3(rsGetElementAt_uchar4(image, coord.x + x, coord.y + y).xyz); 149 float3 candidate = rsGetElementAt_float3(border, i).xyz; 150 sum += distance(orig, candidate); 151 } 152 return sum; 153 } 154