+/*
+=item i_unsharp_mask(im, stddev, scale)
+
+Perform an usharp mask, which is defined as subtracting the blurred
+image from double the original.
+
+=cut
+*/
+void i_unsharp_mask(i_img *im, double stddev, double scale) {
+ i_img copy;
+ int x, y, ch;
+
+ if (scale < 0)
+ return;
+ /* it really shouldn't ever be more than 1.0, but maybe ... */
+ if (scale > 100)
+ scale = 100;
+
+ i_copy(©, im);
+ i_gaussian(©, stddev);
+ if (im->bits == i_8_bits) {
+ i_color *blur = mymalloc(im->xsize * sizeof(i_color) * 2);
+ i_color *out = blur + im->xsize;
+
+ for (y = 0; y < im->ysize; ++y) {
+ i_glin(©, 0, copy.xsize, y, blur);
+ i_glin(im, 0, im->xsize, y, out);
+ for (x = 0; x < im->xsize; ++x) {
+ for (ch = 0; ch < im->channels; ++ch) {
+ /*int temp = out[x].channel[ch] +
+ scale * (out[x].channel[ch] - blur[x].channel[ch]);*/
+ int temp = out[x].channel[ch] * 2 - blur[x].channel[ch];
+ if (temp < 0)
+ temp = 0;
+ else if (temp > 255)
+ temp = 255;
+ out[x].channel[ch] = temp;
+ }
+ }
+ i_plin(im, 0, im->xsize, y, out);
+ }
+
+ myfree(blur);
+ }
+ else {
+ i_fcolor *blur = mymalloc(im->xsize * sizeof(i_fcolor) * 2);
+ i_fcolor *out = blur + im->xsize;
+
+ for (y = 0; y < im->ysize; ++y) {
+ i_glinf(©, 0, copy.xsize, y, blur);
+ i_glinf(im, 0, im->xsize, y, out);
+ for (x = 0; x < im->xsize; ++x) {
+ for (ch = 0; ch < im->channels; ++ch) {
+ double temp = out[x].channel[ch] +
+ scale * (out[x].channel[ch] - blur[x].channel[ch]);
+ if (temp < 0)
+ temp = 0;
+ else if (temp > 1.0)
+ temp = 1.0;
+ out[x].channel[ch] = temp;
+ }
+ }
+ i_plinf(im, 0, im->xsize, y, out);
+ }
+
+ myfree(blur);
+ }
+ i_img_exorcise(©);
+}
+