mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-10-31 07:57:27 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * The Python Imaging Library
 | |
|  * $Id$
 | |
|  *
 | |
|  * various special effects and image generators
 | |
|  *
 | |
|  * history:
 | |
|  * 1997-05-21 fl   Just for fun
 | |
|  * 1997-06-05 fl   Added mandelbrot generator
 | |
|  * 2003-05-24 fl   Added perlin_turbulence generator (in progress)
 | |
|  *
 | |
|  * Copyright (c) 1997-2003 by Fredrik Lundh.
 | |
|  * Copyright (c) 1997 by Secret Labs AB.
 | |
|  *
 | |
|  * See the README file for information on usage and redistribution.
 | |
|  */
 | |
| 
 | |
| 
 | |
| #include "Imaging.h"
 | |
| 
 | |
| #include <math.h>
 | |
| 
 | |
| Imaging
 | |
| ImagingEffectMandelbrot(int xsize, int ysize, double extent[4], int quality)
 | |
| {
 | |
|     /* Generate a Mandelbrot set covering the given extent */
 | |
| 
 | |
|     Imaging im;
 | |
|     int x, y, k;
 | |
|     double width, height;
 | |
|     double x1, y1, xi2, yi2, cr, ci, radius;
 | |
|     double dr, di;
 | |
| 
 | |
|     /* Check arguments */
 | |
|     width  = extent[2] - extent[0];
 | |
|     height = extent[3] - extent[1];
 | |
|     if (width < 0.0 || height < 0.0 || quality < 2)
 | |
|         return (Imaging) ImagingError_ValueError(NULL);
 | |
| 
 | |
|     im = ImagingNew("L", xsize, ysize);
 | |
|     if (!im)
 | |
|         return NULL;
 | |
| 
 | |
|     dr = width/(xsize-1);
 | |
|     di = height/(ysize-1);
 | |
| 
 | |
|     radius = 100.0;
 | |
| 
 | |
|     for (y = 0; y < ysize; y++) {
 | |
|         UINT8* buf = im->image8[y];
 | |
|         for (x = 0; x < xsize; x++) {
 | |
|             x1 = y1 = xi2 = yi2 = 0.0;
 | |
|             cr = x*dr + extent[0];
 | |
|             ci = y*di + extent[1];
 | |
|             for (k = 1;; k++) {
 | |
|                 y1 = 2*x1*y1 + ci;
 | |
|                 x1 = xi2 - yi2 + cr;
 | |
|                 xi2 = x1*x1;
 | |
|                 yi2 = y1*y1;
 | |
|                 if ((xi2 + yi2) > radius) {
 | |
|                     buf[x] = k*255/quality;
 | |
|                     break;
 | |
|                 }
 | |
|                 if (k > quality) {
 | |
|                     buf[x] = 0;
 | |
|                     break;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     return im;
 | |
| }
 | |
| 
 | |
| Imaging
 | |
| ImagingEffectNoise(int xsize, int ysize, float sigma)
 | |
| {
 | |
|     /* Generate Gaussian noise centered around 128 */
 | |
| 
 | |
|     Imaging imOut;
 | |
|     int x, y;
 | |
|     int nextok;
 | |
|     double this, next;
 | |
| 
 | |
|     imOut = ImagingNew("L", xsize, ysize);
 | |
|     if (!imOut)
 | |
|         return NULL;
 | |
| 
 | |
|     next = 0.0;
 | |
|     nextok = 0;
 | |
| 
 | |
|     for (y = 0; y < imOut->ysize; y++) {
 | |
|         UINT8* out = imOut->image8[y];
 | |
|     for (x = 0; x < imOut->xsize; x++) {
 | |
|             if (nextok) {
 | |
|                 this = next;
 | |
|                 nextok = 0;
 | |
|             } else {
 | |
|                 /* after numerical recipes */
 | |
|                 double v1, v2, radius, factor;
 | |
|                 do {
 | |
|                     v1 = rand()*(2.0/RAND_MAX) - 1.0;
 | |
|                     v2 = rand()*(2.0/RAND_MAX) - 1.0;
 | |
|                     radius= v1*v1 + v2*v2;
 | |
|                 } while (radius >= 1.0);
 | |
|                 factor = sqrt(-2.0*log(radius)/radius);
 | |
|                 this = factor * v1;
 | |
|                 next = factor * v2;
 | |
|             }
 | |
|             out[x] = (unsigned char) (128 + sigma * this);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return imOut;
 | |
| }
 | |
| 
 | |
| Imaging
 | |
| ImagingEffectSpread(Imaging imIn, int distance)
 | |
| {
 | |
|     /* Randomly spread pixels in an image */
 | |
| 
 | |
|     Imaging imOut;
 | |
|     int x, y;
 | |
| 
 | |
|     imOut = ImagingNew(imIn->mode, imIn->xsize, imIn->ysize);
 | |
| 
 | |
|     if (!imOut)
 | |
|     return NULL;
 | |
| 
 | |
| #define SPREAD(type, image)\
 | |
|     for (y = 0; y < imIn->ysize; y++)\
 | |
|     for (x = 0; x < imIn->xsize; x++) {\
 | |
|             int xx = x + (rand() % distance) - distance/2;\
 | |
|             int yy = y + (rand() % distance) - distance/2;\
 | |
|             if (xx >= 0 && xx < imIn->xsize && yy >= 0 && yy < imIn->ysize) {\
 | |
|                 imOut->image[yy][xx] = imIn->image[y][x];\
 | |
|                 imOut->image[y][x]   = imIn->image[yy][xx];\
 | |
|             } else\
 | |
|                 imOut->image[y][x]   = imIn->image[y][x];\
 | |
|         }
 | |
| 
 | |
|     if (imIn->image8) {
 | |
|         SPREAD(UINT8, image8);
 | |
|     } else {
 | |
|         SPREAD(INT32, image32);
 | |
|     }
 | |
| 
 | |
|     ImagingCopyInfo(imOut, imIn);
 | |
| 
 | |
|     return imOut;
 | |
| }
 |