UnsharpMask.c 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* PILusm, a gaussian blur and unsharp masking library for PIL
  2. By Kevin Cazabon, copyright 2003
  3. kevin_cazabon@hotmail.com
  4. kevin@cazabon.com */
  5. /* Originally released under LGPL. Graciously donated to PIL
  6. for distribution under the standard PIL license in 2009." */
  7. #include "Imaging.h"
  8. typedef UINT8 pixel[4];
  9. static inline UINT8 clip8(int in)
  10. {
  11. if (in >= 255)
  12. return 255;
  13. if (in <= 0)
  14. return 0;
  15. return (UINT8) in;
  16. }
  17. Imaging
  18. ImagingUnsharpMask(Imaging imOut, Imaging imIn, float radius, int percent,
  19. int threshold)
  20. {
  21. ImagingSectionCookie cookie;
  22. Imaging result;
  23. int x, y, diff;
  24. pixel *lineIn = NULL;
  25. pixel *lineOut = NULL;
  26. UINT8 *lineIn8 = NULL;
  27. UINT8 *lineOut8 = NULL;
  28. /* First, do a gaussian blur on the image, putting results in imOut
  29. temporarily. All format checks are in gaussian blur. */
  30. result = ImagingGaussianBlur(imOut, imIn, radius, 3);
  31. if (!result)
  32. return NULL;
  33. /* Now, go through each pixel, compare "normal" pixel to blurred
  34. pixel. If the difference is more than threshold values, apply
  35. the OPPOSITE correction to the amount of blur, multiplied by
  36. percent. */
  37. ImagingSectionEnter(&cookie);
  38. for (y = 0; y < imIn->ysize; y++) {
  39. if (imIn->image8)
  40. {
  41. lineIn8 = imIn->image8[y];
  42. lineOut8 = imOut->image8[y];
  43. for (x = 0; x < imIn->xsize; x++) {
  44. /* compare in/out pixels, apply sharpening */
  45. diff = lineIn8[x] - lineOut8[x];
  46. if (abs(diff) > threshold) {
  47. /* add the diff*percent to the original pixel */
  48. lineOut8[x] = clip8(lineIn8[x] + diff * percent / 100);
  49. } else {
  50. /* new pixel is the same as imIn */
  51. lineOut8[x] = lineIn8[x];
  52. }
  53. }
  54. } else {
  55. lineIn = (pixel *)imIn->image32[y];
  56. lineOut = (pixel *)imOut->image32[y];
  57. for (x = 0; x < imIn->xsize; x++) {
  58. /* compare in/out pixels, apply sharpening */
  59. diff = lineIn[x][0] - lineOut[x][0];
  60. lineOut[x][0] = abs(diff) > threshold ?
  61. clip8(lineIn[x][0] + diff * percent / 100) : lineIn[x][0];
  62. diff = lineIn[x][1] - lineOut[x][1];
  63. lineOut[x][1] = abs(diff) > threshold ?
  64. clip8(lineIn[x][1] + diff * percent / 100) : lineIn[x][1];
  65. diff = lineIn[x][2] - lineOut[x][2];
  66. lineOut[x][2] = abs(diff) > threshold ?
  67. clip8(lineIn[x][2] + diff * percent / 100) : lineIn[x][2];
  68. diff = lineIn[x][3] - lineOut[x][3];
  69. lineOut[x][3] = abs(diff) > threshold ?
  70. clip8(lineIn[x][3] + diff * percent / 100) : lineIn[x][3];
  71. }
  72. }
  73. }
  74. ImagingSectionLeave(&cookie);
  75. return imOut;
  76. }