ilu_noise.c
Upload User: wmy0603
Upload Date: 2022-05-02
Package Size: 1808k
Code Size: 5k
Development Platform:

Visual C++

  1. //-----------------------------------------------------------------------------
  2. //
  3. // ImageLib Utility Sources
  4. // Copyright (C) 2000-2002 by Denton Woods
  5. // Last modified: 05/25/2001 <--Y2K Compliant! =]
  6. //
  7. // Filename: src-ILU/src/ilu_noise.c
  8. //
  9. // Description: Noise generation functions
  10. //
  11. //-----------------------------------------------------------------------------
  12. #include "ilu_internal.h"
  13. #include <math.h>
  14. //#include <time.h>
  15. #include <limits.h>
  16. // Very simple right now.
  17. // This will probably use Perlin noise and parameters in the future.
  18. ILboolean ILAPIENTRY iluNoisify(ILclampf Tolerance)
  19. {
  20. ILuint i, j, c, Factor, Factor2, NumPix;
  21. ILint Val;
  22. ILushort *ShortPtr;
  23. ILuint *IntPtr;
  24. ILubyte *RegionMask;
  25. iluCurImage = ilGetCurImage();
  26. if (iluCurImage == NULL) {
  27. ilSetError(ILU_ILLEGAL_OPERATION);
  28. return IL_FALSE;
  29. }
  30. RegionMask = iScanFill();
  31. // @TODO:  Change this to work correctly without time()!
  32. //srand(time(NULL));
  33. NumPix = iluCurImage->SizeOfData / iluCurImage->Bpc;
  34. switch (iluCurImage->Bpc)
  35. {
  36. case 1:
  37. Factor = (ILubyte)(Tolerance * (UCHAR_MAX / 2));
  38. if (Factor == 0)
  39. return IL_TRUE;
  40. Factor2 = Factor + Factor;
  41. for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
  42. if (RegionMask) {
  43. if (!RegionMask[j])
  44. continue;
  45. }
  46. Val = (ILint)((ILint)(rand() % Factor2) - Factor);
  47. for (c = 0; c < iluCurImage->Bpp; c++) {
  48. if ((ILint)iluCurImage->Data[i + c] + Val > UCHAR_MAX)
  49. iluCurImage->Data[i + c] = UCHAR_MAX;
  50. else if ((ILint)iluCurImage->Data[i + c] + Val < 0)
  51. iluCurImage->Data[i + c] = 0;
  52. else
  53. iluCurImage->Data[i + c] += Val;
  54. }
  55. }
  56. break;
  57. case 2:
  58. Factor = (ILushort)(Tolerance * (USHRT_MAX / 2));
  59. if (Factor == 0)
  60. return IL_TRUE;
  61. Factor2 = Factor + Factor;
  62. ShortPtr = (ILushort*)iluCurImage->Data;
  63. for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
  64. if (RegionMask) {
  65. if (!RegionMask[j])
  66. continue;
  67. }
  68. Val = (ILint)((ILint)(rand() % Factor2) - Factor);
  69. for (c = 0; c < iluCurImage->Bpp; c++) {
  70. if ((ILint)ShortPtr[i + c] + Val > USHRT_MAX)
  71. ShortPtr[i + c] = USHRT_MAX;
  72. else if ((ILint)ShortPtr[i + c] + Val < 0)
  73. ShortPtr[i + c] = 0;
  74. else
  75. ShortPtr[i + c] += Val;
  76. }
  77. }
  78. break;
  79. case 4:
  80. Factor = (ILuint)(Tolerance * (UINT_MAX / 2));
  81. if (Factor == 0)
  82. return IL_TRUE;
  83. Factor2 = Factor + Factor;
  84. IntPtr = (ILuint*)iluCurImage->Data;
  85. for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
  86. if (RegionMask) {
  87. if (!RegionMask[j])
  88. continue;
  89. }
  90. Val = (ILint)((ILint)(rand() % Factor2) - Factor);
  91. for (c = 0; c < iluCurImage->Bpp; c++) {
  92. if (IntPtr[i + c] + Val > UINT_MAX)
  93. IntPtr[i + c] = UINT_MAX;
  94. else if ((ILint)IntPtr[i + c] + Val < 0)
  95. IntPtr[i + c] = 0;
  96. else
  97. IntPtr[i + c] += Val;
  98. }
  99. }
  100. break;
  101. }
  102. ifree(RegionMask);
  103. return IL_TRUE;
  104. }
  105. // Information on Perlin Noise taken from
  106. // http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
  107. /*ILdouble Noise(ILint x, ILint y)
  108. {
  109.     ILint n;
  110. n = x + y * 57;
  111.     n = (n<<13) ^ n;
  112.     return (1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
  113. }
  114. ILdouble SmoothNoise(ILint x, ILint y)
  115. {
  116. ILdouble corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
  117. ILdouble sides   = ( Noise(x-1, y)  +Noise(x+1, y)  +Noise(x, y-1)  +Noise(x, y+1) ) /  8;
  118. ILdouble center  =  Noise(x, y) / 4;
  119.     return corners + sides + center;
  120. }
  121. ILdouble Interpolate(ILdouble a, ILdouble b, ILdouble x)
  122. {
  123. ILdouble ft = x * 3.1415927;
  124. ILdouble f = (1 - cos(ft)) * .5;
  125. return  a*(1-f) + b*f;
  126. }
  127. ILdouble InterpolatedNoise(ILdouble x, ILdouble y)
  128. {
  129. ILint integer_X, integer_Y;
  130. ILdouble fractional_X, fractional_Y, v1, v2, v3, v4, i1, i2;
  131. integer_X    = (ILint)x;
  132. fractional_X = x - integer_X;
  133. integer_Y    = (ILint)y;
  134. fractional_Y = y - integer_Y;
  135. v1 = SmoothNoise(integer_X,     integer_Y);
  136. v2 = SmoothNoise(integer_X + 1, integer_Y);
  137. v3 = SmoothNoise(integer_X,     integer_Y + 1);
  138. v4 = SmoothNoise(integer_X + 1, integer_Y + 1);
  139. i1 = Interpolate(v1, v2, fractional_X);
  140. i2 = Interpolate(v3, v4, fractional_X);
  141. return Interpolate(i1, i2, fractional_Y);
  142. }
  143. ILdouble PerlinNoise(ILdouble x, ILdouble y)
  144. {
  145. ILuint i, n;
  146. ILdouble total = 0, p, frequency, amplitude;
  147. //p = persistence;
  148. //n = Number_Of_Octaves - 1;
  149. n = 2;
  150. //p = .5;
  151. p = (ILdouble)(rand() % 1000) / 1000.0;
  152. for (i = 0; i < n; i++) {
  153. frequency = pow(2, i);
  154. amplitude = pow(p, i);
  155. total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
  156. }
  157. return total;
  158. }
  159. ILboolean ILAPIENTRY iluNoisify()
  160. {
  161. ILuint x, y, c;
  162. ILint Val;
  163. iluCurImage = ilGetCurImage();
  164. if (iluCurImage == NULL) {
  165. ilSetError(ILU_ILLEGAL_OPERATION);
  166. return IL_FALSE;
  167. }
  168. for (y = 0; y < iluCurImage->Height; y++) {
  169. for (x = 0; x < iluCurImage->Width; x++) {
  170. Val = (ILint)(PerlinNoise(x, y) * 50.0);
  171. for (c = 0; c < iluCurImage->Bpp; c++) {
  172. if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val > 255)
  173. iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 255;
  174. else if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val < 0)
  175. iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 0;
  176. else
  177. iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] += Val;
  178. }
  179. }
  180. }
  181. return IL_TRUE;
  182. }*/