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

608c44
608c44
608c44
typedef void (*BlendFunc)(double *dst, double *src, double val);
608c44
608c44
608c44
void bfuncCopy(double *dst, double *src, double val)
608c44
  { memcpy(dst, src, 4*sizeof(double)); }
608c44
608c44
void bfuncMix(double *dst, double *src, double val) {
608c44
  double iv = 1 - val;
608c44
  dst[0] = dst[0]*iv + src[0]*val;
608c44
  dst[1] = dst[1]*iv + src[1]*val;
608c44
  dst[2] = dst[2]*iv + src[2]*val;
608c44
  dst[3] = dst[3]*iv + src[3]*val;
608c44
}
608c44
608c44
void bfuncComposite(double *dst, double *src, double val) {
608c44
  val *= src[3];
608c44
  double iv = 1 - val;
608c44
  dst[0] = dst[0]*iv + src[0]*val;
608c44
  dst[1] = dst[1]*iv + src[1]*val;
608c44
  dst[2] = dst[2]*iv + src[2]*val;
608c44
  dst[3] = 1 - (1 - dst[3])*val;
608c44
}
608c44
608c44
void bfuncSum(double *dst, double *src, double val) {
608c44
  val *= src[3];
608c44
  dst[0] = dst[0] + src[0]*val;
608c44
  dst[1] = dst[1] + src[1]*val;
608c44
  dst[2] = dst[2] + src[2]*val;
608c44
}
608c44
608c44
void bfuncMul(double *dst, double *src, double val) {
608c44
  val *= src[3];
608c44
  double iv = 1 - val;
608c44
  dst[0] = dst[0]*iv + dst[0]*src[0]*val;
608c44
  dst[1] = dst[1]*iv + dst[1]*src[1]*val;
608c44
  dst[2] = dst[2]*iv + dst[2]*src[2]*val;
608c44
}
608c44
608c44
608c44
608c44
void filterBlendEx(Img *img, Img *src, BlendFunc func, double val, int dx, int dy, int sx, int sy, int w, int h) {
608c44
  if (!img->data || !src->data || !func) return;
608c44
608c44
  if (sx < 0) { dx -= sx; w += sx; sx = 0; }
608c44
  if (sy < 0) { dy -= sy; h += sy; sy = 0; }
608c44
  if (dx < 0) { sx -= dx; w += dx; dx = 0; }
608c44
  if (dy < 0) { sy -= dy; h += dy; dy = 0; }
608c44
608c44
  if (w > img->w - dx) w = img->w - dx;
608c44
  if (h > img->h - dy) h = img->h - dy;
608c44
  if (w > src->w - sx) w = src->w - sx;
608c44
  if (h > src->h - sy) h = src->h - sy;
608c44
608c44
  if (w <= 0 || h <= 0) return;
608c44
  int dr = 4*(img->w - w);
608c44
  int sr = 4*(src->w - w);
608c44
608c44
  if (img == src) {
608c44
    int offset = ((sy - dy)*img->w + sx - dx)*4;
608c44
    if (offset > 0) {
608c44
      for(double *pd = imgPixel(img, dx, dy), *e = pd + 4*h*img->w; pd < e; pd += dr)
608c44
        for(double *re = pd + 4*w; pd < re; pd += 4)
608c44
          func(pd, pd + offset, val);
608c44
    } else
608c44
    if (offset < 0) {
608c44
      for(double *pd = imgPixel(img, dx+w-1, dy+h-1), *e = pd - 4*h*img->w; pd > e; pd -= dr)
608c44
        for(double *re = pd - 4*w; pd > re; pd -= 4)
608c44
          func(pd, pd + offset, val);
608c44
    } else {
608c44
      double ps[4];
608c44
      for(double *pd = imgPixel(img, dx, dy), *e = pd + 4*h*img->w; pd < e; pd += dr)
608c44
        for(double *re = pd + 4*w; pd < re; pd += 4)
608c44
          { memcpy(ps, pd, sizeof(ps)); func(pd, ps, val); }
608c44
    }
608c44
  } else {
608c44
    for(double *pd = imgPixel(img, dx, dy), *ps = imgPixel(src, sx, sy), *e = pd + 4*h*img->w; pd < e; pd += dr, ps += sr)
608c44
      for(double *re = pd + 4*w; pd < re; pd += 4, ps += 4)
608c44
        func(pd, ps, val);
608c44
  }
608c44
}
608c44
608c44
void filterBlend(Img *img, Img *src, BlendFunc func, double val)
608c44
  { filterBlendEx(img, src, func, val, 0, 0, 0, 0, src->w, src->h); }
608c44
608c44
608c44
608c44
608c44
void imgCopyTo(Img *img, Img *src, int dx, int dy, int sx, int sy, int w, int h)
608c44
  { filterBlendEx(img, src, bfuncCopy, 1, dx, dy, sx, sy, w, h); }
608c44
608c44
void imgCropTo(Img *img, Img *src, int x, int y, int w, int h) {
608c44
  imgInit(img, w, h);
608c44
  imgCopyTo(img, src, 0, 0, x, y, w, h);
608c44
}
608c44
608c44
void imgCrop(Img *img, int x, int y, int w, int h) {
608c44
  Img imgC = {};
608c44
  imgSwap(img, &imgC);
608c44
  imgCropTo(img, &imgC, x, y, w, h);
608c44
  imgDestroy(&imgC);
608c44
}
608c44
608c44
void imgCopy(Img *img, Img *src)
608c44
  { imgCropTo(img, src, 0, 0, src->w, src->h); }