Imaging ImagingGaussianBlur(Imaging im, Imaging imOut, float radius) { int channels = 0; int padding = 0; if (strcmp(im->mode, "RGB") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "RGBA") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "RGBX") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "CMYK") == 0) { channels = 4; padding = 0; } else if (strcmp(im->mode, "L") == 0) { channels = 1; padding = 0; } else return ImagingError_ModeError(); return gblur(im, imOut, radius, channels, padding); }
void fill_random_field(float *f, int w, int h, float sigma, float eta) { for (int i = 0; i < w * h * 2; i++) f[i] = sigma*random_normal(); void gblur(float *y, float *x, int w, int h, int pd, float s); gblur(f, f, w, h, 2, eta); }
Imaging ImagingUnsharpMask(Imaging im, Imaging imOut, float radius, int percent, int threshold) { ImagingSectionCookie cookie; Imaging result; int channel = 0; int channels = 0; int padding = 0; int x = 0; int y = 0; int *lineIn = NULL; int *lineOut = NULL; UINT8 *lineIn8 = NULL; UINT8 *lineOut8 = NULL; int diff = 0; INT32 newPixel = 0; if (strcmp(im->mode, "RGB") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "RGBA") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "RGBX") == 0) { channels = 3; padding = 1; } else if (strcmp(im->mode, "CMYK") == 0) { channels = 4; padding = 0; } else if (strcmp(im->mode, "L") == 0) { channels = 1; padding = 0; } else return ImagingError_ModeError(); /* first, do a gaussian blur on the image, putting results in imOut temporarily */ result = gblur(im, imOut, radius, channels, padding); if (!result) return NULL; /* now, go through each pixel, compare "normal" pixel to blurred pixel. if the difference is more than threshold values, apply the OPPOSITE correction to the amount of blur, multiplied by percent. */ ImagingSectionEnter(&cookie); for (y = 0; y < im->ysize; y++) { if (channels == 1) { lineIn8 = im->image8[y]; lineOut8 = imOut->image8[y]; } else { lineIn = im->image32[y]; lineOut = imOut->image32[y]; } for (x = 0; x < im->xsize; x++) { newPixel = 0; /* compare in/out pixels, apply sharpening */ if (channels == 1) { diff = ((UINT8 *) & lineIn8[x])[0] - ((UINT8 *) & lineOut8[x])[0]; if (abs(diff) > threshold) { /* add the diff*percent to the original pixel */ imOut->image8[y][x] = clip((((UINT8 *) & lineIn8[x])[0]) + (diff * ((float) percent) / 100.0)); } else { /* newPixel is the same as imIn */ imOut->image8[y][x] = ((UINT8 *) & lineIn8[x])[0]; } } else { for (channel = 0; channel < channels; channel++) { diff = (int) ((((UINT8 *) & lineIn[x])[channel]) - (((UINT8 *) & lineOut[x])[channel])); if (abs(diff) > threshold) { /* add the diff*percent to the original pixel this may not work for little-endian systems, fix it! */ newPixel = newPixel | clip((float) (((UINT8 *) & lineIn[x])[channel]) + (diff * (((float) percent / 100.0)))) << (channel * 8); } else { /* newPixel is the same as imIn this may not work for little-endian systems, fix it! */ newPixel = newPixel | ((UINT8 *) & lineIn[x])[channel] << (channel * 8); } } if (strcmp(im->mode, "RGBX") == 0 || strcmp(im->mode, "RGBA") == 0) { /* preserve the alpha channel this may not work for little-endian systems, fix it! */ newPixel = newPixel | ((UINT8 *) & lineIn[x])[channel] << 24; } imOut->image32[y][x] = newPixel; } } } ImagingSectionLeave(&cookie); return imOut; }