- Main Page
- Data Structures
- Files

- File List

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

    00001
    00002 // Description: Applies filters to an image.
    00003
    00004 #include "ilu_internal.h"
    00005 #include "ilu_filter.h"
    00006 #include <math.h>
    00007 #include <limits.h>
    00008
    00009
    00010 // Could probably be optimized a bit...too many nested for loops.
    00012 ILboolean ILAPIENTRY iluPixelize(ILuint PixSize)
    00013 {
    00014         ILuint          x, y, z, i, j, k, c, r, Total, Tested;
    00015         ILushort        *ShortPtr;
    00016         ILuint          *IntPtr;
    00017         ILdouble        *DblPtr, DblTotal, DblTested;
    00018         ILubyte         *RegionMask;
    00019
    00020         iluCurImage = ilGetCurImage();
    00021         if (iluCurImage == NULL) {
    00022                 ilSetError(ILU_ILLEGAL_OPERATION);
    00023                 return IL_FALSE;
    00024         }
    00025
    00026         if (PixSize == 0)
    00027                 PixSize = 1;
    00028         r = 0;
    00029
    00030         if (iluCurImage->Format == IL_COLOUR_INDEX)
    00031                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00032
    00033         RegionMask = iScanFill();
    00034
    00035         switch (iluCurImage->Bpc)
    00036         {
    00037                 case 1:
    00038                         for (z = 0; z < iluCurImage->Depth; z += PixSize) {
    00039                                 for (y = 0; y < iluCurImage->Height; y += PixSize) {
    00040                                         for (x = 0; x < iluCurImage->Width; x += PixSize) {
    00041                                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00042                                                         Total = 0;  Tested = 0;
    00043                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00044                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00045                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00046                                                                                 Total += iluCurImage->Data[(z+k) * iluCurImage->SizeOfPlane +
    00047                                                                                         (y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
    00048                                                                         }
    00049                                                                 }
    00050                                                         }
    00051                                                         Total /= Tested;
    00052
    00053                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00054                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00055                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00056                                                                                 if (RegionMask) {
    00057                                                                                         if (!RegionMask[(y+j) * iluCurImage->Width + (x+i)])
    00058                                                                                                 continue;
    00059                                                                                 }
    00060                                                                                 iluCurImage->Data[(z+k) * iluCurImage->SizeOfPlane + (y+j)
    00061                                                                                         * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
    00062                                                                                         Total;
    00063                                                                         }
    00064                                                                 }
    00065                                                         }
    00066                                                 }
    00067                                         }
    00068                                 }
    00069                         }
    00070                         break;
    00071                 case 2:
    00072                         ShortPtr = (ILushort*)iluCurImage->Data;
    00073                         iluCurImage->Bps /= 2;
    00074                         for (z = 0; z < iluCurImage->Depth; z += PixSize) {
    00075                                 for (y = 0; y < iluCurImage->Height; y += PixSize) {
    00076                                         for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
    00077                                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00078                                                         Total = 0;  Tested = 0;
    00079                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00080                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00081                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00082                                                                                 Total += ShortPtr[(z+k) * iluCurImage->SizeOfPlane +
    00083                                                                                         (y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
    00084                                                                         }
    00085                                                                 }
    00086                                                         }
    00087                                                         Total /= Tested;
    00088
    00089                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00090                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00091                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00092                                                                                 if (RegionMask[r+i]) {
    00093                                                                                         ShortPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
    00094                                                                                                 * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
    00095                                                                                                 Total;
    00096                                                                                 }
    00097                                                                         }
    00098                                                                 }
    00099                                                         }
    00100                                                 }
    00101                                         }
    00102                                 }
    00103                         }
    00104                         iluCurImage->Bps *= 2;
    00105                         break;
    00106                 case 4:
    00107                         IntPtr = (ILuint*)iluCurImage->Data;
    00108                         iluCurImage->Bps /= 4;
    00109                         for (z = 0; z < iluCurImage->Depth; z += PixSize) {
    00110                                 for (y = 0; y < iluCurImage->Height; y += PixSize) {
    00111                                         for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
    00112                                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00113                                                         Total = 0;  Tested = 0;
    00114                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00115                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00116                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00117                                                                                 Total += IntPtr[(z+k) * iluCurImage->SizeOfPlane +
    00118                                                                                         (y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
    00119                                                                         }
    00120                                                                 }
    00121                                                         }
    00122                                                         Total /= Tested;
    00123
    00124                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00125                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00126                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, Tested++) {
    00127                                                                                 if (RegionMask[r+i]) {
    00128                                                                                         IntPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
    00129                                                                                                 * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
    00130                                                                                                 Total;
    00131                                                                                 }
    00132                                                                         }
    00133                                                                 }
    00134                                                         }
    00135                                                 }
    00136                                         }
    00137                                 }
    00138                         }
    00139                         iluCurImage->Bps *= 4;
    00140                         break;
    00141                 case 8:
    00142                         DblPtr = (ILdouble*)iluCurImage->Data;
    00143                         iluCurImage->Bps /= 8;
    00144                         for (z = 0; z < iluCurImage->Depth; z += PixSize) {
    00145                                 for (y = 0; y < iluCurImage->Height; y += PixSize) {
    00146                                         for (x = 0; x < iluCurImage->Width; x += PixSize, r += PixSize) {
    00147                                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00148                                                         DblTotal = 0.0;  DblTested = 0.0;
    00149                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00150                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00151                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, DblTested++) {
    00152                                                                                 DblTotal += DblPtr[(z+k) * iluCurImage->SizeOfPlane +
    00153                                                                                         (y+j) * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c];
    00154                                                                         }
    00155                                                                 }
    00156                                                         }
    00157                                                         DblTotal /= DblTested;
    00158
    00159                                                         for (k = 0; k < PixSize && z+k < iluCurImage->Depth; k++) {
    00160                                                                 for (j = 0; j < PixSize && y+j < iluCurImage->Height; j++) {
    00161                                                                         for (i = 0; i < PixSize && x+i < iluCurImage->Width; i++, DblTested++) {
    00162                                                                                 if (RegionMask[r+i]) {
    00163                                                                                         DblPtr[(z+k) * iluCurImage->SizeOfPlane + (y+j)
    00164                                                                                                 * iluCurImage->Bps + (x+i) * iluCurImage->Bpp + c] =
    00165                                                                                                 DblTotal;
    00166                                                                                 }
    00167                                                                         }
    00168                                                                 }
    00169                                                         }
    00170                                                 }
    00171                                         }
    00172                                 }
    00173                         }
    00174                         iluCurImage->Bps *= 8;
    00175                         break;
    00176         }
    00177
    00178         ifree(RegionMask);
    00179
    00180         return IL_TRUE;
    00181 }
    00182
    00183
    00184 // Everything here was taken from a tutorial on "Elementary Digital Filtering"
    00185 //      by Ender Wiggen, found at http://www.gamedev.net/reference/programming/features/edf/
    00186
    00187 // Needs some SERIOUS optimization.
    00188 ILubyte *Filter(ILimage *Image, const ILint *matrix, ILint scale, ILint bias)
    00189 {
    00190     ILint               x, y, c, LastX, LastY, Offsets[9];
    00191         ILuint          i, Temp, z;
    00192         ILubyte         *Data, *ImgData, *NewData, *RegionMask;
    00193         ILdouble        Num;
    00194
    00195         if (Image == NULL) {
    00196                 ilSetError(ILU_ILLEGAL_OPERATION);
    00197                 return NULL;
    00198         }
    00199
    00200         Data = (ILubyte*)ialloc(Image->SizeOfData);
    00201         if (Data == NULL) {
    00202                 return NULL;
    00203         }
    00204
    00205         RegionMask = iScanFill();
    00206
    00207         // Preserve original data.
    00208         ImgData = Image->Data;
    00209         NewData = Data;
    00210
    00211         for (z = 0; z < Image->Depth; z++) {
    00212                 LastX = Image->Width  - 1;
    00213                 LastY = Image->Height - 1;
    00214                 for (y = 1; y < LastY; y++) {
    00215                         for (x = 1; x < LastX; x++) {
    00216                                 Offsets[4] = ((y  ) * Image->Width + (x  )) * Image->Bpp;
    00217                                 if (RegionMask) {
    00218                                         if (!RegionMask[y * Image->Width + x]) {
    00219                                                 for (c = 0; c < Image->Bpp; c++) {
    00220                                                         Data[Offsets[4]+c] = Image->Data[Offsets[4]+c];
    00221                                                 }
    00222                                                 continue;
    00223                                         }
    00224                                 }
    00225
    00226                                 Offsets[0] = ((y-1) * Image->Width + (x-1)) * Image->Bpp;
    00227                                 Offsets[1] = ((y-1) * Image->Width + (x  )) * Image->Bpp;
    00228                                 Offsets[2] = ((y-1) * Image->Width + (x+1)) * Image->Bpp;
    00229                                 Offsets[3] = ((y  ) * Image->Width + (x-1)) * Image->Bpp;
    00230                                 Offsets[5] = ((y  ) * Image->Width + (x+1)) * Image->Bpp;
    00231                                 Offsets[6] = ((y+1) * Image->Width + (x-1)) * Image->Bpp;
    00232                                 Offsets[7] = ((y+1) * Image->Width + (x  )) * Image->Bpp;
    00233                                 Offsets[8] = ((y+1) * Image->Width + (x-1)) * Image->Bpp;
    00234
    00235                                 // Always has at least one, so get rid of all those +c's
    00236                                 Num =   Image->Data[Offsets[0]] * matrix[0] +
    00237                                                 Image->Data[Offsets[1]] * matrix[1]+
    00238                                                 Image->Data[Offsets[2]] * matrix[2]+
    00239                                                 Image->Data[Offsets[3]] * matrix[3]+
    00240                                                 Image->Data[Offsets[4]] * matrix[4]+
    00241                                                 Image->Data[Offsets[5]] * matrix[5]+
    00242                                                 Image->Data[Offsets[6]] * matrix[6]+
    00243                                                 Image->Data[Offsets[7]] * matrix[7]+
    00244                                                 Image->Data[Offsets[8]] * matrix[8];
    00245
    00246                                 Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00247                                 if (Temp > 255)
    00248                                         Data[Offsets[4]] = 255;
    00249                                 else
    00250                                         Data[Offsets[4]] = Temp;
    00251
    00252                                 for (c = 1; c < Image->Bpp; c++) {
    00253                                         Num =   Image->Data[Offsets[0]+c] * matrix[0]+
    00254                                                         Image->Data[Offsets[1]+c] * matrix[1]+
    00255                                                         Image->Data[Offsets[2]+c] * matrix[2]+
    00256                                                         Image->Data[Offsets[3]+c] * matrix[3]+
    00257                                                         Image->Data[Offsets[4]+c] * matrix[4]+
    00258                                                         Image->Data[Offsets[5]+c] * matrix[5]+
    00259                                                         Image->Data[Offsets[6]+c] * matrix[6]+
    00260                                                         Image->Data[Offsets[7]+c] * matrix[7]+
    00261                                                         Image->Data[Offsets[8]+c] * matrix[8];
    00262
    00263                                         Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00264                                         if (Temp > 255)
    00265                                                 Data[Offsets[4]+c] = 255;
    00266                                         else
    00267                                                 Data[Offsets[4]+c] = Temp;
    00268                                 }
    00269                         }
    00270                 }
    00271
    00272
    00273                 // Copy 4 corners
    00274                 for (c = 0; c < Image->Bpp; c++) {
    00275                         Data[c] = Image->Data[c];
    00276                         Data[Image->Bps - Image->Bpp + c] = Image->Data[Image->Bps - Image->Bpp + c];
    00277                         Data[(Image->Height - 1) * Image->Bps + c] = Image->Data[(Image->Height - 1) * Image->Bps + c];
    00278                         Data[Image->Height * Image->Bps - Image->Bpp + c] =
    00279                                 Image->Data[Image->Height * Image->Bps - Image->Bpp + c];
    00280                 }
    00281
    00282
    00283                 // If we only copy the edge pixels, then they receive no filtering, making them
    00284                 //      look out of place after several passes of an image.  So we filter the edge
    00285                 //      rows/columns, duplicating the edge pixels for one side of the "matrix".
    00286
    00287                 // First row
    00288                 for (x = 1; x < (ILint)Image->Width-1; x++) {
    00289                         if (RegionMask) {
    00290                                 if (!RegionMask[x]) {
    00291                                         Data[y + x * Image->Bpp + c] = Image->Data[y + x * Image->Bpp + c];
    00292                                         continue;
    00293                                 }
    00294                         }
    00295                         for (c = 0; c < Image->Bpp; c++) {
    00296                                 Num =   Image->Data[(x-1) * Image->Bpp + c] * matrix[0] +
    00297                                                 Image->Data[x * Image->Bpp + c] * matrix[1]+
    00298                                                 Image->Data[(x+1) * Image->Bpp + c] * matrix[2]+
    00299                                                 Image->Data[(x-1) * Image->Bpp + c] * matrix[3]+
    00300                                                 Image->Data[x * Image->Bpp + c] * matrix[4]+
    00301                                                 Image->Data[(x+1) * Image->Bpp + c] * matrix[5]+
    00302                                                 Image->Data[(Image->Width + (x-1)) * Image->Bpp + c] * matrix[6]+
    00303                                                 Image->Data[(Image->Width + (x  )) * Image->Bpp + c] * matrix[7]+
    00304                                                 Image->Data[(Image->Width + (x-1)) * Image->Bpp + c] * matrix[8];
    00305
    00306                                         Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00307                                         if (Temp > 255)
    00308                                                 Data[x * Image->Bpp + c] = 255;
    00309                                         else
    00310                                                 Data[x * Image->Bpp + c] = Temp;
    00311                         }
    00312                 }
    00313
    00314                 // Last row
    00315                 y = (Image->Height - 1) * Image->Bps;
    00316                 for (x = 1; x < (ILint)Image->Width-1; x++) {
    00317                         if (RegionMask) {
    00318                                 if (!RegionMask[(Image->Height - 1) * Image->Width + x]) {
    00319                                         Data[y + x * Image->Bpp + c] = Image->Data[y + x * Image->Bpp + c];
    00320                                         continue;
    00321                                 }
    00322                         }
    00323                         for (c = 0; c < Image->Bpp; c++) {
    00324                                 Num =   Image->Data[y - Image->Bps + (x-1) * Image->Bpp + c] * matrix[0] +
    00325                                                 Image->Data[y - Image->Bps + x * Image->Bpp + c] * matrix[1]+
    00326                                                 Image->Data[y - Image->Bps + (x+1) * Image->Bpp + c] * matrix[2]+
    00327                                                 Image->Data[y + (x-1) * Image->Bpp + c] * matrix[3]+
    00328                                                 Image->Data[y + x * Image->Bpp + c] * matrix[4]+
    00329                                                 Image->Data[y + (x+1) * Image->Bpp + c] * matrix[5]+
    00330                                                 Image->Data[y + (x-1) * Image->Bpp + c] * matrix[6]+
    00331                                                 Image->Data[y + x * Image->Bpp + c] * matrix[7]+
    00332                                                 Image->Data[y + (x-1) * Image->Bpp + c] * matrix[8];
    00333
    00334                                         Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00335                                         if (Temp > 255)
    00336                                                 Data[y + x * Image->Bpp + c] = 255;
    00337                                         else
    00338                                                 Data[y + x * Image->Bpp + c] = Temp;
    00339                         }
    00340                 }
    00341
    00342                 // Left side
    00343                 for (i = 1, y = Image->Bps; i < Image->Height-1; i++, y += Image->Bps) {
    00344                         if (RegionMask) {
    00345                                 if (!RegionMask[y / Image->Bpp]) {
    00346                                         Data[y + c] = Image->Data[y + c];
    00347                                         continue;
    00348                                 }
    00349                         }
    00350                         for (c = 0; c < Image->Bpp; c++) {
    00351                                 Num =   Image->Data[y - Image->Bps + c] * matrix[0] +
    00352                                                 Image->Data[y - Image->Bps + Image->Bpp + c] * matrix[1]+
    00353                                                 Image->Data[y - Image->Bps + 2 * Image->Bpp + c] * matrix[2]+
    00354                                                 Image->Data[y + c] * matrix[3]+
    00355                                                 Image->Data[y + Image->Bpp + c] * matrix[4]+
    00356                                                 Image->Data[y + 2 * Image->Bpp + c] * matrix[5]+
    00357                                                 Image->Data[y + Image->Bps + c] * matrix[6]+
    00358                                                 Image->Data[y + Image->Bps + Image->Bpp + c] * matrix[7]+
    00359                                                 Image->Data[y + Image->Bps + 2 * Image->Bpp + c] * matrix[8];
    00360
    00361                                         Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00362                                         if (Temp > 255)
    00363                                                 Data[y + c] = 255;
    00364                                         else
    00365                                                 Data[y + c] = Temp;
    00366                         }
    00367                 }
    00368
    00369                 // Right side
    00370                 for (i = 1, y = Image->Bps * 2 - Image->Bpp; i < Image->Height-1; i++, y += Image->Bps) {
    00371                         if (RegionMask) {
    00372                                 if (!RegionMask[y / Image->Bpp + (Image->Width - 1)]) {
    00373                                         for (c = 0; c < Image->Bpp; c++) {
    00374                                                 Data[y + c] = Image->Data[y + c];
    00375                                         }
    00376                                         continue;
    00377                                 }
    00378                         }
    00379                         for (c = 0; c < Image->Bpp; c++) {
    00380                                 Num =   Image->Data[y - Image->Bps + c] * matrix[0] +
    00381                                                 Image->Data[y - Image->Bps + Image->Bpp + c] * matrix[1]+
    00382                                                 Image->Data[y - Image->Bps + 2 * Image->Bpp + c] * matrix[2]+
    00383                                                 Image->Data[y + c] * matrix[3]+
    00384                                                 Image->Data[y + Image->Bpp + c] * matrix[4]+
    00385                                                 Image->Data[y + 2 * Image->Bpp + c] * matrix[5]+
    00386                                                 Image->Data[y + Image->Bps + c] * matrix[6]+
    00387                                                 Image->Data[y + Image->Bps + Image->Bpp + c] * matrix[7]+
    00388                                                 Image->Data[y + Image->Bps + 2 * Image->Bpp + c] * matrix[8];
    00389
    00390                                         Temp = (ILuint)fabs((Num / (ILdouble)scale) + bias);
    00391                                         if (Temp > 255)
    00392                                                 Data[y + c] = 255;
    00393                                         else
    00394                                                 Data[y + c] = Temp;
    00395                         }
    00396                 }
    00397
    00398                 // Go to next "plane".
    00399                 Image->Data += Image->SizeOfPlane;
    00400                 Data += Image->SizeOfPlane;
    00401         }
    00402
    00403         ifree(RegionMask);
    00404
    00405         // Restore original data.
    00406         Image->Data = ImgData;
    00407         Data = NewData;
    00408
    00409         return Data;
    00410 }
    00411
    00412
    00413 ILboolean ILAPIENTRY iluEdgeDetectP()
    00414 {
    00415         ILubyte         *HPass, *VPass;
    00416         ILuint          i;
    00417         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00418         ILenum          Type = 0;
    00419
    00420         iluCurImage = ilGetCurImage();
    00421         if (iluCurImage == NULL) {
    00422                 ilSetError(ILU_ILLEGAL_OPERATION);
    00423                 return IL_FALSE;
    00424         }
    00425
    00426         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00427                 Palette = IL_TRUE;
    00428                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00429         }
    00430         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00431                 Converted = IL_TRUE;
    00432                 Type = iluCurImage->Type;
    00433                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00434         }
    00435
    00436
    00437         HPass = Filter(iluCurImage, filter_h_prewitt, filter_h_prewitt_scale, filter_h_prewitt_bias);
    00438         VPass = Filter(iluCurImage, filter_v_prewitt, filter_v_prewitt_scale, filter_v_prewitt_bias);
    00439         if (!HPass || !VPass) {
    00440                 ifree(HPass);
    00441                 ifree(VPass);
    00442                 return IL_FALSE;
    00443         }
    00444
    00445         // Combine the two passes
    00446         //      Optimization by Matt Denham
    00447         for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00448                 if (HPass[i] == 0)
    00449                         iluCurImage->Data[i] = VPass[i];
    00450                 else if (VPass[i] == 0)
    00451                         iluCurImage->Data[i] = HPass[i];
    00452                 else
    00453                         iluCurImage->Data[i] = (ILubyte)sqrt((float)(HPass[i]*HPass[i]+VPass[i]*VPass[i]));
    00454         }
    00455
    00456         /*for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00457                 iluCurImage->Data[i] = (ILubyte)sqrt(HPass[i]*HPass[i]+VPass[i]*VPass[i]);
    00458         }*/
    00459
    00460         ifree(HPass);
    00461         ifree(VPass);
    00462
    00463         if (Palette)
    00464                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00465         else if (Converted)
    00466                 ilConvertImage(iluCurImage->Format, Type);
    00467
    00468         return IL_TRUE;
    00469 }
    00470
    00471
    00472 ILboolean ILAPIENTRY iluEdgeDetectS()
    00473 {
    00474         ILubyte         *HPass, *VPass;
    00475         ILuint          i;
    00476         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00477         ILenum          Type = 0;
    00478
    00479         iluCurImage = ilGetCurImage();
    00480         if (iluCurImage == NULL) {
    00481                 ilSetError(ILU_ILLEGAL_OPERATION);
    00482                 return IL_FALSE;
    00483         }
    00484
    00485         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00486                 Palette = IL_TRUE;
    00487                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00488         }
    00489         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00490                 Converted = IL_TRUE;
    00491                 Type = iluCurImage->Type;
    00492                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00493         }
    00494
    00495         HPass = Filter(iluCurImage, filter_h_sobel, filter_h_sobel_scale, filter_h_sobel_bias);
    00496         VPass = Filter(iluCurImage, filter_v_sobel, filter_v_sobel_scale, filter_v_sobel_bias);
    00497         if (!HPass || !VPass) {
    00498                 ifree(HPass);
    00499                 ifree(VPass);
    00500                 return IL_FALSE;
    00501         }
    00502
    00503         // Combine the two passes
    00504         //      Optimization by Matt Denham
    00505         for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00506                 if (HPass[i] == 0)
    00507                         iluCurImage->Data[i] = VPass[i];
    00508                 else if (VPass[i] == 0)
    00509                         iluCurImage->Data[i] = HPass[i];
    00510                 else
    00511                         iluCurImage->Data[i] = (ILubyte)sqrt((float)(HPass[i]*HPass[i]+VPass[i]*VPass[i]));
    00512         }
    00513
    00514         /*for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00515                 iluCurImage->Data[i] = (ILubyte)sqrt(HPass[i]*HPass[i]+VPass[i]*VPass[i]);
    00516         }*/
    00517
    00518         ifree(HPass);
    00519         ifree(VPass);
    00520
    00521         if (Palette)
    00522                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00523         else if (Converted)
    00524                 ilConvertImage(iluCurImage->Format, Type);
    00525
    00526         return IL_TRUE;
    00527 }
    00528
    00529
    00530 ILboolean ILAPIENTRY iluBlurAvg(ILuint Iter)
    00531 {
    00532         ILubyte         *Data;
    00533         ILuint          i;
    00534         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00535         ILenum          Type = 0;
    00536
    00537         iluCurImage = ilGetCurImage();
    00538         if (iluCurImage == NULL) {
    00539                 ilSetError(ILU_ILLEGAL_OPERATION);
    00540                 return IL_FALSE;
    00541         }
    00542
    00543         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00544                 Palette = IL_TRUE;
    00545                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00546         }
    00547         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00548                 Converted = IL_TRUE;
    00549                 Type = iluCurImage->Type;
    00550                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00551         }
    00552
    00553         for (i = 0; i < Iter; i++) {
    00554                 Data = Filter(iluCurImage, filter_average, filter_average_scale, filter_average_bias);
    00555                 if (!Data)
    00556                         return IL_FALSE;
    00557                 ifree(iluCurImage->Data);
    00558                 iluCurImage->Data = Data;
    00559         }
    00560
    00561         if (Palette)
    00562                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00563         else if (Converted)
    00564                 ilConvertImage(iluCurImage->Format, Type);
    00565
    00566         return IL_TRUE;
    00567 }
    00568
    00569
    00570 ILboolean ILAPIENTRY iluBlurGaussian(ILuint Iter)
    00571 {
    00572         ILubyte         *Data;
    00573         ILuint          i;
    00574         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00575         ILenum          Type = 0;
    00576
    00577         iluCurImage = ilGetCurImage();
    00578         if (iluCurImage == NULL) {
    00579                 ilSetError(ILU_ILLEGAL_OPERATION);
    00580                 return IL_FALSE;
    00581         }
    00582
    00583         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00584                 Palette = IL_TRUE;
    00585                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00586         }
    00587         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00588                 Converted = IL_TRUE;
    00589                 Type = iluCurImage->Type;
    00590                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00591         }
    00592
    00593         for (i = 0; i < Iter; i++) {
    00594                 Data = Filter(iluCurImage, filter_gaussian, filter_gaussian_scale, filter_gaussian_bias );
    00595                 if (!Data)
    00596                         return IL_FALSE;
    00597                 ifree(iluCurImage->Data);
    00598                 iluCurImage->Data = Data;
    00599         }
    00600
    00601         if (Palette)
    00602                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00603         else if (Converted)
    00604                 ilConvertImage(iluCurImage->Format, Type);
    00605
    00606         return IL_TRUE;
    00607 }
    00608
    00609
    00610 ILboolean ILAPIENTRY iluEmboss()
    00611 {
    00612         ILubyte         *Data;
    00613         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00614         ILenum          Type = 0;
    00615
    00616         iluCurImage = ilGetCurImage();
    00617         if (iluCurImage == NULL) {
    00618                 ilSetError(ILU_ILLEGAL_OPERATION);
    00619                 return IL_FALSE;
    00620         }
    00621
    00622         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00623                 Palette = IL_TRUE;
    00624                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00625         }
    00626         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00627                 Converted = IL_TRUE;
    00628                 Type = iluCurImage->Type;
    00629                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00630         }
    00631
    00632         Data = Filter(iluCurImage, filter_emboss, filter_emboss_scale, filter_emboss_bias);
    00633         if (!Data)
    00634                 return IL_FALSE;
    00635         ifree(iluCurImage->Data);
    00636         iluCurImage->Data = Data;
    00637
    00638         if (Palette)
    00639                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00640         else if (Converted)
    00641                 ilConvertImage(iluCurImage->Format, Type);
    00642
    00643         return IL_TRUE;
    00644 }
    00645
    00646 /*ILboolean ILAPIENTRY iluEmboss()
    00647 {
    00648         ILuint  x, y, c, i = 0;
    00649         ILubyte *Data;
    00650
    00651         iluCurImage = ilGetCurImage();
    00652         if (iluCurImage == NULL) {
    00653                 ilSetError(ILU_ILLEGAL_OPERATION);
    00654                 return IL_FALSE;
    00655         }
    00656
    00657         Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
    00658         if (Data == NULL) {
    00659                 return IL_FALSE;
    00660         }
    00661
    00662         for (y = 0; y < iluCurImage->Height; y++, i += iluCurImage->Bps) {
    00663                 for (x = 0; x < (ILint)iluCurImage->Bps - iluCurImage->Bpp; x += iluCurImage->Bpp) {
    00664                         for (c = 0; c < iluCurImage->Bpp; c++) {
    00665                                 Data[i+x+c] = iluCurImage->Data[i+x+c] - iluCurImage->Data[i+iluCurImage->Bpp+c] + 128;
    00666                         }
    00667                 }
    00668                 Data[i+x] = 128;
    00669         }
    00670
    00671         ifree(iluCurImage->Data);
    00672         iluCurImage->Data = Data;
    00673
    00674         return IL_TRUE;
    00675 }*/
    00676
    00677
    00678 ILboolean ILAPIENTRY iluEdgeDetectE()
    00679 {
    00680         ILubyte         *Data;
    00681         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    00682         ILenum          Type = 0;
    00683
    00684         iluCurImage = ilGetCurImage();
    00685         if (iluCurImage == NULL) {
    00686                 ilSetError(ILU_ILLEGAL_OPERATION);
    00687                 return IL_FALSE;
    00688         }
    00689
    00690         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00691                 Palette = IL_TRUE;
    00692                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    00693         }
    00694         else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    00695                 Converted = IL_TRUE;
    00696                 Type = iluCurImage->Type;
    00697                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    00698         }
    00699
    00700         Data = Filter(iluCurImage, filter_embossedge, filter_embossedge_scale, filter_embossedge_bias);
    00701         if (!Data)
    00702                 return IL_FALSE;
    00703         ifree(iluCurImage->Data);
    00704         iluCurImage->Data = Data;
    00705
    00706         if (Palette)
    00707                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    00708         else if (Converted)
    00709                 ilConvertImage(iluCurImage->Format, Type);
    00710
    00711         return IL_TRUE;
    00712 }
    00713
    00714 ILboolean ILAPIENTRY iluScaleAlpha(ILfloat scale)
    00715 {
    00716         ILuint          i;
    00717         ILint           alpha;
    00718
    00719         iluCurImage = ilGetCurImage();
    00720         if (iluCurImage == NULL) {
    00721                 ilSetError(ILU_ILLEGAL_OPERATION);
    00722                 return IL_FALSE;
    00723         }
    00724
    00725         if( (iluCurImage->Format != IL_COLOUR_INDEX) && (iluCurImage->Type != IL_BYTE) ) {
    00726                 ilSetError(ILU_ILLEGAL_OPERATION);
    00727                 return IL_FALSE;
    00728         }
    00729
    00730         switch (iluCurImage->Format)
    00731         {
    00732                 case IL_BGRA:
    00733                 case IL_RGBA:
    00734                         for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00735                                 alpha = (ILint)(iluCurImage->Data[i+3] * scale);
    00736                                 if (alpha > UCHAR_MAX) alpha = UCHAR_MAX;
    00737                                 if (alpha < 0) alpha = 0;
    00738                                 iluCurImage->Data[i+3] = (ILubyte)alpha;
    00739                         }
    00740                         break;
    00741
    00742                 case IL_COLOUR_INDEX:
    00743                         switch (iluCurImage->Pal.PalType)
    00744                         {
    00745                                 case IL_PAL_RGBA32:
    00746                                 case IL_PAL_BGRA32:
    00747                                         for (i = 0; i < iluCurImage->Pal.PalSize; i += ilGetInteger(IL_PALETTE_BPP)) {
    00748                                                 alpha = (ILint)(iluCurImage->Pal.Palette[i+3] * scale);
    00749                                                 if (alpha > UCHAR_MAX) alpha = UCHAR_MAX;
    00750                                                 if (alpha < 0) alpha = 0;
    00751                                                 iluCurImage->Pal.Palette[i+3] = (ILubyte)alpha;
    00752                                         }
    00753                                         break;
    00754
    00755                                 default:
    00756                                         ilSetError(ILU_ILLEGAL_OPERATION);
    00757                                         return IL_FALSE;
    00758                         }
    00759                         break;
    00760
    00761                 default:
    00762                         ilSetError(ILU_ILLEGAL_OPERATION);
    00763                         return IL_FALSE;
    00764         }
    00765
    00766         return IL_TRUE;
    00767 }
    00768
    00769 // Everything here was taken from "Grafica Obscura",
    00770 //      found at http://www.sgi.com/grafica/matrix/index.html
    00771
    00772
    00773 // @TODO:  fast float to byte
    00775 ILboolean ILAPIENTRY iluScaleColours(ILfloat r, ILfloat g, ILfloat b) {
    00776         ILuint          i;
    00777         ILint           red, grn, blu, grey;
    00778         ILushort        *ShortPtr;
    00779         ILuint          *IntPtr, NumPix;
    00780         ILdouble        *DblPtr;
    00781
    00782         iluCurImage = ilGetCurImage();
    00783         if (iluCurImage == NULL) {
    00784                 ilSetError(ILU_ILLEGAL_OPERATION);
    00785                 return IL_FALSE;
    00786         }
    00787
    00788         if( (iluCurImage->Format != IL_COLOUR_INDEX) && (iluCurImage->Type != IL_BYTE) ) {
    00789                 ilSetError(ILU_ILLEGAL_OPERATION);
    00790                 return IL_FALSE;
    00791         }
    00792
    00793         switch (iluCurImage->Format)
    00794         {
    00795                 case IL_RGB:
    00796                 case IL_RGBA:
    00797                         for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00798                                 red = (ILint)(iluCurImage->Data[i] * r);
    00799                                 grn = (ILint)(iluCurImage->Data[i+1] * g);
    00800                                 blu = (ILint)(iluCurImage->Data[i+2] * b);
    00801                                 if (red > UCHAR_MAX) red = UCHAR_MAX;
    00802                                 if (red < 0) red = 0;
    00803                                 if (grn > UCHAR_MAX) grn = UCHAR_MAX;
    00804                                 if (grn < 0) grn = 0;
    00805                                 if (blu > UCHAR_MAX) blu = UCHAR_MAX;
    00806                                 if (blu < 0) blu = 0;
    00807                                 iluCurImage->Data[i]   = (ILubyte)red;
    00808                                 iluCurImage->Data[i+1] = (ILubyte)grn;
    00809                                 iluCurImage->Data[i+2] = (ILubyte)blu;
    00810                         }
    00811                         break;
    00812
    00813                 case IL_BGR:
    00814                 case IL_BGRA:
    00815                         for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00816                                 red = (ILint)(iluCurImage->Data[i+2] * r);
    00817                                 grn = (ILint)(iluCurImage->Data[i+1] * g);
    00818                                 blu = (ILint)(iluCurImage->Data[i] * b);
    00819                                 if (red > UCHAR_MAX) red = UCHAR_MAX;
    00820                                 if (red < 0) red = 0;
    00821                                 if (grn > UCHAR_MAX) grn = UCHAR_MAX;
    00822                                 if (grn < 0) grn = 0;
    00823                                 if (blu > UCHAR_MAX) blu = UCHAR_MAX;
    00824                                 if (blu < 0) blu = 0;
    00825                                 iluCurImage->Data[i+2] = (ILubyte)red;
    00826                                 iluCurImage->Data[i+1] = (ILubyte)grn;
    00827                                 iluCurImage->Data[i]   = (ILubyte)blu;
    00828                         }
    00829                         break;
    00830
    00831                 case IL_LUMINANCE:
    00832                 case IL_LUMINANCE_ALPHA:
    00833                         NumPix = iluCurImage->SizeOfData / (iluCurImage->Bpc*iluCurImage->Bpp);
    00834                         switch (iluCurImage->Bpc) {
    00835                                 case 1:
    00836                                         for (i = 0; i < NumPix; i+=iluCurImage->Bpp) {
    00837                                                 grey = (ILint)(iluCurImage->Data[i] * r);
    00838                                                 if (grey > UCHAR_MAX) grey = UCHAR_MAX;
    00839                                                 if (grey < 0) grey = 0;
    00840                                                 iluCurImage->Data[i] = (ILubyte)grey;
    00841                                         }
    00842                                         break;
    00843
    00844                                 case 2:
    00845                                         ShortPtr = (ILushort*)iluCurImage->Data;
    00846                                         for (i = 0; i < NumPix; i+=iluCurImage->Bpp) {
    00847                                                 grey = (ILint)(ShortPtr[i] * r);
    00848                                                 if (grey > USHRT_MAX) grey = USHRT_MAX;
    00849                                                 if (grey < 0) grey = 0;
    00850                                                 ShortPtr[i] = (ILushort)grey;
    00851                                         }
    00852                                         break;
    00853
    00854                                 case 4:
    00855                                         IntPtr = (ILuint*)iluCurImage->Data;
    00856                                         for (i = 0; i < NumPix; i+=iluCurImage->Bpp) {
    00857                                                 grey = (ILint)(IntPtr[i] * r);
    00858                                                 if (grey < 0) grey = 0;
    00859                                                 IntPtr[i] = (ILuint)grey;
    00860                                         }
    00861                                         break;
    00862
    00863                                 case 8:
    00864                                         DblPtr = (ILdouble*)iluCurImage->Data;
    00865                                         for (i = 0; i < NumPix; i+=iluCurImage->Bpp) {
    00866                                                 DblPtr[i] = DblPtr[i] * r;
    00867                                         }
    00868                                         break;
    00869                         }
    00870                         break;
    00871
    00872                 case IL_COLOUR_INDEX:
    00873                         switch (iluCurImage->Pal.PalType)
    00874                         {
    00875                                 case IL_PAL_RGB24:
    00876                                 case IL_PAL_RGB32:
    00877                                 case IL_PAL_RGBA32:
    00878                                         for (i = 0; i < iluCurImage->Pal.PalSize; i += ilGetInteger(IL_PALETTE_BPP)) {
    00879                                                 red = (ILint)(iluCurImage->Pal.Palette[i] * r);
    00880                                                 grn = (ILint)(iluCurImage->Pal.Palette[i+1] * g);
    00881                                                 blu = (ILint)(iluCurImage->Pal.Palette[i+2] * b);
    00882                                                 if (red > UCHAR_MAX) red = UCHAR_MAX;
    00883                                                 if (red < 0) red = 0;
    00884                                                 if (grn > UCHAR_MAX) grn = UCHAR_MAX;
    00885                                                 if (grn < 0) grn = 0;
    00886                                                 if (blu > UCHAR_MAX) blu = UCHAR_MAX;
    00887                                                 if (blu < 0) blu = 0;
    00888                                                 iluCurImage->Pal.Palette[i]   = (ILubyte)red;
    00889                                                 iluCurImage->Pal.Palette[i+1] = (ILubyte)grn;
    00890                                                 iluCurImage->Pal.Palette[i+2] = (ILubyte)blu;
    00891                                         }
    00892                                         break;
    00893
    00894                                 case IL_PAL_BGR24:
    00895                                 case IL_PAL_BGR32:
    00896                                 case IL_PAL_BGRA32:
    00897                                         for (i = 0; i < iluCurImage->Pal.PalSize; i += ilGetInteger(IL_PALETTE_BPP)) {
    00898                                                 red = (ILint)(iluCurImage->Pal.Palette[i+2] * r);
    00899                                                 grn = (ILint)(iluCurImage->Pal.Palette[i+1] * g);
    00900                                                 blu = (ILint)(iluCurImage->Pal.Palette[i] * b);
    00901                                                 if (red > UCHAR_MAX) red = UCHAR_MAX;
    00902                                                 if (red < 0) red = 0;
    00903                                                 if (grn > UCHAR_MAX) grn = UCHAR_MAX;
    00904                                                 if (grn < 0) grn = 0;
    00905                                                 if (blu > UCHAR_MAX) blu = UCHAR_MAX;
    00906                                                 if (blu < 0) blu = 0;
    00907                                                 iluCurImage->Pal.Palette[i+2]   = (ILubyte)red;
    00908                                                 iluCurImage->Pal.Palette[i+1] = (ILubyte)grn;
    00909                                                 iluCurImage->Pal.Palette[i] = (ILubyte)blu;
    00910                                         }
    00911                                         break;
    00912
    00913
    00914                                 default:
    00915                                         ilSetError(ILU_ILLEGAL_OPERATION);
    00916                                         return IL_FALSE;
    00917                         }
    00918                         break;
    00919
    00920                 default:
    00921                         ilSetError(ILU_ILLEGAL_OPERATION);
    00922                         return IL_FALSE;
    00923         }
    00924
    00925         return IL_TRUE;
    00926 }
    00927
    00928
    00929 /*ILboolean ILAPIENTRY iluGammaCorrectScale(ILfloat Gamma)
    00930 {
    00931         return iluScaleColours(Gamma, Gamma, Gamma);
    00932 }*/
    00933
    00934
    00935 ILboolean ILAPIENTRY iluGammaCorrect(ILfloat Gamma)
    00936 {
    00937         ILfloat         Table[256];
    00938         ILuint          i, NumPix;
    00939         ILushort        *ShortPtr;
    00940         ILuint          *IntPtr;
    00941
    00942         iluCurImage = ilGetCurImage();
    00943         if (iluCurImage == NULL) {
    00944                 ilSetError(ILU_ILLEGAL_OPERATION);
    00945                 return IL_FALSE;
    00946         }
    00947
    00948         for (i = 0; i < 256; i++) {
    00949                 Table[i] = (ILfloat)pow(i / 255.0, 1.0 / Gamma);
    00950         }
    00951
    00952         // Do we need to clamp here?
    00953         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00954                 for (i = 0; i < iluCurImage->Pal.PalSize; i++) {
    00955                         iluCurImage->Pal.Palette[i] = (ILubyte)(Table[iluCurImage->Pal.Palette[i]] * 255);
    00956                 }
    00957         }
    00958         else {
    00959                 // Not too sure if this is the correct way of handling multiple bpc's.
    00960                 switch (iluCurImage->Bpc)
    00961                 {
    00962                         case 1:
    00963                                 for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00964                                         iluCurImage->Data[i] = (ILubyte)(Table[iluCurImage->Data[i]] * UCHAR_MAX);
    00965                                 }
    00966                                 break;
    00967                         case 2:
    00968                                 NumPix = iluCurImage->SizeOfData / 2;
    00969                                 ShortPtr = (ILushort*)iluCurImage->Data;
    00970                                 for (i = 0; i < NumPix; i++) {
    00971                                         ShortPtr[i] = (ILushort)(Table[ShortPtr[i] >> 8] * USHRT_MAX);
    00972                                 }
    00973                                 break;
    00974                         case 4:
    00975                                 NumPix = iluCurImage->SizeOfData / 4;
    00976                                 IntPtr = (ILuint*)iluCurImage->Data;
    00977                                 for (i = 0; i < NumPix; i++) {
    00978                                         IntPtr[i] = (ILuint)(Table[IntPtr[i] >> 24] * UINT_MAX);
    00979                                 }
    00980                                 break;
    00981                 }
    00982         }
    00983
    00984         return IL_TRUE;
    00985 }
    00986
    00987
    00988 //
    00989 // Colour matrix stuff follows
    00990 // ---------------------------
    00991 //
    00992
    00993
    00994 void iApplyMatrix(ILimage *Image, ILfloat Mat[4][4])
    00995 {
    00996         ILubyte *Data = Image->Data;
    00997         ILuint  i;
    00998         ILubyte r, g, b;
    00999
    01000         switch (Image->Format)
    01001         {
    01002                 case IL_RGB:
    01003                 case IL_RGBA:
    01004                         for (i = 0; i < Image->SizeOfData; ) {
    01005                                 r = (ILubyte)(Data[i] * Mat[0][0] + Data[i+1] * Mat[1][0] +
    01006                                                                         Data[i+2] * Mat[2][0]);// + Mat[3][0]);
    01007                                 g = (ILubyte)(Data[i] * Mat[0][1] + Data[i+1] * Mat[1][1] +
    01008                                                                         Data[i+2] * Mat[2][1]);// + Mat[3][1]);
    01009                                 b = (ILubyte)(Data[i] * Mat[0][2] + Data[i+1] * Mat[1][2] +
    01010                                                                         Data[i+2] * Mat[2][2]);// + Mat[3][2]);
    01011                                 Data[i]   = r;
    01012                                 Data[i+1] = g;
    01013                                 Data[i+2] = b;
    01014                                 i += Image->Bpp;
    01015                         }
    01016                         break;
    01017
    01018                 case IL_BGR:
    01019                 case IL_BGRA:
    01020                         for (i = 0; i < Image->SizeOfData; ) {
    01021                                 r = (ILubyte)(Data[i] * Mat[0][2] + Data[i+1] * Mat[1][2] +
    01022                                                                         Data[i+2] * Mat[2][2]);// + Mat[3][2]);
    01023                                 g = (ILubyte)(Data[i] * Mat[0][1] + Data[i+1] * Mat[1][1] +
    01024                                                                         Data[i+2] * Mat[2][1]);// + Mat[3][1]);
    01025                                 b = (ILubyte)(Data[i] * Mat[0][0] + Data[i+1] * Mat[1][0] +
    01026                                                                         Data[i+2] * Mat[2][0]);// + Mat[3][0]);
    01027                                 Data[i]   = b;
    01028                                 Data[i+1] = g;
    01029                                 Data[i+2] = r;
    01030                                 i += Image->Bpp;
    01031                         }
    01032                         break;
    01033
    01034                 default:
    01035                         ilSetError(ILU_ILLEGAL_OPERATION);
    01036                         return;
    01037         }
    01038
    01039         return;
    01040 }
    01041
    01042
    01043 void iIdentity(ILfloat *Matrix)
    01044 {
    01045     *Matrix++ = 1.0;    // row 1
    01046     *Matrix++ = 0.0;
    01047     *Matrix++ = 0.0;
    01048     //*Matrix++ = 0.0;
    01049     *Matrix++ = 0.0;    // row 2
    01050     *Matrix++ = 1.0;
    01051     *Matrix++ = 0.0;
    01052     //*Matrix++ = 0.0;
    01053     *Matrix++ = 0.0;    // row 3
    01054     *Matrix++ = 0.0;
    01055     *Matrix++ = 1.0;
    01056     //*Matrix++ = 0.0;
    01061 }
    01062
    01063
    01064 ILboolean ILAPIENTRY iluSaturate1f(ILfloat Saturation)
    01065 {
    01066         return iluSaturate4f(0.3086f, 0.6094f, 0.0820f, Saturation);
    01067 }
    01068
    01069
    01070 ILboolean ILAPIENTRY iluSaturate4f(ILfloat r, ILfloat g, ILfloat b, ILfloat Saturation)
    01071 {
    01072         ILfloat Mat[4][4];
    01073         ILfloat s = Saturation;
    01074
    01075         Mat[0][0] = (1.0f - s) * r + s;
    01076         Mat[0][1] = (1.0f - s) * r;
    01077         Mat[0][2] = (1.0f - s) * r;
    01078         Mat[0][3] = 0.0f;
    01079
    01080         Mat[1][0] = (1.0f - s) * g;
    01081         Mat[1][1] = (1.0f - s) * g + s;
    01082         Mat[1][2] = (1.0f - s) * g;
    01083         Mat[1][3] = 0.0f;
    01084
    01085         Mat[2][0] = (1.0f - s) * b;
    01086         Mat[2][1] = (1.0f - s) * b;
    01087         Mat[2][2] = (1.0f - s) * b + s;
    01088         Mat[2][3] = 0.0f;
    01089
    01090         Mat[3][0] = 0.0f;
    01091         Mat[3][1] = 0.0f;
    01092         Mat[3][2] = 0.0f;
    01093         Mat[3][3] = 1.0f;
    01094
    01095         iluCurImage = ilGetCurImage();
    01096         if (iluCurImage == NULL) {
    01097                 ilSetError(ILU_ILLEGAL_OPERATION);
    01098                 return IL_FALSE;
    01099         }
    01100
    01101         iApplyMatrix(iluCurImage, Mat);
    01102
    01103         return IL_TRUE;
    01104 }
    01105
    01106
    01107
    01109 ILboolean ILAPIENTRY iluAlienify(void)
    01110 {
    01111         ILfloat Mat[3][3];
    01112         ILubyte *Data;
    01113         ILuint  i;
    01114
    01115         iluCurImage = ilGetCurImage();
    01116         if (iluCurImage == NULL) {
    01117                 ilSetError(ILU_ILLEGAL_OPERATION);
    01118                 return IL_FALSE;
    01119         }
    01120         Data = iluCurImage->Data;
    01121
    01122         iIdentity((ILfloat*)Mat);
    01123
    01124         switch (iluCurImage->Format)
    01125         {
    01126                 case IL_BGR:
    01127                 case IL_BGRA:
    01128                         for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    01129                                 Data[i+2] = (ILubyte)(Data[i] * Mat[0][0] + Data[i+1] * Mat[1][0] +
    01130                                                                         Data[i+2] * Mat[2][0]);// + Mat[3][0]);
    01131                                 Data[i+1] = (ILubyte)(Data[i] * Mat[0][1] + Data[i+1] * Mat[1][1] +
    01132                                                                         Data[i+2] * Mat[2][1]);// + Mat[3][1]);
    01133                                 Data[i]   = (ILubyte)(Data[i] * Mat[0][2] + Data[i+1] * Mat[1][2] +
    01134                                                                         Data[i+2] * Mat[2][2]);// + Mat[3][2]);
    01135                         }
    01136                 break;
    01137
    01138                 case IL_RGB:
    01139                 case IL_RGBA:
    01140                         for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    01141                                 Data[i]   = (ILubyte)(Data[i] * Mat[0][2] + Data[i+1] * Mat[1][2] +
    01142                                                                         Data[i+2] * Mat[2][2]);// + Mat[3][2]);
    01143                                 Data[i+1] = (ILubyte)(Data[i] * Mat[0][1] + Data[i+1] * Mat[1][1] +
    01144                                                                         Data[i+2] * Mat[2][1]);// + Mat[3][1]);
    01145                                 Data[i+2] = (ILubyte)(Data[i] * Mat[0][0] + Data[i+1] * Mat[1][0] +
    01146                                                                         Data[i+2] * Mat[2][0]);// + Mat[3][0]);
    01147                         }
    01148                 break;
    01149
    01150                 default:
    01151                         //ilSetError(ILU_ILLEGAL_OPERATION);
    01152                         return IL_FALSE;
    01153         }
    01154
    01155         return IL_TRUE;
    01156 }
    01157
    01158
    01159
    01160
    01161 // Everything here was taken from
    01162 //      http://bae.fse.missouri.edu/luw/course/image/project1/project1.html
    01163 //      and http://www.sgi.com/grafica/interp/index.html
    01164
    01165
    01166
    01167 void iIntExtImg(ILimage *Image1, ILimage *Image2, ILfloat a)
    01168 {
    01169         ILuint  i;
    01170         ILint   d;
    01171         ILubyte *Data1, *Data2;
    01172
    01173         Data1 = Image1->Data;
    01174         Data2 = Image2->Data;
    01175
    01176         for (i = 0; i < Image2->SizeOfData; i++) {
    01177                 d = (ILint)((1 - a) * *Data1 + a * *Data2);
    01178                 // Limit a pixel value to the range [0, 255]
    01179                 if (d < 0)
    01180                         d = 0;
    01181                 else if (d > 255)
    01182                         d = 255;
    01183                 *Data2 = d;
    01184
    01185                 Data1++;
    01186                 Data2++;
    01187         }
    01188
    01189         return;
    01190 }
    01191
    01192
    01193 // Works best when Gamma is in the range [0.0, 2.0].
    01194 /*ILboolean ILAPIENTRY iluGammaCorrectInter(ILfloat Gamma)
    01195 {
    01196         ILimage *Black;
    01197         ILuint  i;
    01198
    01199         iluCurImage = ilGetCurImage();
    01200         if (iluCurImage == NULL) {
    01201                 ilSetError(IL_ILLEGAL_OPERATION);
    01202                 return IL_FALSE;
    01203         }
    01204
    01205         Black = ilNewImage(iluCurImage->Width, iluCurImage->Height, iluCurImage->Depth, iluCurImage->Bpp, iluCurImage->Bpc);
    01206         if (Black == NULL) {
    01207                 return IL_FALSE;
    01208         }
    01209
    01210         // Make Black all 0's
    01211         for (i = 0; i < Black->SizeOfData; i++) {
    01212                 Black->Data[i] = 0;
    01213         }
    01214
    01215         iIntExtImg(Black, iluCurImage, Gamma);
    01216         ilCloseImage(Black);
    01217
    01218         return IL_TRUE;
    01219 }*/
    01220
    01221
    01222 // Works best when Contrast is in the range [-0.5, 1.7].
    01223 ILboolean ILAPIENTRY iluContrast(ILfloat Contrast)
    01224 {
    01225         ILimage *Grey;
    01226         ILuint  i;
    01227
    01228         iluCurImage = ilGetCurImage();
    01229         if (iluCurImage == NULL) {
    01230                 ilSetError(IL_ILLEGAL_OPERATION);
    01231                 return IL_FALSE;
    01232         }
    01233
    01234         Grey = ilNewImage(iluCurImage->Width, iluCurImage->Height, iluCurImage->Depth, iluCurImage->Bpp, iluCurImage->Bpc);
    01235         if (Grey == NULL) {
    01236                 return IL_FALSE;
    01237         }
    01238
    01239         // Make Grey all 127's
    01240         for (i = 0; i < Grey->SizeOfData; i++) {
    01241                 Grey->Data[i] = 127;
    01242         }
    01243
    01244         iIntExtImg(Grey, iluCurImage, Contrast);
    01245         ilCloseImage(Grey);
    01246
    01247         return IL_TRUE;
    01248 }
    01249
    01250
    01251 // Sharpens when Factor is in the range [1.0, 2.5].
    01252 // Blurs when Factor is in the range [0.0, 1.0].
    01253 ILboolean ILAPIENTRY iluSharpen(ILfloat Factor, ILuint Iter)
    01254 {
    01255         ILimage *Blur, *CurImage;  // iluBlur() changes iluCurImage
    01256         ILuint  i;
    01257
    01258         CurImage = ilGetCurImage();
    01259         if (CurImage == NULL) {
    01260                 ilSetError(ILU_ILLEGAL_OPERATION);
    01261                 return IL_FALSE;
    01262         }
    01263
    01264         Blur = ilNewImage(CurImage->Width, CurImage->Height, CurImage->Depth, CurImage->Bpp, CurImage->Bpc);
    01265         if (Blur == NULL) {
    01266                 return IL_FALSE;
    01267         }
    01268         ilCopyImageAttr(Blur, CurImage);
    01269
    01270         ilCopyPixels(0, 0, 0, CurImage->Width, CurImage->Height, 1, CurImage->Format, CurImage->Type, Blur->Data);
    01271         ilSetCurImage(Blur);
    01272         iluBlurGaussian(1);
    01273
    01274         for (i = 0; i < Iter; i++) {
    01275                 iIntExtImg(Blur, CurImage, Factor);
    01276         }
    01277
    01278         ilCloseImage(Blur);
    01279         ilSetCurImage(CurImage);
    01280
    01281         return IL_TRUE;
    01282 }
    01283
    01284
    01285 ILAPI ILboolean ILAPIENTRY iluConvolution(ILint *matrix, ILint scale, ILint bias) {
    01286         ILubyte         *Data;
    01287         ILboolean       Palette = IL_FALSE, Converted = IL_FALSE;
    01288         ILenum          Type = 0;
    01289         ILimage         *iluCurImage = ilGetCurImage();
    01290
    01291         if (iluCurImage == NULL) {
    01292                 ilSetError(ILU_ILLEGAL_OPERATION);
    01293                 return IL_FALSE;
    01294         }
    01295
    01296         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    01297                 Palette = IL_TRUE;
    01298                 ilConvertImage(ilGetPalBaseType(iluCurImage->Pal.PalType), IL_UNSIGNED_BYTE);
    01299         } else if (iluCurImage->Type > IL_UNSIGNED_BYTE) {
    01300                 Converted = IL_TRUE;
    01301                 Type = iluCurImage->Type;
    01302                 ilConvertImage(iluCurImage->Format, IL_UNSIGNED_BYTE);
    01303         }
    01304
    01305         Data = Filter(iluCurImage, matrix, scale, bias);
    01306         if (!Data)
    01307                 return IL_FALSE;
    01308         ifree(iluCurImage->Data);
    01309         iluCurImage->Data = Data;
    01310
    01311         if (Palette)
    01312                 ilConvertImage(IL_COLOUR_INDEX, IL_UNSIGNED_BYTE);
    01313         else if (Converted)
    01314                 ilConvertImage(iluCurImage->Format, Type);
    01315
    01316         return IL_TRUE;
    01317 }
    01318