- Main Page
- Data Structures
- Files

- File List

# E:/DevIL/src-ILU/src/ilu_noise.c

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Utility Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 05/25/2001 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-ILU/src/ilu_noise.c
    00008 //
    00009 // Description: Noise generation functions
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "ilu_internal.h"
    00015 #include <math.h>
    00016 //#include <time.h>
    00017 #include <limits.h>
    00018
    00019
    00020 // Very simple right now.
    00021 //      This will probably use Perlin noise and parameters in the future.
    00022 ILboolean ILAPIENTRY iluNoisify(ILclampf Tolerance)
    00023 {
    00024         ILuint          i, j, c, Factor, Factor2, NumPix;
    00025         ILint           Val;
    00026         ILushort        *ShortPtr;
    00027         ILuint          *IntPtr;
    00028         ILubyte         *RegionMask;
    00029
    00030         iluCurImage = ilGetCurImage();
    00031         if (iluCurImage == NULL) {
    00032                 ilSetError(ILU_ILLEGAL_OPERATION);
    00033                 return IL_FALSE;
    00034         }
    00035
    00036         RegionMask = iScanFill();
    00037
    00038         // @TODO:  Change this to work correctly without time()!
    00039         //srand(time(NULL));
    00040         NumPix = iluCurImage->SizeOfData / iluCurImage->Bpc;
    00041
    00042         switch (iluCurImage->Bpc)
    00043         {
    00044                 case 1:
    00045                         Factor = (ILubyte)(Tolerance * (UCHAR_MAX / 2));
    00046                         if (Factor == 0)
    00047                                 return IL_TRUE;
    00048                         Factor2 = Factor + Factor;
    00049                         for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
    00050                                 if (RegionMask) {
    00051                                         if (!RegionMask[j])
    00052                                                 continue;
    00053                                 }
    00054                                 Val = (ILint)((ILint)(rand() % Factor2) - Factor);
    00055                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00056                                         if ((ILint)iluCurImage->Data[i + c] + Val > UCHAR_MAX)
    00057                                                 iluCurImage->Data[i + c] = UCHAR_MAX;
    00058                                         else if ((ILint)iluCurImage->Data[i + c] + Val < 0)
    00059                                                 iluCurImage->Data[i + c] = 0;
    00060                                         else
    00061                                                 iluCurImage->Data[i + c] += Val;
    00062                                 }
    00063                         }
    00064                         break;
    00065                 case 2:
    00066                         Factor = (ILushort)(Tolerance * (USHRT_MAX / 2));
    00067                         if (Factor == 0)
    00068                                 return IL_TRUE;
    00069                         Factor2 = Factor + Factor;
    00070                         ShortPtr = (ILushort*)iluCurImage->Data;
    00071                         for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
    00072                                 if (RegionMask) {
    00073                                         if (!RegionMask[j])
    00074                                                 continue;
    00075                                 }
    00076                                 Val = (ILint)((ILint)(rand() % Factor2) - Factor);
    00077                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00078                                         if ((ILint)ShortPtr[i + c] + Val > USHRT_MAX)
    00079                                                 ShortPtr[i + c] = USHRT_MAX;
    00080                                         else if ((ILint)ShortPtr[i + c] + Val < 0)
    00081                                                 ShortPtr[i + c] = 0;
    00082                                         else
    00083                                                 ShortPtr[i + c] += Val;
    00084                                 }
    00085                         }
    00086                         break;
    00087                 case 4:
    00088                         Factor = (ILuint)(Tolerance * (UINT_MAX / 2));
    00089                         if (Factor == 0)
    00090                                 return IL_TRUE;
    00091                         Factor2 = Factor + Factor;
    00092                         IntPtr = (ILuint*)iluCurImage->Data;
    00093                         for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
    00094                                 if (RegionMask) {
    00095                                         if (!RegionMask[j])
    00096                                                 continue;
    00097                                 }
    00098                                 Val = (ILint)((ILint)(rand() % Factor2) - Factor);
    00099                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00100                                         if (IntPtr[i + c] + Val > UINT_MAX)
    00101                                                 IntPtr[i + c] = UINT_MAX;
    00102                                         else if ((ILint)IntPtr[i + c] + Val < 0)
    00103                                                 IntPtr[i + c] = 0;
    00104                                         else
    00105                                                 IntPtr[i + c] += Val;
    00106                                 }
    00107                         }
    00108                         break;
    00109         }
    00110
    00111         ifree(RegionMask);
    00112
    00113         return IL_TRUE;
    00114 }
    00115
    00116
    00117
    00118
    00119 // Information on Perlin Noise taken from
    00120 //      http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
    00121
    00122
    00123 /*ILdouble Noise(ILint x, ILint y)
    00124 {
    00125     ILint n;
    00126         n = x + y * 57;
    00127     n = (n<<13) ^ n;
    00128     return (1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
    00129 }
    00130
    00131
    00132 ILdouble SmoothNoise(ILint x, ILint y)
    00133 {
    00134         ILdouble corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
    00135         ILdouble sides   = ( Noise(x-1, y)  +Noise(x+1, y)  +Noise(x, y-1)  +Noise(x, y+1) ) /  8;
    00136         ILdouble center  =  Noise(x, y) / 4;
    00137     return corners + sides + center;
    00138 }
    00139
    00140
    00141 ILdouble Interpolate(ILdouble a, ILdouble b, ILdouble x)
    00142 {
    00143         ILdouble ft = x * 3.1415927;
    00144         ILdouble f = (1 - cos(ft)) * .5;
    00145
    00146         return  a*(1-f) + b*f;
    00147 }
    00148
    00149
    00150 ILdouble InterpolatedNoise(ILdouble x, ILdouble y)
    00151 {
    00152         ILint           integer_X, integer_Y;
    00153         ILdouble        fractional_X, fractional_Y, v1, v2, v3, v4, i1, i2;
    00154
    00155         integer_X    = (ILint)x;
    00156         fractional_X = x - integer_X;
    00157
    00158         integer_Y    = (ILint)y;
    00159         fractional_Y = y - integer_Y;
    00160
    00161         v1 = SmoothNoise(integer_X,     integer_Y);
    00162         v2 = SmoothNoise(integer_X + 1, integer_Y);
    00163         v3 = SmoothNoise(integer_X,     integer_Y + 1);
    00164         v4 = SmoothNoise(integer_X + 1, integer_Y + 1);
    00165
    00166         i1 = Interpolate(v1, v2, fractional_X);
    00167         i2 = Interpolate(v3, v4, fractional_X);
    00168
    00169         return Interpolate(i1, i2, fractional_Y);
    00170 }
    00171
    00172
    00173
    00174 ILdouble PerlinNoise(ILdouble x, ILdouble y)
    00175 {
    00176         ILuint i, n;
    00177         ILdouble total = 0, p, frequency, amplitude;
    00178         //p = persistence;
    00179         //n = Number_Of_Octaves - 1;
    00180         n = 2;
    00181         //p = .5;
    00182
    00183         p = (ILdouble)(rand() % 1000) / 1000.0;
    00184
    00185
    00186         for (i = 0; i < n; i++) {
    00187                 frequency = pow(2, i);
    00188                 amplitude = pow(p, i);
    00189
    00190                 total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
    00191         }
    00192
    00193         return total;
    00194 }
    00195
    00196
    00197
    00198 ILboolean ILAPIENTRY iluNoisify()
    00199 {
    00200         ILuint x, y, c;
    00201         ILint Val;
    00202
    00203         iluCurImage = ilGetCurImage();
    00204         if (iluCurImage == NULL) {
    00205                 ilSetError(ILU_ILLEGAL_OPERATION);
    00206                 return IL_FALSE;
    00207         }
    00208
    00209         for (y = 0; y < iluCurImage->Height; y++) {
    00210                 for (x = 0; x < iluCurImage->Width; x++) {
    00211                         Val = (ILint)(PerlinNoise(x, y) * 50.0);
    00212
    00213                         for (c = 0; c < iluCurImage->Bpp; c++) {
    00214                                 if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val > 255)
    00215                                         iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 255;
    00216                                 else if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val < 0)
    00217                                         iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 0;
    00218                                 else
    00219                                         iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] += Val;
    00220                         }
    00221                 }
    00222         }
    00223
    00224         return IL_TRUE;
    00225 }*/