Blame simple/imgfilters/filter.curve.inc.c

608c44
608c44
608c44
double calcCurvePointEx(double *curveX, int stepX, double *curveY, int stepY, int count, double x) {
608c44
  if (count <= 0) return 0;
608c44
  if (count == 1) return *curveY;
608c44
  if (x <= curveX[0]) return *curveY;
608c44
  if (x >= curveX[(count-1)*stepX]) return curveY[(count-1)*stepY];
608c44
608c44
  int i = 0;
608c44
  while(i+1 < count && curveX[(i+1)*stepX] < x)
608c44
    ++i;
608c44
608c44
  int i0 = i > 0 ? i-1 : i;
608c44
  int i1 = i;
608c44
  int i2 = i1+1 < count ? i1+1 : i1;
608c44
  int i3 = i2+1 < count ? i2+1 : i2;
608c44
608c44
  double p0[] = { curveX[i0*stepX], curveY[i0*stepY] };
608c44
  double p1[] = { curveX[i1*stepX], curveY[i1*stepY] };
608c44
  double p2[] = { curveX[i2*stepX], curveY[i2*stepY] };
608c44
  double p3[] = { curveX[i3*stepX], curveY[i3*stepY] };
608c44
608c44
  double dx = p2[0] - p1[0];
608c44
  if (dx <= IMG_PRECISION) return p1[1];
608c44
608c44
  double a = p1[1];
608c44
  double b = p2[1];
608c44
  double ta = p2[0]-p0[0]; ta = ta > IMG_PRECISION ? (p2[1]-p0[1])/ta*dx : 0;
608c44
  double tb = p3[0]-p1[0]; tb = tb > IMG_PRECISION ? (p3[1]-p1[1])/tb*dx : 0;
608c44
  double l = (x - p1[0])/dx;
608c44
608c44
  return a + (ta + (3*(b-a)-ta-ta-tb + (2*(a-b)+ta+tb)*l)*l)*l;
608c44
}
608c44
608c44
608c44
double calcCurvePoint(double *curve, int count, double x)
608c44
  { return calcCurvePointEx(curve, 2, curve+1, 2, count, x); }
608c44
608c44
608c44
double calcTCurvePointEx(
608c44
  double *curveX, int stepX,
608c44
  double *curveY, int stepY,
608c44
  double *curveT, int stepT,
608c44
  int count, double x)
608c44
{
608c44
  if (count <= 0) return 0;
608c44
  if (count == 1) return *curveY;
608c44
  if (x <= curveX[0]) return *curveY;
608c44
  if (x >= curveX[(count-1)*stepX]) return curveY[(count-1)*stepY];
608c44
608c44
  int i0 = 0, i1 = 1;
608c44
  while(i1+1 < count && curveX[i1*stepX] < x)
608c44
    ++i0, ++i1;
608c44
608c44
  double x0 = curveX[i0*stepX];
608c44
  double x1 = curveX[i1*stepX];
608c44
  double dx = x1 - x0;
608c44
  if (dx <= IMG_PRECISION) return curveY[i0*stepY];
608c44
608c44
  double a  = curveY[i0*stepY];
608c44
  double b  = curveY[i1*stepY];
608c44
  double ta = curveT[i0*stepT]*dx;
608c44
  double tb = curveT[i1*stepT]*dx;
608c44
  double l = (x - x0)/dx;
608c44
608c44
  return a + (ta + (3*(b-a)-ta-ta-tb + (2*(a-b)+ta+tb)*l)*l)*l;
608c44
}
608c44
608c44
608c44
double calcTCurvePoint(double *curve, int count, double x)
608c44
  { return calcTCurvePointEx(curve, 3, curve+1, 3, curve+2, 3, count, x); }
608c44
608c44
608c44
608c44
void filterRasterizeCurve(Img *img, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double v = calcCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
608c44
    for(int y = 0; y < img->h; ++y) {
608c44
      double *p = imgPixel(img, x, y);
608c44
      p[0] = p[1] = p[2] = p[3] = v;
608c44
    }
608c44
  }
608c44
}
608c44
608c44
608c44
void filterRasterizeCurveCh(Img *img, int ch, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double v = calcCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
608c44
    for(int y = 0; y < img->h; ++y)
608c44
      imgPixel(img, x, y)[ch] = v;
608c44
  }
608c44
}
608c44
608c44
608c44
void filterRasterizeCurveColor(Img *img, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double l = l0 + (l1 - l0)*x/(img->w - 1);
608c44
    double c[] = {
608c44
      calcCurvePointEx(curve, 5, curve+1, 5, count, l),
608c44
      calcCurvePointEx(curve, 5, curve+2, 5, count, l),
608c44
      calcCurvePointEx(curve, 5, curve+3, 5, count, l),
608c44
      calcCurvePointEx(curve, 5, curve+4, 5, count, l) };
608c44
    for(int y = 0; y < img->h; ++y)
608c44
      memcpy(imgPixel(img, x, y), c, sizeof(c));
608c44
  }
608c44
}
608c44
608c44
608c44
void filterRasterizeTCurve(Img *img, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double v = calcTCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
608c44
    for(int y = 0; y < img->h; ++y) {
608c44
      double *p = imgPixel(img, x, y);
608c44
      p[0] = p[1] = p[2] = p[3] = v;
608c44
    }
608c44
  }
608c44
}
608c44
608c44
608c44
void filterRasterizeTCurveCh(Img *img, int ch, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double v = calcTCurvePoint(curve, count, l0 + (l1 - l0)*x/(img->w - 1));
608c44
    for(int y = 0; y < img->h; ++y)
608c44
      imgPixel(img, x, y)[ch] = v;
608c44
  }
608c44
}
608c44
608c44
608c44
void filterRasterizeTCurveColor(Img *img, double *curve, int count, double l0, double l1) {
608c44
  if (!img->data) return;
608c44
  for(int x = 0; x < img->w; ++x) {
608c44
    double l = l0 + (l1 - l0)*x/(img->w - 1);
608c44
    double c[] = {
608c44
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+2, 6, count, l),
608c44
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+3, 6, count, l),
608c44
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+4, 6, count, l),
608c44
      calcTCurvePointEx(curve, 6, curve+1, 6, curve+5, 6, count, l) };
608c44
    for(int y = 0; y < img->h; ++y)
608c44
      memcpy(imgPixel(img, x, y), c, sizeof(c));
608c44
  }
608c44
}
608c44