Files
love-android/jni/devil-1.7.8/src-ILU/src/ilu_noise.c
T

226 lines
5.4 KiB
C

//-----------------------------------------------------------------------------
//
// ImageLib Utility Sources
// Copyright (C) 2000-2002 by Denton Woods
// Last modified: 05/25/2001 <--Y2K Compliant! =]
//
// Filename: src-ILU/src/ilu_noise.c
//
// Description: Noise generation functions
//
//-----------------------------------------------------------------------------
#include "ilu_internal.h"
#include <math.h>
//#include <time.h>
#include <limits.h>
// Very simple right now.
// This will probably use Perlin noise and parameters in the future.
ILboolean ILAPIENTRY iluNoisify(ILclampf Tolerance)
{
ILuint i, j, c, Factor, Factor2, NumPix;
ILint Val;
ILushort *ShortPtr;
ILuint *IntPtr;
ILubyte *RegionMask;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
RegionMask = iScanFill();
// @TODO: Change this to work correctly without time()!
//srand(time(NULL));
NumPix = iluCurImage->SizeOfData / iluCurImage->Bpc;
switch (iluCurImage->Bpc)
{
case 1:
Factor = (ILubyte)(Tolerance * (UCHAR_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)iluCurImage->Data[i + c] + Val > UCHAR_MAX)
iluCurImage->Data[i + c] = UCHAR_MAX;
else if ((ILint)iluCurImage->Data[i + c] + Val < 0)
iluCurImage->Data[i + c] = 0;
else
iluCurImage->Data[i + c] += Val;
}
}
break;
case 2:
Factor = (ILushort)(Tolerance * (USHRT_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
ShortPtr = (ILushort*)iluCurImage->Data;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)ShortPtr[i + c] + Val > USHRT_MAX)
ShortPtr[i + c] = USHRT_MAX;
else if ((ILint)ShortPtr[i + c] + Val < 0)
ShortPtr[i + c] = 0;
else
ShortPtr[i + c] += Val;
}
}
break;
case 4:
Factor = (ILuint)(Tolerance * (UINT_MAX / 2));
if (Factor == 0)
return IL_TRUE;
Factor2 = Factor + Factor;
IntPtr = (ILuint*)iluCurImage->Data;
for (i = 0, j = 0; i < NumPix; i += iluCurImage->Bpp, j++) {
if (RegionMask) {
if (!RegionMask[j])
continue;
}
Val = (ILint)((ILint)(rand() % Factor2) - Factor);
for (c = 0; c < iluCurImage->Bpp; c++) {
if (IntPtr[i + c] + Val > UINT_MAX)
IntPtr[i + c] = UINT_MAX;
else if ((ILint)IntPtr[i + c] + Val < 0)
IntPtr[i + c] = 0;
else
IntPtr[i + c] += Val;
}
}
break;
}
ifree(RegionMask);
return IL_TRUE;
}
// Information on Perlin Noise taken from
// http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
/*ILdouble Noise(ILint x, ILint y)
{
ILint n;
n = x + y * 57;
n = (n<<13) ^ n;
return (1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
ILdouble SmoothNoise(ILint x, ILint y)
{
ILdouble corners = ( Noise(x-1, y-1)+Noise(x+1, y-1)+Noise(x-1, y+1)+Noise(x+1, y+1) ) / 16;
ILdouble sides = ( Noise(x-1, y) +Noise(x+1, y) +Noise(x, y-1) +Noise(x, y+1) ) / 8;
ILdouble center = Noise(x, y) / 4;
return corners + sides + center;
}
ILdouble Interpolate(ILdouble a, ILdouble b, ILdouble x)
{
ILdouble ft = x * 3.1415927;
ILdouble f = (1 - cos(ft)) * .5;
return a*(1-f) + b*f;
}
ILdouble InterpolatedNoise(ILdouble x, ILdouble y)
{
ILint integer_X, integer_Y;
ILdouble fractional_X, fractional_Y, v1, v2, v3, v4, i1, i2;
integer_X = (ILint)x;
fractional_X = x - integer_X;
integer_Y = (ILint)y;
fractional_Y = y - integer_Y;
v1 = SmoothNoise(integer_X, integer_Y);
v2 = SmoothNoise(integer_X + 1, integer_Y);
v3 = SmoothNoise(integer_X, integer_Y + 1);
v4 = SmoothNoise(integer_X + 1, integer_Y + 1);
i1 = Interpolate(v1, v2, fractional_X);
i2 = Interpolate(v3, v4, fractional_X);
return Interpolate(i1, i2, fractional_Y);
}
ILdouble PerlinNoise(ILdouble x, ILdouble y)
{
ILuint i, n;
ILdouble total = 0, p, frequency, amplitude;
//p = persistence;
//n = Number_Of_Octaves - 1;
n = 2;
//p = .5;
p = (ILdouble)(rand() % 1000) / 1000.0;
for (i = 0; i < n; i++) {
frequency = pow(2, i);
amplitude = pow(p, i);
total = total + InterpolatedNoise(x * frequency, y * frequency) * amplitude;
}
return total;
}
ILboolean ILAPIENTRY iluNoisify()
{
ILuint x, y, c;
ILint Val;
iluCurImage = ilGetCurImage();
if (iluCurImage == NULL) {
ilSetError(ILU_ILLEGAL_OPERATION);
return IL_FALSE;
}
for (y = 0; y < iluCurImage->Height; y++) {
for (x = 0; x < iluCurImage->Width; x++) {
Val = (ILint)(PerlinNoise(x, y) * 50.0);
for (c = 0; c < iluCurImage->Bpp; c++) {
if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val > 255)
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 255;
else if ((ILint)iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] + Val < 0)
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] = 0;
else
iluCurImage->Data[y * iluCurImage->Bps + x * iluCurImage->Bpp + c] += Val;
}
}
}
return IL_TRUE;
}*/