UnsharpMask.c 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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
  10. clip8(int in) {
  11. if (in >= 255) {
  12. return 255;
  13. }
  14. if (in <= 0) {
  15. return 0;
  16. }
  17. return (UINT8)in;
  18. }
  19. Imaging
  20. ImagingUnsharpMask(
  21. Imaging imOut, Imaging imIn, float radius, int percent, int threshold) {
  22. ImagingSectionCookie cookie;
  23. Imaging result;
  24. int x, y, diff;
  25. pixel *lineIn = NULL;
  26. pixel *lineOut = NULL;
  27. UINT8 *lineIn8 = NULL;
  28. UINT8 *lineOut8 = NULL;
  29. /* First, do a gaussian blur on the image, putting results in imOut
  30. temporarily. All format checks are in gaussian blur. */
  31. result = ImagingGaussianBlur(imOut, imIn, radius, radius, 3);
  32. if (!result) {
  33. return NULL;
  34. }
  35. /* Now, go through each pixel, compare "normal" pixel to blurred
  36. pixel. If the difference is more than threshold values, apply
  37. the OPPOSITE correction to the amount of blur, multiplied by
  38. percent. */
  39. ImagingSectionEnter(&cookie);
  40. for (y = 0; y < imIn->ysize; y++) {
  41. if (imIn->image8) {
  42. lineIn8 = imIn->image8[y];
  43. lineOut8 = imOut->image8[y];
  44. for (x = 0; x < imIn->xsize; x++) {
  45. /* compare in/out pixels, apply sharpening */
  46. diff = lineIn8[x] - lineOut8[x];
  47. if (abs(diff) > threshold) {
  48. /* add the diff*percent to the original pixel */
  49. lineOut8[x] = clip8(lineIn8[x] + diff * percent / 100);
  50. } else {
  51. /* new pixel is the same as imIn */
  52. lineOut8[x] = lineIn8[x];
  53. }
  54. }
  55. } else {
  56. lineIn = (pixel *)imIn->image32[y];
  57. lineOut = (pixel *)imOut->image32[y];
  58. for (x = 0; x < imIn->xsize; x++) {
  59. /* compare in/out pixels, apply sharpening */
  60. diff = lineIn[x][0] - lineOut[x][0];
  61. lineOut[x][0] = abs(diff) > threshold
  62. ? clip8(lineIn[x][0] + diff * percent / 100)
  63. : lineIn[x][0];
  64. diff = lineIn[x][1] - lineOut[x][1];
  65. lineOut[x][1] = abs(diff) > threshold
  66. ? clip8(lineIn[x][1] + diff * percent / 100)
  67. : lineIn[x][1];
  68. diff = lineIn[x][2] - lineOut[x][2];
  69. lineOut[x][2] = abs(diff) > threshold
  70. ? clip8(lineIn[x][2] + diff * percent / 100)
  71. : lineIn[x][2];
  72. diff = lineIn[x][3] - lineOut[x][3];
  73. lineOut[x][3] = abs(diff) > threshold
  74. ? clip8(lineIn[x][3] + diff * percent / 100)
  75. : lineIn[x][3];
  76. }
  77. }
  78. }
  79. ImagingSectionLeave(&cookie);
  80. return imOut;
  81. }