getPixelCubic method

int getPixelCubic(
  1. num fx,
  2. num fy
)

Get the pixel using cubic interpolation for non-integer pixel coordinates.

Implementation

int getPixelCubic(num fx, num fy) {
  final x = fx.toInt() - (fx >= 0.0 ? 0 : 1);
  final px = x - 1;
  final nx = x + 1;
  final ax = x + 2;
  final y = fy.toInt() - (fy >= 0.0 ? 0 : 1);
  final py = y - 1;
  final ny = y + 1;
  final ay = y + 2;

  final dx = fx - x;
  final dy = fy - y;

  num _cubic(num dx, num Ipp, num Icp, num Inp, num Iap) =>
      Icp +
      0.5 *
          (dx * (-Ipp + Inp) +
              dx * dx * (2 * Ipp - 5 * Icp + 4 * Inp - Iap) +
              dx * dx * dx * (-Ipp + 3 * Icp - 3 * Inp + Iap));

  final Icc = getPixelSafe(x, y);

  final Ipp = px < 0 || py < 0 ? Icc : getPixelSafe(px, py);
  final Icp = px < 0 ? Icc : getPixelSafe(x, py);
  final Inp = py < 0 || nx >= width ? Icc : getPixelSafe(nx, py);
  final Iap = ax >= width || py < 0 ? Icc : getPixelSafe(ax, py);

  final Ip0 = _cubic(dx, getRed(Ipp), getRed(Icp), getRed(Inp), getRed(Iap));

  final Ip1 =
      _cubic(dx, getGreen(Ipp), getGreen(Icp), getGreen(Inp), getGreen(Iap));
  final Ip2 =
      _cubic(dx, getBlue(Ipp), getBlue(Icp), getBlue(Inp), getBlue(Iap));
  final Ip3 =
      _cubic(dx, getAlpha(Ipp), getAlpha(Icp), getAlpha(Inp), getAlpha(Iap));

  final Ipc = px < 0 ? Icc : getPixelSafe(px, y);
  final Inc = nx >= width ? Icc : getPixelSafe(nx, y);
  final Iac = ax >= width ? Icc : getPixelSafe(ax, y);

  final Ic0 = _cubic(dx, getRed(Ipc), getRed(Icc), getRed(Inc), getRed(Iac));
  final Ic1 =
      _cubic(dx, getGreen(Ipc), getGreen(Icc), getGreen(Inc), getGreen(Iac));
  final Ic2 =
      _cubic(dx, getBlue(Ipc), getBlue(Icc), getBlue(Inc), getBlue(Iac));
  final Ic3 =
      _cubic(dx, getAlpha(Ipc), getAlpha(Icc), getAlpha(Inc), getAlpha(Iac));

  final Ipn = px < 0 || ny >= height ? Icc : getPixelSafe(px, ny);
  final Icn = ny >= height ? Icc : getPixelSafe(x, ny);
  final Inn = nx >= width || ny >= height ? Icc : getPixelSafe(nx, ny);
  final Ian = ax >= width || ny >= height ? Icc : getPixelSafe(ax, ny);

  final In0 = _cubic(dx, getRed(Ipn), getRed(Icn), getRed(Inn), getRed(Ian));
  final In1 =
      _cubic(dx, getGreen(Ipn), getGreen(Icn), getGreen(Inn), getGreen(Ian));
  final In2 =
      _cubic(dx, getBlue(Ipn), getBlue(Icn), getBlue(Inn), getBlue(Ian));
  final In3 =
      _cubic(dx, getAlpha(Ipn), getAlpha(Icn), getAlpha(Inn), getAlpha(Ian));

  final Ipa = px < 0 || ay >= height ? Icc : getPixelSafe(px, ay);
  final Ica = ay >= height ? Icc : getPixelSafe(x, ay);
  final Ina = nx >= width || ay >= height ? Icc : getPixelSafe(nx, ay);
  final Iaa = ax >= width || ay >= height ? Icc : getPixelSafe(ax, ay);

  final Ia0 = _cubic(dx, getRed(Ipa), getRed(Ica), getRed(Ina), getRed(Iaa));
  final Ia1 =
      _cubic(dx, getGreen(Ipa), getGreen(Ica), getGreen(Ina), getGreen(Iaa));
  final Ia2 =
      _cubic(dx, getBlue(Ipa), getBlue(Ica), getBlue(Ina), getBlue(Iaa));
  final Ia3 =
      _cubic(dx, getAlpha(Ipa), getAlpha(Ica), getAlpha(Ina), getAlpha(Iaa));

  final c0 = _cubic(dy, Ip0, Ic0, In0, Ia0);
  final c1 = _cubic(dy, Ip1, Ic1, In1, Ia1);
  final c2 = _cubic(dy, Ip2, Ic2, In2, Ia2);
  final c3 = _cubic(dy, Ip3, Ic3, In3, Ia3);

  return getColor(c0.toInt(), c1.toInt(), c2.toInt(), c3.toInt());
}