Effects.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * The Python Imaging Library
  3. * $Id$
  4. *
  5. * various special effects and image generators
  6. *
  7. * history:
  8. * 1997-05-21 fl Just for fun
  9. * 1997-06-05 fl Added mandelbrot generator
  10. * 2003-05-24 fl Added perlin_turbulence generator (in progress)
  11. *
  12. * Copyright (c) 1997-2003 by Fredrik Lundh.
  13. * Copyright (c) 1997 by Secret Labs AB.
  14. *
  15. * See the README file for information on usage and redistribution.
  16. */
  17. #include "Imaging.h"
  18. #include <math.h>
  19. Imaging
  20. ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality)
  21. {
  22. /* Generate a Mandelbrot set covering the given extent */
  23. Imaging im;
  24. int x, y, k;
  25. double width, height;
  26. double x1, y1, xi2, yi2, cr, ci, radius;
  27. double dr, di;
  28. /* Check arguments */
  29. width = extent[2] - extent[0];
  30. height = extent[3] - extent[1];
  31. if (width < 0.0 || height < 0.0 || quality < 2)
  32. return (Imaging) ImagingError_ValueError(NULL);
  33. im = ImagingNewDirty("L", xsize, ysize);
  34. if (!im)
  35. return NULL;
  36. dr = width/(xsize-1);
  37. di = height/(ysize-1);
  38. radius = 100.0;
  39. for (y = 0; y < ysize; y++) {
  40. UINT8* buf = im->image8[y];
  41. for (x = 0; x < xsize; x++) {
  42. x1 = y1 = xi2 = yi2 = 0.0;
  43. cr = x*dr + extent[0];
  44. ci = y*di + extent[1];
  45. for (k = 1;; k++) {
  46. y1 = 2*x1*y1 + ci;
  47. x1 = xi2 - yi2 + cr;
  48. xi2 = x1*x1;
  49. yi2 = y1*y1;
  50. if ((xi2 + yi2) > radius) {
  51. buf[x] = k*255/quality;
  52. break;
  53. }
  54. if (k > quality) {
  55. buf[x] = 0;
  56. break;
  57. }
  58. }
  59. }
  60. }
  61. return im;
  62. }
  63. Imaging
  64. ImagingEffectNoise(int xsize, int ysize, float sigma)
  65. {
  66. /* Generate Gaussian noise centered around 128 */
  67. Imaging imOut;
  68. int x, y;
  69. int nextok;
  70. double this, next;
  71. imOut = ImagingNewDirty("L", xsize, ysize);
  72. if (!imOut)
  73. return NULL;
  74. next = 0.0;
  75. nextok = 0;
  76. for (y = 0; y < imOut->ysize; y++) {
  77. UINT8* out = imOut->image8[y];
  78. for (x = 0; x < imOut->xsize; x++) {
  79. if (nextok) {
  80. this = next;
  81. nextok = 0;
  82. } else {
  83. /* after numerical recipes */
  84. double v1, v2, radius, factor;
  85. do {
  86. v1 = rand()*(2.0/RAND_MAX) - 1.0;
  87. v2 = rand()*(2.0/RAND_MAX) - 1.0;
  88. radius= v1*v1 + v2*v2;
  89. } while (radius >= 1.0);
  90. factor = sqrt(-2.0*log(radius)/radius);
  91. this = factor * v1;
  92. next = factor * v2;
  93. }
  94. out[x] = CLIP8(128 + sigma * this);
  95. }
  96. }
  97. return imOut;
  98. }
  99. Imaging
  100. ImagingEffectSpread(Imaging imIn, int distance)
  101. {
  102. /* Randomly spread pixels in an image */
  103. Imaging imOut;
  104. int x, y;
  105. imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize);
  106. if (!imOut)
  107. return NULL;
  108. #define SPREAD(type, image)\
  109. for (y = 0; y < imOut->ysize; y++)\
  110. for (x = 0; x < imOut->xsize; x++) {\
  111. int xx = x + (rand() % distance) - distance/2;\
  112. int yy = y + (rand() % distance) - distance/2;\
  113. if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\
  114. imOut->image[yy][xx] = imIn->image[y][x];\
  115. imOut->image[y][x] = imIn->image[yy][xx];\
  116. } else\
  117. imOut->image[y][x] = imIn->image[y][x];\
  118. }
  119. if (imIn->image8) {
  120. SPREAD(UINT8, image8);
  121. } else {
  122. SPREAD(INT32, image32);
  123. }
  124. ImagingCopyPalette(imOut, imIn);
  125. return imOut;
  126. }