getPixelCubic method

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

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

Implementation

Color 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, ipp.r, icp.r, inp.r, iap.r);
  final ip1 = cubic(dx, ipp.g, icp.g, inp.g, iap.g);
  final ip2 = cubic(dx, ipp.b, icp.b, inp.b, iap.b);
  final ip3 = cubic(dx, ipp.a, icp.a, inp.a, iap.a);

  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, ipc.r, icc.r, inc.r, iac.r);
  final ic1 = cubic(dx, ipc.g, icc.g, inc.g, iac.g);
  final ic2 = cubic(dx, ipc.b, icc.b, inc.b, iac.b);
  final ic3 = cubic(dx, ipc.a, icc.a, inc.a, iac.a);

  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, ipn.r, icn.r, inn.r, ian.r);
  final in1 = cubic(dx, ipn.g, icn.g, inn.g, ian.g);
  final in2 = cubic(dx, ipn.b, icn.b, inn.b, ian.b);
  final in3 = cubic(dx, ipn.a, icn.a, inn.a, ian.a);

  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, ipa.r, ica.r, ina.r, iaa.r);
  final ia1 = cubic(dx, ipa.g, ica.g, ina.g, iaa.g);
  final ia2 = cubic(dx, ipa.b, ica.b, ina.b, iaa.b);
  final ia3 = cubic(dx, ipa.a, ica.a, ina.a, iaa.a);

  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());
}