Effects.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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. /* Generate a Mandelbrot set covering the given extent */
  22. Imaging im;
  23. int x, y, k;
  24. double width, height;
  25. double x1, y1, xi2, yi2, cr, ci, radius;
  26. double dr, di;
  27. /* Check arguments */
  28. width = extent[2] - extent[0];
  29. height = extent[3] - extent[1];
  30. if (width < 0.0 || height < 0.0 || quality < 2) {
  31. return (Imaging)ImagingError_ValueError(NULL);
  32. }
  33. im = ImagingNewDirty("L", xsize, ysize);
  34. if (!im) {
  35. return NULL;
  36. }
  37. dr = width / (xsize - 1);
  38. di = height / (ysize - 1);
  39. radius = 100.0;
  40. for (y = 0; y < ysize; y++) {
  41. UINT8 *buf = im->image8[y];
  42. for (x = 0; x < xsize; x++) {
  43. x1 = y1 = xi2 = yi2 = 0.0;
  44. cr = x * dr + extent[0];
  45. ci = y * di + extent[1];
  46. for (k = 1;; k++) {
  47. y1 = 2 * x1 * y1 + ci;
  48. x1 = xi2 - yi2 + cr;
  49. xi2 = x1 * x1;
  50. yi2 = y1 * y1;
  51. if ((xi2 + yi2) > radius) {
  52. buf[x] = k * 255 / quality;
  53. break;
  54. }
  55. if (k > quality) {
  56. buf[x] = 0;
  57. break;
  58. }
  59. }
  60. }
  61. }
  62. return im;
  63. }
  64. Imaging
  65. ImagingEffectNoise(int xsize, int ysize, float sigma) {
  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. }
  75. next = 0.0;
  76. nextok = 0;
  77. for (y = 0; y < imOut->ysize; y++) {
  78. UINT8 *out = imOut->image8[y];
  79. for (x = 0; x < imOut->xsize; x++) {
  80. if (nextok) {
  81. this = next;
  82. nextok = 0;
  83. } else {
  84. /* after numerical recipes */
  85. double v1, v2, radius, factor;
  86. do {
  87. v1 = rand() * (2.0 / RAND_MAX) - 1.0;
  88. v2 = rand() * (2.0 / RAND_MAX) - 1.0;
  89. radius = v1 * v1 + v2 * v2;
  90. } while (radius >= 1.0);
  91. factor = sqrt(-2.0 * log(radius) / radius);
  92. this = factor * v1;
  93. next = factor * v2;
  94. }
  95. out[x] = CLIP8(128 + sigma * this);
  96. }
  97. }
  98. return imOut;
  99. }
  100. Imaging
  101. ImagingEffectSpread(Imaging imIn, int distance) {
  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. }
  109. #define SPREAD(type, image) \
  110. if (distance == 0) { \
  111. for (y = 0; y < imOut->ysize; y++) { \
  112. for (x = 0; x < imOut->xsize; x++) { \
  113. imOut->image[y][x] = imIn->image[y][x]; \
  114. } \
  115. } \
  116. } else { \
  117. for (y = 0; y < imOut->ysize; y++) { \
  118. for (x = 0; x < imOut->xsize; x++) { \
  119. int xx = x + (rand() % distance) - distance / 2; \
  120. int yy = y + (rand() % distance) - distance / 2; \
  121. if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) { \
  122. imOut->image[yy][xx] = imIn->image[y][x]; \
  123. imOut->image[y][x] = imIn->image[yy][xx]; \
  124. } else { \
  125. imOut->image[y][x] = imIn->image[y][x]; \
  126. } \
  127. } \
  128. } \
  129. }
  130. if (imIn->image8) {
  131. SPREAD(UINT8, image8);
  132. } else {
  133. SPREAD(INT32, image32);
  134. }
  135. ImagingCopyPalette(imOut, imIn);
  136. return imOut;
  137. }