blob: 08e1f39854802db76647f824636bb02ddca39e4b [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.sample)
#pragma rs_fp_relaxed
/**
This describes the algorithm that uses the code
This takes polygon and image to copy from(src_image) and and image to paste to(dest_image)
void __attribute__((invoke_cpu)) findBestFit(rs_allocation poly,
rs_allocation src_image,
rs_allocation dest_image) {
int width = rsAllocationGetDimX(src_image);
int height = rsAllocationGetDimY(src_image);
mask = alloc_uchar(width, height, 0);
src = alloc_float3(width height, 0);
dest1 = alloc_float3(width height, 0);
dest2 = alloc_float3(width height, 0);
mask = alloc_uchar(width, height, 0);
foreach_convert_to_f(src_image, src);
laplace = alloc_float3(width, height, 0);
LaunchOptions options;
options.setX(1, width-1);
options.setY(1, height-1);
forEach_laplacian(laplace, options);
forEach_copyMasked(mask, dest1);
int steps = (int) sqrt(calcMaskArea());
for (int i = 0; i < steps; i++) {
forEach_solve1(mask, dest2);
forEach_solve2(mask, dest1);
}
forEach_convert_to_uc(dest1, dest_image);
forEach_alphaMask(dest_image, dest_image);
}
int calcMaskArea(Allocation mask) {
int width = rsAllocationGetDimX(mask);
int height = rsAllocationGetDimY(mask);
int count = 0;
int val = rsGetElementAt_uchar(mask,0,0);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (val != rsGetElementAt_uchar(mask, x, y) ) {
count++;
}
}
}
return count;
}
*/
typedef rs_allocation AllocationF32_3;
AllocationF32_3 src;
float3 __attribute__((kernel)) laplacian( uint32_t x, uint32_t y) {
float3 out = 4 * rsGetElementAt_float3(src, x, y);
out -= rsGetElementAt_float3(src, x - 1, y);
out -= rsGetElementAt_float3(src, x + 1, y);
out -= rsGetElementAt_float3(src, x, y -1 );
out -= rsGetElementAt_float3(src, x, y + 1);
return out;
}
rs_allocation mask; // uchar
AllocationF32_3 laplace; // float3
AllocationF32_3 dest1; // float3
AllocationF32_3 dest2; // float3
float3 __attribute__((kernel)) convert_to_f(uchar4 in) {
return convert_float3(in.xyz);
}
float3 __attribute__((kernel)) copyMasked(uchar in, uint32_t x, uint32_t y) {
return rsGetElementAt_float3((in>0) ? src : dest1, x, y);
}
uchar4 __attribute__((kernel)) convert_to_uc(float3 in) {
in = clamp(in, 0.0f, 255.0f);
return convert_uchar4((float4){in.x, in.y, in.z, 0xFF});
}
uchar4 __attribute__((kernel)) alphaMask(uchar4 in, uint32_t x, uint32_t y) {
if (rsGetElementAt_uchar(mask,x,y) == 0) {
return (uchar4){0, 0, 0, 0};
}
return in;
}
float3 __attribute__((kernel)) solve1(uchar in, uint32_t x, uint32_t y) {
if (in > 0) {
float3 k = rsGetElementAt_float3(dest1, x - 1, y);
k += rsGetElementAt_float3(dest1, x + 1, y);
k += rsGetElementAt_float3(dest1, x, y - 1);
k += rsGetElementAt_float3(dest1, x, y + 1);
k += rsGetElementAt_float3(laplace, x, y);
k /= 4;
return k;
}
return rsGetElementAt_float3(dest1, x, y);;
}
float3 __attribute__((kernel)) solve2(uchar in, uint32_t x, uint32_t y) {
if (in > 0) {
float3 k = rsGetElementAt_float3(dest2, x - 1, y);
k += rsGetElementAt_float3(dest2, x + 1, y);
k += rsGetElementAt_float3(dest2, x, y - 1);
k += rsGetElementAt_float3(dest2, x, y + 1);
k += rsGetElementAt_float3(laplace, x, y);
k /= 4;
return k;
}
return rsGetElementAt_float3(dest2, x, y);;
}
rs_allocation image;
rs_allocation border; // float3
rs_allocation border_coords; //int2
int borderLength;
float3 __attribute__((kernel))extractBorder(int2 in) {
return convert_float3(rsGetElementAt_uchar4(image, in.x, in.y).xyz);
}
float __attribute__((kernel)) bordercorrelation(uint32_t x, uint32_t y) {
float sum = 0;
for(int i = 0 ; i < borderLength; i++) {
int2 coord = rsGetElementAt_int2(border_coords,i);
float3 orig = convert_float3(rsGetElementAt_uchar4(image, coord.x + x, coord.y + y).xyz);
float3 candidate = rsGetElementAt_float3(border, i).xyz;
sum += distance(orig, candidate);
}
return sum;
}