oilify.cl.h 10.2 KB
Newer Older
Victor Oliveira's avatar
Victor Oliveira committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
static const char* oilify_cl_source =
"/* two small different kernels are better than one big */                     \n"
"                                                                              \n"
"#define NUM_INTENSITIES 256                                                   \n"
"                                                                              \n"
"kernel void kernel_oilify(global float4 *in,                                  \n"
"                             global float4 *out,                              \n"
"                             const int mask_radius,                           \n"
"                             const int intensities,                           \n"
"                             const float exponent)                            \n"
"{                                                                             \n"
"  int gidx = get_global_id(0);                                                \n"
"  int gidy = get_global_id(1);                                                \n"
"  int x = gidx + mask_radius;                                                 \n"
"  int y = gidy + mask_radius;                                                 \n"
"  int dst_width = get_global_size(0);                                         \n"
"  int src_width = dst_width + mask_radius * 2;                                \n"
"  float4 hist[NUM_INTENSITIES];                                               \n"
"  float4 hist_max = 1.0;                                                      \n"
"  int i, j, intensity;                                                        \n"
"  int radius_sq = mask_radius * mask_radius;                                  \n"
"  float4 temp_pixel;                                                          \n"
"  for (i = 0; i < intensities; i++)                                           \n"
"    hist[i] = 0.0;                                                            \n"
"                                                                              \n"
"  for (i = -mask_radius; i <= mask_radius; i++)                               \n"
"  {                                                                           \n"
"    for (j = -mask_radius; j <= mask_radius; j++)                             \n"
"      {                                                                       \n"
"        if (i*i + j*j <= radius_sq)                                           \n"
"          {                                                                   \n"
"            temp_pixel = in[x + i + (y + j) * src_width];                     \n"
"            hist[(int)(temp_pixel.x * (intensities - 1))].x+=1;               \n"
"            hist[(int)(temp_pixel.y * (intensities - 1))].y+=1;               \n"
"            hist[(int)(temp_pixel.z * (intensities - 1))].z+=1;               \n"
"            hist[(int)(temp_pixel.w * (intensities - 1))].w+=1;               \n"
"          }                                                                   \n"
"      }                                                                       \n"
"  }                                                                           \n"
"                                                                              \n"
"  for (i = 0; i < intensities; i++) {                                         \n"
"    if(hist_max.x < hist[i].x)                                                \n"
"      hist_max.x = hist[i].x;                                                 \n"
"    if(hist_max.y < hist[i].y)                                                \n"
"      hist_max.y = hist[i].y;                                                 \n"
"    if(hist_max.z < hist[i].z)                                                \n"
"      hist_max.z = hist[i].z;                                                 \n"
"    if(hist_max.w < hist[i].w)                                                \n"
"      hist_max.w = hist[i].w;                                                 \n"
"  }                                                                           \n"
"  float4 div = 0.0;                                                           \n"
"  float4 sum = 0.0;                                                           \n"
"  float4 ratio, weight;                                                       \n"
"  for (i = 0; i < intensities; i++)                                           \n"
"  {                                                                           \n"
"    ratio = hist[i] / hist_max;                                               \n"
"    weight = pow(ratio, (float4)exponent);                                    \n"
"    sum += weight * (float4)i;                                                \n"
"    div += weight;                                                            \n"
"  }                                                                           \n"
"  out[gidx + gidy * dst_width] = sum / div / (float)(intensities - 1);        \n"
"}                                                                             \n"
"                                                                              \n"
"kernel void kernel_oilify_inten(global float4 *in,                            \n"
"                             global float4 *out,                              \n"
"                             const int mask_radius,                           \n"
"                             const int intensities,                           \n"
"                             const float exponent)                            \n"
"{                                                                             \n"
"  int gidx = get_global_id(0);                                                \n"
"  int gidy = get_global_id(1);                                                \n"
"  int x = gidx + mask_radius;                                                 \n"
"  int y = gidy + mask_radius;                                                 \n"
"  int dst_width = get_global_size(0);                                         \n"
"  int src_width = dst_width + mask_radius * 2;                                \n"
"  float4 cumulative_rgb[NUM_INTENSITIES];                                     \n"
"  int hist_inten[NUM_INTENSITIES], inten_max;                                 \n"
"  int i, j, intensity;                                                        \n"
"  int radius_sq = mask_radius * mask_radius;                                  \n"
"  float4 temp_pixel;                                                          \n"
"  for (i = 0; i < intensities; i++)                                           \n"
"  {                                                                           \n"
"    hist_inten[i] = 0;                                                        \n"
"    cumulative_rgb[i] = 0.0;                                                  \n"
"  }                                                                           \n"
"  for (i = -mask_radius; i <= mask_radius; i++)                               \n"
"  {                                                                           \n"
"    for (j = -mask_radius; j <= mask_radius; j++)                             \n"
"      {                                                                       \n"
"        if (i*i + j*j <= radius_sq)                                           \n"
"          {                                                                   \n"
"            temp_pixel = in[x + i + (y + j) * src_width];                     \n"
"            /*Calculate intensity on the fly, GPU does it fast*/              \n"
"            intensity = (int)((0.299 * temp_pixel.x                           \n"
"                      +0.587 * temp_pixel.y                                   \n"
"                      +0.114 * temp_pixel.z) * (float)(intensities-1));       \n"
"            hist_inten[intensity] += 1;                                       \n"
"            cumulative_rgb[intensity] += temp_pixel;                          \n"
"          }                                                                   \n"
"      }                                                                       \n"
"  }                                                                           \n"
"  inten_max = 1;                                                              \n"
"                                                                              \n"
"  /* calculated maximums */                                                   \n"
"  for (i = 0; i < intensities; i++) {                                         \n"
"    if(hist_inten[i] > inten_max)                                             \n"
"      inten_max = hist_inten[i];                                              \n"
"  }                                                                           \n"
"  float div = 0.0;                                                            \n"
"  float ratio, weight, mult_inten;                                            \n"
"                                                                              \n"
"  float4 color = 0.0;                                                         \n"
"  for (i = 0; i < intensities; i++)                                           \n"
"  {                                                                           \n"
"    if (hist_inten[i] > 0)                                                    \n"
"    {                                                                         \n"
"      ratio = (float)(hist_inten[i]) / (float)(inten_max);                    \n"
"      weight = pow(ratio, exponent);                                          \n"
"      mult_inten = weight / (float)(hist_inten[i]);                           \n"
"                                                                              \n"
"      div += weight;                                                          \n"
"      color += mult_inten * cumulative_rgb[i];                                \n"
"    }                                                                         \n"
"  }                                                                           \n"
"  out[gidx + gidy * dst_width] = color/div;                                   \n"
"}                                                                             \n"
;