Example #1
0
// 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;
}
Example #2
0
// Could probably be optimized a bit...too many nested for loops.
//! Pixelizes an image
ILboolean ILAPIENTRY iluPixelize(ILuint PixSize)
{
	ILuint		x, y, z, i, j, k, c, r, Total, Tested;
	ILushort	*ShortPtr;
	ILuint		*IntPtr;
	ILdouble	*DblPtr, DblTotal, DblTested;
	ILubyte		*RegionMask;

	iluCurImage = ilGetCurImage();
	if (iluCurImage == NULL) {
		ilSetError(ILU_ILLEGAL_OPERATION);
		return IL_FALSE;
	}

	if (PixSize == 0)
		PixSize = 1;
	r = 0;

	if (iluCurImage->Format == IL_COLOUR_INDEX)
		ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);

	RegionMask = iScanFill();

	switch (iluCurImage->Bpc)
	{
		case 1:
			for (z = 0; z < iluCurImage->Depth; z += PixSize) {
				for (y = 0; y < iluCurImage->Height; y += PixSize) {
					for (x = 0; x < iluCurImage->Width; x += PixSize) {
						for (c = 0; c < iluCurImage->Bpp; c++) {
							Total = 0;  Tested = 0;
							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										Total += iluCurImage->Data[(z+k) * iluCurImage->SizeOfPlane + 
											(y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
									}
								}
							}
							Total /= Tested;

							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										if (RegionMask) {
											if (!RegionMask[(y+j) * iluCurImage->Width + (x+i)])
												continue;
										}
										iluCurImage->Data[(z+k) * iluCurImage->SizeOfPlane + (y+j)
											* iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
											Total;
									}
								}
							}
						}
					}
				}
			}
			break;
		case 2:
			ShortPtr = (ILushort*)iluCurImage->Data;
			iluCurImage->Bps /= 2;
			for (z = 0; z < iluCurImage->Depth; z += PixSize) {
				for (y = 0; y < iluCurImage->Height; y += PixSize) {
					for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
						for (c = 0; c < iluCurImage->Bpp; c++) {
							Total = 0;  Tested = 0;
							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										Total += ShortPtr[(z+k) * iluCurImage->SizeOfPlane + 
											(y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
									}
								}
							}
							Total /= Tested;

							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										if (RegionMask[r+i]) {
											ShortPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
												* iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
												Total;
										}
									}
								}
							}
						}
					}
				}
			}
			iluCurImage->Bps *= 2;
			break;
		case 4:
			IntPtr = (ILuint*)iluCurImage->Data;
			iluCurImage->Bps /= 4;
			for (z = 0; z < iluCurImage->Depth; z += PixSize) {
				for (y = 0; y < iluCurImage->Height; y += PixSize) {
					for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
						for (c = 0; c < iluCurImage->Bpp; c++) {
							Total = 0;  Tested = 0;
							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										Total += IntPtr[(z+k) * iluCurImage->SizeOfPlane + 
											(y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
									}
								}
							}
							Total /= Tested;

							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
										if (RegionMask[r+i]) {
											IntPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
												* iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
												Total;
										}
									}
								}
							}
						}
					}
				}
			}
			iluCurImage->Bps *= 4;
			break;
		case 8:
			DblPtr = (ILdouble*)iluCurImage->Data;
			iluCurImage->Bps /= 8;
			for (z = 0; z < iluCurImage->Depth; z += PixSize) {
				for (y = 0; y < iluCurImage->Height; y += PixSize) {
					for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
						for (c = 0; c < iluCurImage->Bpp; c++) {
							DblTotal = 0.0;  DblTested = 0.0;
							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, DblTested++) {
										DblTotal += DblPtr[(z+k) * iluCurImage->SizeOfPlane + 
											(y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
									}
								}
							}
							DblTotal /= DblTested;

							for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
								for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
									for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, DblTested++) {
										if (RegionMask[r+i]) {
											DblPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
												* iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
												DblTotal;
										}
									}
								}
							}
						}
					}
				}
			}
			iluCurImage->Bps *= 8;
			break;
	}

	ifree(RegionMask);

	return IL_TRUE;
}
Example #3
0
ILboolean iNoisify(ILimage *Image, ILclampf Tolerance) {
  ILuint    i, j, c, Factor1, Factor2, NumPix;
  ILint   Val;
  ILubyte   *RegionMask;

  if (Image == NULL) {
    iSetError(ILU_ILLEGAL_OPERATION);
    return IL_FALSE;
  }

  RegionMask = iScanFill(Image);

  // @TODO:  Change this to work correctly without time()!
  //srand(time(NULL));
  NumPix = Image->SizeOfData / Image->Bpc;

  switch (Image->Bpc)
  {
    case 1:
      Factor1 = (ILubyte)(Tolerance * IL_MAX_UNSIGNED_BYTE * 0.5f);
      Factor2 = Factor1 + Factor1;
      if (Factor1 == 0) return IL_TRUE;

      for (i = 0, j = 0; i < NumPix; i += Image->Bpp, j++) {
        if (RegionMask) {
          if (!RegionMask[j])
            continue;
        }
        Val = iGetNoiseValue(Factor1, Factor2);
        for (c = 0; c < Image->Bpp; c++) {
          ILint NewVal = (ILint)iGetImageDataUByte(Image)[i + c] + Val;
          if (NewVal > IL_MAX_UNSIGNED_BYTE)
            iGetImageDataUByte(Image)[i + c] = IL_MAX_UNSIGNED_BYTE;
          else if (NewVal < 0)
            iGetImageDataUByte(Image)[i + c] = 0;
          else
            iGetImageDataUByte(Image)[i + c] += Val;
        }
      }
      break;
    case 2:
      Factor1 = (ILushort)(Tolerance * IL_MAX_UNSIGNED_SHORT * 0.5f);
      Factor2 = Factor1 + Factor1;
      if (Factor1 == 0) return IL_TRUE;

      for (i = 0, j = 0; i < NumPix; i += Image->Bpp, j++) {
        if (RegionMask) {
          if (!RegionMask[j])
            continue;
        }
        Val = iGetNoiseValue(Factor1, Factor2);
        for (c = 0; c < Image->Bpp; c++) {
          ILint NewVal = (ILint)iGetImageDataUShort(Image)[i + c] + Val;
          if (NewVal > IL_MAX_UNSIGNED_SHORT)
            iGetImageDataUShort(Image)[i + c] = IL_MAX_UNSIGNED_SHORT;
          else if (NewVal < 0)
            iGetImageDataUShort(Image)[i + c] = 0;
          else
            iGetImageDataUShort(Image)[i + c] = (ILushort)NewVal;
        }
      }
      break;
      // FIXME: ILfloat, ILdouble
    case 4:
      Factor1 = (ILuint)(Tolerance * IL_MAX_UNSIGNED_INT * 0.5f);
      Factor2 = Factor1 + Factor1;
      if (Factor1 == 0) return IL_TRUE;

      for (i = 0, j = 0; i < NumPix; i += Image->Bpp, j++) {
        if (RegionMask) {
          if (!RegionMask[j])
            continue;
        }
        Val = iGetNoiseValue(Factor1, Factor2);
        for (c = 0; c < Image->Bpp; c++) {
          ILint64 NewVal = (ILint64)iGetImageDataUInt(Image)[i + c] + Val;
          if (NewVal > IL_MAX_UNSIGNED_INT)
            iGetImageDataUInt(Image)[i + c] = IL_MAX_UNSIGNED_INT;
          else if (NewVal < 0)
            iGetImageDataUInt(Image)[i + c] = 0;
          else
            iGetImageDataUInt(Image)[i + c] = (ILuint)NewVal;
        }
      }
      break;
  }

  ifree(RegionMask);

  return IL_TRUE;
}
Example #4
0
// Needs some SERIOUS optimization.
ILubyte *Filter(ILimage *Image, const ILint *matrix, ILint scale, ILint bias)
{
    ILint		x, y, c, LastX, LastY, Offsets[9];
	ILuint		i, Temp, z;
	ILubyte		*Data, *ImgData, *NewData, *RegionMask;
	ILdouble	Num;
	
	if (Image == NULL) {
		ilSetError(ILU_ILLEGAL_OPERATION);
		return NULL;
	}

	Data = (ILubyte*)ialloc(Image->SizeOfData);
	if (Data == NULL) {
		return NULL;
	}

	RegionMask = iScanFill();

	// Preserve original data.
	ImgData = Image->Data;
	NewData = Data;

	for (z = 0; z < Image->Depth; z++) {
		LastX = Image->Width  - 1;
		LastY = Image->Height - 1;
		for (y = 1; y < LastY; y++) {
			for (x = 1; x < LastX; x++) {
				Offsets[4] = ((y  ) * Image->Width + (x  )) * Image->Bpp;
				if (RegionMask) {
					if (!RegionMask[y * Image->Width + x]) {
						for (c = 0; c < Image->Bpp; c++) {
							Data[Offsets[4]+c] = Image->Data[Offsets[4]+c];
						}
						continue;
					}
				}

				Offsets[0] = ((y-1) * Image->Width + (x-1)) * Image->Bpp;
				Offsets[1] = ((y-1) * Image->Width + (x  )) * Image->Bpp;
				Offsets[2] = ((y-1) * Image->Width + (x+1)) * Image->Bpp;
				Offsets[3] = ((y  ) * Image->Width + (x-1)) * Image->Bpp;
				Offsets[5] = ((y  ) * Image->Width + (x+1)) * Image->Bpp;
				Offsets[6] = ((y+1) * Image->Width + (x-1)) * Image->Bpp;
				Offsets[7] = ((y+1) * Image->Width + (x  )) * Image->Bpp;
				Offsets[8] = ((y+1) * Image->Width + (x-1)) * Image->Bpp;

				// Always has at least one, so get rid of all those +c's
				Num =   Image->Data[Offsets[0]] * matrix[0] +
						Image->Data[Offsets[1]] * matrix[1]+
						Image->Data[Offsets[2]] * matrix[2]+
						Image->Data[Offsets[3]] * matrix[3]+
						Image->Data[Offsets[4]] * matrix[4]+
						Image->Data[Offsets[5]] * matrix[5]+
						Image->Data[Offsets[6]] * matrix[6]+
						Image->Data[Offsets[7]] * matrix[7]+
						Image->Data[Offsets[8]] * matrix[8];

				Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
				if (Temp > 255)
					Data[Offsets[4]] = 255;
				else
					Data[Offsets[4]] = Temp;

				for (c = 1; c < Image->Bpp; c++) {
					Num =   Image->Data[Offsets[0]+c] * matrix[0]+
							Image->Data[Offsets[1]+c] * matrix[1]+
							Image->Data[Offsets[2]+c] * matrix[2]+
							Image->Data[Offsets[3]+c] * matrix[3]+
							Image->Data[Offsets[4]+c] * matrix[4]+
							Image->Data[Offsets[5]+c] * matrix[5]+
							Image->Data[Offsets[6]+c] * matrix[6]+
							Image->Data[Offsets[7]+c] * matrix[7]+
							Image->Data[Offsets[8]+c] * matrix[8];

					Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
					if (Temp > 255)
						Data[Offsets[4]+c] = 255;
					else
						Data[Offsets[4]+c] = Temp;
				}
			}
		}


		// Copy 4 corners
		for (c = 0; c < Image->Bpp; c++) {
			Data[c] = Image->Data[c];
			Data[Image->Bps - Image->Bpp + c] = Image->Data[Image->Bps - Image->Bpp + c];
			Data[(Image->Height - 1) * Image->Bps + c] = Image->Data[(Image->Height - 1) * Image->Bps + c];
			Data[Image->Height * Image->Bps - Image->Bpp + c] = 
				Image->Data[Image->Height * Image->Bps - Image->Bpp + c];
		}


		// If we only copy the edge pixels, then they receive no filtering, making them
		//	look out of place after several passes of an image.  So we filter the edge
		//	rows/columns, duplicating the edge pixels for one side of the "matrix".

		// First row
		for (x = 1; x < (ILint)Image->Width-1; x++) {
			if (RegionMask) {
				if (!RegionMask[x]) {
					Data[y + x * Image->Bpp + c] = Image->Data[y + x * Image->Bpp + c];
					continue;
				}
			}
			for (c = 0; c < Image->Bpp; c++) {
				Num =   Image->Data[(x-1) * Image->Bpp + c] * matrix[0] +
						Image->Data[x * Image->Bpp + c] * matrix[1]+
						Image->Data[(x+1) * Image->Bpp + c] * matrix[2]+
						Image->Data[(x-1) * Image->Bpp + c] * matrix[3]+
						Image->Data[x * Image->Bpp + c] * matrix[4]+
						Image->Data[(x+1) * Image->Bpp + c] * matrix[5]+
						Image->Data[(Image->Width + (x-1)) * Image->Bpp + c] * matrix[6]+
						Image->Data[(Image->Width + (x  )) * Image->Bpp + c] * matrix[7]+
						Image->Data[(Image->Width + (x-1)) * Image->Bpp + c] * matrix[8];

					Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
					if (Temp > 255)
						Data[x * Image->Bpp + c] = 255;
					else
						Data[x * Image->Bpp + c] = Temp;
			}
		}

		// Last row
		y = (Image->Height - 1) * Image->Bps;
		for (x = 1; x < (ILint)Image->Width-1; x++) {
			if (RegionMask) {
				if (!RegionMask[(Image->Height - 1) * Image->Width + x]) {
					Data[y + x * Image->Bpp + c] = Image->Data[y + x * Image->Bpp + c];
					continue;
				}
			}
			for (c = 0; c < Image->Bpp; c++) {
				Num =   Image->Data[y - Image->Bps + (x-1) * Image->Bpp + c] * matrix[0] +
						Image->Data[y - Image->Bps + x * Image->Bpp + c] * matrix[1]+
						Image->Data[y - Image->Bps + (x+1) * Image->Bpp + c] * matrix[2]+
						Image->Data[y + (x-1) * Image->Bpp + c] * matrix[3]+
						Image->Data[y + x * Image->Bpp + c] * matrix[4]+
						Image->Data[y + (x+1) * Image->Bpp + c] * matrix[5]+
						Image->Data[y + (x-1) * Image->Bpp + c] * matrix[6]+
						Image->Data[y + x * Image->Bpp + c] * matrix[7]+
						Image->Data[y + (x-1) * Image->Bpp + c] * matrix[8];

					Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
					if (Temp > 255)
						Data[y + x * Image->Bpp + c] = 255;
					else
						Data[y + x * Image->Bpp + c] = Temp;
			}
		}

		// Left side
		for (i = 1, y = Image->Bps; i < Image->Height-1; i++, y += Image->Bps) {
			if (RegionMask) {
				if (!RegionMask[y / Image->Bpp]) {
					Data[y + c] = Image->Data[y + c];
					continue;
				}
			}
			for (c = 0; c < Image->Bpp; c++) {
				Num =   Image->Data[y - Image->Bps + c] * matrix[0] +
						Image->Data[y - Image->Bps + Image->Bpp + c] * matrix[1]+
						Image->Data[y - Image->Bps + 2 * Image->Bpp + c] * matrix[2]+
						Image->Data[y + c] * matrix[3]+
						Image->Data[y + Image->Bpp + c] * matrix[4]+
						Image->Data[y + 2 * Image->Bpp + c] * matrix[5]+
						Image->Data[y + Image->Bps + c] * matrix[6]+
						Image->Data[y + Image->Bps + Image->Bpp + c] * matrix[7]+
						Image->Data[y + Image->Bps + 2 * Image->Bpp + c] * matrix[8];

					Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
					if (Temp > 255)
						Data[y + c] = 255;
					else
						Data[y + c] = Temp;
			}
		}

		// Right side
		for (i = 1, y = Image->Bps * 2 - Image->Bpp; i < Image->Height-1; i++, y += Image->Bps) {
			if (RegionMask) {
				if (!RegionMask[y / Image->Bpp + (Image->Width - 1)]) {
					for (c = 0; c < Image->Bpp; c++) {
						Data[y + c] = Image->Data[y + c];
					}
					continue;
				}
			}
			for (c = 0; c < Image->Bpp; c++) {
				Num =   Image->Data[y - Image->Bps + c] * matrix[0] +
						Image->Data[y - Image->Bps + Image->Bpp + c] * matrix[1]+
						Image->Data[y - Image->Bps + 2 * Image->Bpp + c] * matrix[2]+
						Image->Data[y + c] * matrix[3]+
						Image->Data[y + Image->Bpp + c] * matrix[4]+
						Image->Data[y + 2 * Image->Bpp + c] * matrix[5]+
						Image->Data[y + Image->Bps + c] * matrix[6]+
						Image->Data[y + Image->Bps + Image->Bpp + c] * matrix[7]+
						Image->Data[y + Image->Bps + 2 * Image->Bpp + c] * matrix[8];

					Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
					if (Temp > 255)
						Data[y + c] = 255;
					else
						Data[y + c] = Temp;
			}
		}

		// Go to next "plane".
		Image->Data += Image->SizeOfPlane;
		Data += Image->SizeOfPlane;
	}

	ifree(RegionMask);

	// Restore original data.
	Image->Data = ImgData;
	Data = NewData;

	return Data;
}