void filterFill(Img *img, double *pix) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4)
memcpy(p, pix, sizeof(double)*4);
}
void filterFillCh(Img *img, int ch, double val) {
if (!img->data) return;
for(double *p = img->data + ch, *e = p + 4*img->w*img->h; p < e; p += 4)
*p = val;
}
void filterMin(Img *img, double *pix) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
if (!(p[0] >= pix[0])) p[0] = pix[0];
if (!(p[1] >= pix[1])) p[1] = pix[1];
if (!(p[2] >= pix[2])) p[2] = pix[2];
if (!(p[3] >= pix[3])) p[3] = pix[3];
}
}
void filterMinCh(Img *img, int ch, double val) {
if (!img->data) return;
for(double *p = img->data + ch, *e = p + 4*img->w*img->h; p < e; p += 4)
if (!(*p <= val)) *p = val;
}
void filterMax(Img *img, double *pix) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
if (!(p[0] <= pix[0])) p[0] = pix[0];
if (!(p[1] <= pix[1])) p[1] = pix[1];
if (!(p[2] <= pix[2])) p[2] = pix[2];
if (!(p[3] <= pix[3])) p[3] = pix[3];
}
}
void filterMaxCh(Img *img, int ch, double val) {
if (!img->data) return;
for(double *p = img->data + ch, *e = p + 4*img->w*img->h; p < e; p += 4)
if (!(*p <= val)) *p = val;
}
void filterClampEx(Img *img, double *pmin, double *pmax) {
filterMax(img, pmax);
filterMin(img, pmin);
}
void filterClamp(Img *img) {
double pmin[4] = {}, pmax[4] = { 1, 1, 1, 1 };
filterClampEx(img, pmin, pmax);
}
void filterClampCh(Img *img, int ch, double vmin, double vmax) {
filterMaxCh(img, ch, vmax);
filterMinCh(img, ch, vmin);
}
void filterMulAlpha(Img *img) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
double a = p[3];
p[0] *= a; p[1] *= a; p[2] *= a;
}
}
void filterDivAlpha(Img *img) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
double k = p[3];
k = fabs(k) > IMG_PRECISION ? 1/k : 0;
p[0] *= k; p[1] *= k; p[2] *= k;
}
}
void filterResampleCubic(Img *img, int w, int h) {
Img imgC = {};
imgInit(&imgC, w, h);
imgSwap(img, &imgC);
if (img->data && imgC.data) {
double kx = (double)imgC.w/img->w;
double ky = (double)imgC.h/img->h;
for(int y = 0; y < img->h; ++y)
for(int x = 0; x < img->w; ++x)
imgCubic(&imgC, x*kx, y*ky, imgPixel(img, x, y));
}
imgDestroy(&imgC);
}
void filterCurve(Img *img, Img *icurve) {
if (!img->data || !icurve->data) return;
double k = icurve->w;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
p[0] = imgCubicHCh(icurve, 0, p[0]*k, 0);
p[1] = imgCubicHCh(icurve, 1, p[1]*k, 0);
p[2] = imgCubicHCh(icurve, 2, p[2]*k, 0);
p[3] = imgCubicHCh(icurve, 3, p[3]*k, 0);
}
}
void filterCurveCh(Img *img, Img *icurve, int dstCh, int srcCh, int curveCh) {
if (!img->data || !icurve->data) return;
double k = icurve->w;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4)
p[dstCh] = imgCubicHCh(icurve, curveCh, p[srcCh]*k, 0);
}
void filterCurveByCh(Img *img, Img *icurve, int ch) {
if (!img->data || !icurve->data) return;
double k = icurve->w;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4)
imgCubicH(icurve, p[ch]*k, 0, p);
}
void filterPow(Img *img, double val) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
p[0] = pow(p[0], val);
p[1] = pow(p[1], val);
p[2] = pow(p[2], val);
p[3] = pow(p[3], val);
}
}
void filterPowCh(Img *img, int ch, double val) {
if (!img->data) return;
for(double *p = img->data + ch, *e = p + 4*img->w*img->h; p < e; p += 4)
*p = pow(*p, val);
}
void filterScreenToCompositeHSV(Img *img) {
if (!img->data) return;
for(double *p = img->data, *e = p + 4*img->w*img->h; p < e; p += 4) {
rgbToHsv(p, p);
p[3] = p[2]; p[2] = 1;
hsvToRgb(p, p);
}
}