text: #include "filter.h"
  
  static PyObject*
  _round_corner_apply(PyObject *self, PyObject *args)
  {
      PyObject *buffer = NULL, *image_mode = NULL, *a_radius_py = NULL, *b_radius_py = NULL,
               *width_py = NULL, *height_py = NULL, *r_py = NULL, *b_py = NULL, *g_py = NULL,
               *aa_py = NULL, *transparent_py = NULL;
  
      if (!PyArg_UnpackTuple(args, "apply", 10, 11, &aa_py, &image_mode, &a_radius_py, &b_radius_py,
              &r_py, &g_py, &b_py, &width_py, &height_py, &buffer, &transparent_py)) {
          return NULL;
      }
  
      char *image_mode_str = PyString_AsString(image_mode);
      int aa_enabled = (int)PyInt_AsLong(aa_py);
  
      unsigned char *ptr = (unsigned char *) PyString_AsString(buffer);
      int a_radius = (int) PyInt_AsLong(a_radius_py),
          b_radius = (int) PyInt_AsLong(b_radius_py),
          width = (int) PyInt_AsLong(width_py),
          height = (int) PyInt_AsLong(height_py);
  
      unsigned char r = (unsigned char) PyInt_AsLong(r_py),
                    g = (unsigned char) PyInt_AsLong(g_py),
                    b = (unsigned char) PyInt_AsLong(b_py);
  
      char transparent = 0;
      if (transparent_py != NULL) {
          transparent = (char) PyObject_IsTrue(transparent_py);
      }
  
      int num_bytes = bytes_per_pixel(image_mode_str);
  
      int r_idx = rgb_order(image_mode_str, 'R'),
          g_idx = rgb_order(image_mode_str, 'G'),
          b_idx = rgb_order(image_mode_str, 'B'),
          a_idx = rgb_order(image_mode_str, 'A');
  
      float aa_amount = .75f;
  
      if (a_radius > width / 2) {
          a_radius = width / 2;
      }
      if (b_radius > height / 2) {
          b_radius = height / 2;
      }
  
      float a_rad = (float)a_radius, b_rad = (float)b_radius;
      float x;
      int y = 0;
  
      #ifndef NDEBUG
      int image_size = width * height * num_bytes;
      #endif
  
      for (y = 0; y <= b_rad; y += 1) {
          x = (float)(-(a_rad * sqrt((b_rad * b_rad) - (y * y))) / b_rad);
  
          int curr_x = 0,
              y_top = b_rad - y,
              y_bottom = (height - b_rad) + y - 1;
          int end_x = x + a_rad;
  
          for (; curr_x < end_x; ++curr_x) {
              int top_left = num_bytes * ((y_top * width) + curr_x),
                  bottom_left = num_bytes * ((y_bottom * width) + curr_x),
                  top_right = num_bytes * ((y_top * width) + (width - curr_x)),
                  bottom_right = num_bytes * ((y_bottom * width) + (width - curr_x));
  
              assert(top_left + r_idx < image_size);
              assert(top_left + g_idx < image_size);
              assert(top_left + b_idx < image_size);
              if (transparent == 1) {
                  assert(top_left + a_idx < image_size);
              }
              assert(bottom_left + r_idx < image_size);
              assert(bottom_left + g_idx < image_size);
              assert(bottom_left + b_idx < image_size);
              if (transparent == 1) {
                  assert(bottom_left + a_idx < image_size);
              }
              ptr[top_left + r_idx] = ptr[bottom_left + r_idx] = r;
              ptr[top_left + g_idx] = ptr[bottom_left + g_idx] = g;
              ptr[top_left + b_idx] = ptr[bottom_left + b_idx] = b;
              if (transparent == 1) {
                  ptr[top_left + a_idx] = ptr[bottom_left + a_idx] = 0;
              }
  
              if (curr_x > 0) {
                  assert(top_right + r_idx < image_size);
                  assert(top_right + g_idx < image_size);
                  assert(top_right + b_idx < image_size);
                  if (transparent == 1) {
                      assert(top_right + a_idx < image_size);
                  }
                  assert(bottom_right + r_idx < image_size);
                  assert(bottom_right + g_idx < image_size);
                  assert(bottom_right + b_idx < image_size);
                  if (transparent == 1) {
                      assert(bottom_right + a_idx < image_size);
                  }
                  ptr[top_right + r_idx] = ptr[bottom_right + r_idx] = r;
                  ptr[top_right + g_idx] = ptr[bottom_right + g_idx] = g;
                  ptr[top_right + b_idx] = ptr[bottom_right + b_idx] = b;
                  if (transparent == 1) {
                      ptr[top_right + a_idx] = ptr[bottom_right + a_idx] = 0;
                  }
              }
          }
  
          if (!aa_enabled) {
              continue;
          }
  
          int last_top_left = num_bytes * ((y_top * width) + end_x),
              last_bottom_left = num_bytes * ((y_bottom * width) + end_x),
              last_top_right = num_bytes * ((y_top * width) + (width - end_x)),
              last_bottom_right = num_bytes * ((y_bottom * width) + (width - end_x));
  
          int idx = 1;
          int aa_x = x - 1;
          unsigned char *color_top_left = ptr + last_top_left,
                        *color_bottom_left = ptr + last_bottom_left,
                        *color_top_right = ptr + last_top_right,
                        *color_bottom_right = ptr + last_bottom_right;
  
  
          int pixel_count_x = 0;
  
          for (; aa_x >= (-a_rad); --aa_x) {
              int aa_y = (float)(((b_rad * sqrt(a_rad * a_rad - aa_x * aa_x)) / a_rad) + 1.f);
  
              if (aa_y != y) {
                  break;
              }
  
              ++pixel_count_x;
          }
  
          aa_x = x - pixel_count_x;
          if (aa_x < -a_rad) {
              aa_x += 1;
          }
          idx = 1;
          for (; aa_x < x; ++aa_x, ++idx) {
              int aa_x_adj = aa_x + a_rad;
              int top_left = num_bytes * ((y_top * width) + aa_x_adj),
                  bottom_left = num_bytes * ((y_bottom * width) + aa_x_adj),
                  top_right = num_bytes * ((y_top * width) + (width - aa_x_adj)),
                  bottom_right = num_bytes * ((y_bottom * width) + (width - aa_x_adj));
  
  
              float aa = 1.f - ((idx / (float)pixel_count_x) * aa_amount);
  
              if (transparent == 1) {
                  ptr[top_left + r_idx] = (color_top_left[r_idx] * (1.f - aa));
                  ptr[top_left + g_idx] = (color_top_left[g_idx] * (1.f - aa));
                  ptr[top_left + b_idx] = (color_top_left[b_idx] * (1.f - aa));
  
                  ptr[bottom_left + r_idx] = (color_bottom_left[r_idx] * (1.f - aa));
                  ptr[bottom_left + g_idx] = (color_bottom_left[g_idx] * (1.f - aa));
                  ptr[bottom_left + b_idx] = (color_bottom_left[b_idx] * (1.f - aa));
  
                  ptr[top_right + r_idx] = (color_top_right[r_idx] * (1.f - aa));
                  ptr[top_right + g_idx] = (color_top_right[g_idx] * (1.f - aa));
                  ptr[top_right + b_idx] = (color_top_right[b_idx] * (1.f - aa));
  
                  ptr[bottom_right + r_idx] = (color_bottom_right[r_idx] * (1.f - aa));
                  ptr[bottom_right + g_idx] = (color_bottom_right[g_idx] * (1.f - aa));
                  ptr[bottom_right + b_idx] = (color_bottom_right[b_idx] * (1.f - aa));
              } else {
                  ptr[top_left + r_idx] = (color_top_left[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[top_left + g_idx] = (color_top_left[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[top_left + b_idx] = (color_top_left[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[bottom_left + r_idx] = (color_bottom_left[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[bottom_left + g_idx] = (color_bottom_left[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[bottom_left + b_idx] = (color_bottom_left[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[top_right + r_idx] = (color_top_right[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[top_right + g_idx] = (color_top_right[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[top_right + b_idx] = (color_top_right[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[bottom_right + r_idx] = (color_bottom_right[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[bottom_right + g_idx] = (color_bottom_right[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[bottom_right + b_idx] = (color_bottom_right[b_idx] * (1.f - aa)) + (b * (aa));
              }
          }
  
      }
  
      if (!aa_enabled) {
          goto END;
      }
  
      for (x = 0.f; x >= -a_rad; x -= 1.f) {
          float y = (float)((b_rad * sqrt((a_rad * a_rad) - (x * x))) / a_rad);
  
          int pixel_count_y = 0;
          int aa_y = y + 1;
          for (; aa_y < b_rad; ++aa_y) {
              int aa_x = (float)(-((a_rad * sqrt((b_rad * b_rad) - (aa_y * aa_y))) / b_rad) - 1.f);
              if (aa_x != (int)x) {
                  break;
              }
  
              ++pixel_count_y;
          }
  
          int end_x = x + a_rad;
          int y_top = b_rad - y;
          int y_bottom = (height - b_rad) + y - 1;
  
          int last_top_left = num_bytes * ((y_top * width) + end_x),
              last_bottom_left = num_bytes * ((y_bottom * width) + end_x),
              last_top_right = num_bytes * ((y_top * width) + (width - end_x)),
              last_bottom_right = num_bytes * ((y_bottom * width) + (width - end_x));
  
          unsigned char *color_top_left = ptr + last_top_left,
                        *color_bottom_left = ptr + last_bottom_left,
                        *color_top_right = ptr + last_top_right,
                        *color_bottom_right = ptr + last_bottom_right;
  
          int left_x = x + a_rad;
          int right_x = width - a_rad - x;
          int idx = 1;
  
          aa_y = y + pixel_count_y;
          if (aa_y > b_rad) {
              aa_y -= 1;
          }
          for (; aa_y > y; --aa_y, ++idx) {
              int top_left = num_bytes * (((b_rad - aa_y) * width) + left_x),
                  bottom_left = num_bytes * ((((height - b_rad) + aa_y - 1) * width) + left_x),
                  top_right = num_bytes * (((b_rad - aa_y) * width) + right_x),
                  bottom_right = num_bytes * ((((height - b_rad) + aa_y - 1) * width) + right_x);
  
              float aa = 1.f - ((idx / (float)pixel_count_y) * aa_amount);
  
              if (transparent == 1) {
                  ptr[top_left + r_idx] = (color_top_left[r_idx] * (1.f - aa));
                  ptr[top_left + g_idx] = (color_top_left[g_idx] * (1.f - aa));
                  ptr[top_left + b_idx] = (color_top_left[b_idx] * (1.f - aa));
  
                  ptr[bottom_left + r_idx] = (color_bottom_left[r_idx] * (1.f - aa));
                  ptr[bottom_left + g_idx] = (color_bottom_left[g_idx] * (1.f - aa));
                  ptr[bottom_left + b_idx] = (color_bottom_left[b_idx] * (1.f - aa));
  
                  ptr[top_right + r_idx] = (color_top_right[r_idx] * (1.f - aa));
                  ptr[top_right + g_idx] = (color_top_right[g_idx] * (1.f - aa));
                  ptr[top_right + b_idx] = (color_top_right[b_idx] * (1.f - aa));
  
                  ptr[bottom_right + r_idx] = (color_bottom_right[r_idx] * (1.f - aa));
                  ptr[bottom_right + g_idx] = (color_bottom_right[g_idx] * (1.f - aa));
                  ptr[bottom_right + b_idx] = (color_bottom_right[b_idx] * (1.f - aa));
              } else {
                  ptr[top_left + r_idx] = (color_top_left[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[top_left + g_idx] = (color_top_left[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[top_left + b_idx] = (color_top_left[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[bottom_left + r_idx] = (color_bottom_left[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[bottom_left + g_idx] = (color_bottom_left[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[bottom_left + b_idx] = (color_bottom_left[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[top_right + r_idx] = (color_top_right[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[top_right + g_idx] = (color_top_right[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[top_right + b_idx] = (color_top_right[b_idx] * (1.f - aa)) + (b * (aa));
  
                  ptr[bottom_right + r_idx] = (color_bottom_right[r_idx] * (1.f - aa)) + (r * (aa));
                  ptr[bottom_right + g_idx] = (color_bottom_right[g_idx] * (1.f - aa)) + (g * (aa));
                  ptr[bottom_right + b_idx] = (color_bottom_right[b_idx] * (1.f - aa)) + (b * (aa));
              }
          }
      }
  
  END:
  
      Py_INCREF(buffer);
      return buffer;
  }
  
  FILTER_MODULE(_round_corner,
      "apply(a_radius, b_radius, r, g, b, width, height, buffer) -> string"
  )
  