Blob Blame Raw



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