Blob Blame Raw


double calcCurvePointEx(double *curveX, int stepX, double *curveY, int stepY, int count, double x) {
  if (count <= 0) return 0;
  if (count == 1) return *curveY;
  if (x <= curveX[0]) return *curveY;
  if (x >= curveX[(count-1)*stepX]) return curveY[(count-1)*stepY];

  int i = 0;
  while(i+1 < count && curveX[(i+1)*stepX] < x)
    ++i;

  int i0 = i > 0 ? i-1 : i;
  int i1 = i;
  int i2 = i1+1 < count ? i1+1 : i1;
  int i3 = i2+1 < count ? i2+1 : i2;

  double p0[] = { curveX[i0*stepX], curveY[i0*stepY] };
  double p1[] = { curveX[i1*stepX], curveY[i1*stepY] };
  double p2[] = { curveX[i2*stepX], curveY[i2*stepY] };
  double p3[] = { curveX[i3*stepX], curveY[i3*stepY] };

  double dx = p2[0] - p1[0];
  if (dx <= IMG_PRECISION) return p1[1];

  double a = p1[1];
  double b = p2[1];
  double ta = p2[0]-p0[0]; ta = ta > IMG_PRECISION ? (p2[1]-p0[1])/ta*dx : 0;
  double tb = p3[0]-p1[0]; tb = tb > IMG_PRECISION ? (p3[1]-p1[1])/tb*dx : 0;
  double l = (x - p1[0])/dx;

  return a + (ta + (3*(b-a)-ta-ta-tb + (2*(a-b)+ta+tb)*l)*l)*l;
}


double calcCurvePoint(double *curve, int count, double x)
  { return calcCurvePointEx(curve, 2, curve+1, 2, count, x); }


double calcTCurvePointEx(
  double *curveX, int stepX,
  double *curveY, int stepY,
  double *curveT, int stepT,
  int count, double x)
{
  if (count <= 0) return 0;
  if (count == 1) return *curveY;
  if (x <= curveX[0]) return *curveY;
  if (x >= curveX[(count-1)*stepX]) return curveY[(count-1)*stepY];

  int i0 = 0, i1 = 1;
  while(i1+1 < count && curveX[i1*stepX] < x)
    ++i0, ++i1;

  double x0 = curveX[i0*stepX];
  double x1 = curveX[i1*stepX];
  double dx = x1 - x0;
  if (dx <= IMG_PRECISION) return curveY[i0*stepY];

  double a  = curveY[i0*stepY];
  double b  = curveY[i1*stepY];
  double ta = curveT[i0*stepT]*dx;
  double tb = curveT[i1*stepT]*dx;
  double l = (x - x0)/dx;

  return a + (ta + (3*(b-a)-ta-ta-tb + (2*(a-b)+ta+tb)*l)*l)*l;
}


double calcTCurvePoint(double *curve, int count, double x)
  { return calcTCurvePointEx(curve, 3, curve+1, 3, curve+2, 3, count, x); }



void filterRasterizeCurve(Img *img, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double v = calcCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
    for(int y = 0; y < img->h; ++y) {
      double *p = imgPixel(img, x, y);
      p[0] = p[1] = p[2] = p[3] = v;
    }
  }
}


void filterRasterizeCurveCh(Img *img, int ch, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double v = calcCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
    for(int y = 0; y < img->h; ++y)
      imgPixel(img, x, y)[ch] = v;
  }
}


void filterRasterizeCurveColor(Img *img, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double l = l0 + (l1 - l0)*x/(img->w - 1);
    double c[] = {
      calcCurvePointEx(curve, 5, curve+1, 5, count, l),
      calcCurvePointEx(curve, 5, curve+2, 5, count, l),
      calcCurvePointEx(curve, 5, curve+3, 5, count, l),
      calcCurvePointEx(curve, 5, curve+4, 5, count, l) };
    for(int y = 0; y < img->h; ++y)
      memcpy(imgPixel(img, x, y), c, sizeof(c));
  }
}


void filterRasterizeTCurve(Img *img, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double v = calcTCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
    for(int y = 0; y < img->h; ++y) {
      double *p = imgPixel(img, x, y);
      p[0] = p[1] = p[2] = p[3] = v;
    }
  }
}


void filterRasterizeTCurveCh(Img *img, int ch, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double v = calcTCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
    for(int y = 0; y < img->h; ++y)
      imgPixel(img, x, y)[ch] = v;
  }
}


void filterRasterizeTCurveColor(Img *img, double *curve, int count, double l0, double l1) {
  if (!img->data) return;
  for(int x = 0; x < img->w; ++x) {
    double l = l0 + (l1 - l0)*x/(img->w - 1);
    double c[] = {
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+2, 6, count, l),
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+3, 6, count, l),
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+4, 6, count, l),
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+5, 6, count, l) };
    for(int y = 0; y < img->h; ++y)
      memcpy(imgPixel(img, x, y), c, sizeof(c));
  }
}