/* * 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 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 = ImagingNewDirty("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 = ImagingNewDirty("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] = CLIP8(128 + sigma * this); } } return imOut; } Imaging ImagingEffectSpread(Imaging imIn, int distance) { /* Randomly spread pixels in an image */ Imaging imOut; int x, y; imOut = ImagingNewDirty(imIn->mode, imIn->xsize, imIn->ysize); if (!imOut) return NULL; #define SPREAD(type, image)\ for (y = 0; y < imOut->ysize; y++)\ for (x = 0; x < imOut->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); } ImagingCopyPalette(imOut, imIn); return imOut; }