|
|
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 |
|