Home | History | Annotate | Download | only in healingbrush
      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