- Main Page
- Data Structures
- Files

- File List

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

    00001
    00002 #include "ilu_internal.h"
    00003 #include "ilu_states.h"
    00004 #include <float.h>
    00005 #include <limits.h>
    00006
    00007
    00008 ILboolean iluCrop2D(ILuint XOff, ILuint YOff, ILuint Width, ILuint Height) {
    00009         ILuint  x, y, c, OldBps;
    00010         ILubyte *Data;
    00011         ILenum  Origin;
    00012
    00013         iluCurImage = ilGetCurImage();
    00014         if (iluCurImage == NULL) {
    00015                 ilSetError(ILU_ILLEGAL_OPERATION);
    00016                 return IL_FALSE;
    00017         }
    00018
    00019         // Uh-oh, what about 0 dimensions?!
    00020         if (Width > iluCurImage->Width || Height > iluCurImage->Height) {
    00021                 ilSetError(ILU_ILLEGAL_OPERATION);
    00022                 return IL_FALSE;
    00023         }
    00024
    00025         Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
    00026         if (Data == NULL) {
    00027                 return IL_FALSE;
    00028         }
    00029
    00030         OldBps = iluCurImage->Bps;
    00031         Origin = iluCurImage->Origin;
    00032         ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, 1, iluCurImage->Format, iluCurImage->Type, Data);
    00033         if (!ilTexImage(Width, Height, iluCurImage->Depth, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL)) {
    00034                 free(Data);
    00035                 return IL_FALSE;
    00036         }
    00037         iluCurImage->Origin = Origin;
    00038
    00039         // @TODO:  Optimize!  (Especially XOff * iluCurImage->Bpp...get rid of it!)
    00040         for (y = 0; y < iluCurImage->Height; y++) {
    00041                 for (x = 0; x < iluCurImage->Bps; x += iluCurImage->Bpp) {
    00042                         for (c = 0; c < iluCurImage->Bpp; c++) {
    00043                                 iluCurImage->Data[y * iluCurImage->Bps + x + c] =
    00044                                         Data[(y + YOff) * OldBps + x + XOff * iluCurImage->Bpp + c];
    00045                         }
    00046                 }
    00047         }
    00048
    00049         ifree(Data);
    00050
    00051         return IL_TRUE;
    00052 }
    00053
    00054
    00055 ILboolean iluCrop3D(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth)
    00056 {
    00057         ILuint  x, y, z, c, OldBps, OldPlane;
    00058         ILubyte *Data;
    00059         ILenum  Origin;
    00060
    00061         iluCurImage = ilGetCurImage();
    00062         if (iluCurImage == NULL) {
    00063                 ilSetError(ILU_ILLEGAL_OPERATION);
    00064                 return IL_FALSE;
    00065         }
    00066
    00067         // Uh-oh, what about 0 dimensions?!
    00068         if (Width > iluCurImage->Width || Height > iluCurImage->Height || Depth > iluCurImage->Depth) {
    00069                 ilSetError(ILU_ILLEGAL_OPERATION);
    00070                 return IL_FALSE;
    00071         }
    00072
    00073         Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
    00074         if (Data == NULL) {
    00075                 return IL_FALSE;
    00076         }
    00077
    00078         OldBps = iluCurImage->Bps;
    00079         OldPlane = iluCurImage->SizeOfPlane;
    00080         Origin = iluCurImage->Origin;
    00081         ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, iluCurImage->Depth, iluCurImage->Format, iluCurImage->Type, Data);
    00082         if (!ilTexImage(Width - XOff, Height - YOff, Depth - ZOff, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL)) {
    00083                 ifree(Data);
    00084         }
    00085         iluCurImage->Origin = Origin;
    00086
    00087         for (z = 0; z < iluCurImage->Depth; z++) {
    00088                 for (y = 0; y < iluCurImage->Height; y++) {
    00089                         for (x = 0; x < iluCurImage->Bps; x += iluCurImage->Bpp) {
    00090                                 for (c = 0; c < iluCurImage->Bpp; c++) {
    00091                                         iluCurImage->Data[z * iluCurImage->SizeOfPlane + y * iluCurImage->Bps + x + c] =
    00092                                                 Data[(z + ZOff) * OldPlane + (y + YOff) * OldBps + (x + XOff) + c];
    00093                                 }
    00094                         }
    00095                 }
    00096         }
    00097
    00098         ifree(Data);
    00099
    00100         return IL_TRUE;
    00101 }
    00102
    00103
    00104 ILboolean ILAPIENTRY iluCrop(ILuint XOff, ILuint YOff, ILuint ZOff, ILuint Width, ILuint Height, ILuint Depth)
    00105 {
    00106         if (ZOff <= 1)
    00107                 return iluCrop2D(XOff, YOff, Width, Height);
    00108         return iluCrop3D(XOff, YOff, ZOff, Width, Height, Depth);
    00109 }
    00110
    00111
    00113 ILboolean ILAPIENTRY iluEnlargeCanvas(ILuint Width, ILuint Height, ILuint Depth)
    00114 {
    00115         ILubyte *Data/*, Clear[4]*/;
    00116         ILuint  x, y, z, OldBps, OldH, OldD, OldPlane, AddX, AddY;
    00117         ILenum  Origin;
    00118
    00119         iluCurImage = ilGetCurImage();
    00120         if (iluCurImage == NULL) {
    00121                 ilSetError(ILU_ILLEGAL_OPERATION);
    00122                 return IL_FALSE;
    00123         }
    00124
    00125         // Uh-oh, what about 0 dimensions?!
    00126         if (Width < iluCurImage->Width || Height < iluCurImage->Height || Depth < iluCurImage->Depth) {
    00127                 ilSetError(ILU_ILLEGAL_OPERATION);
    00128                 return IL_FALSE;
    00129         }
    00130
    00131         if (iluCurImage->Origin == IL_ORIGIN_LOWER_LEFT) {
    00132                 switch (iluPlacement)
    00133                 {
    00134                         case ILU_LOWER_LEFT:
    00135                                 AddX = 0;
    00136                                 AddY = 0;
    00137                                 break;
    00138                         case ILU_LOWER_RIGHT:
    00139                                 AddX = Width - iluCurImage->Width;
    00140                                 AddY = 0;
    00141                                 break;
    00142                         case ILU_UPPER_LEFT:
    00143                                 AddX = 0;
    00144                                 AddY = Height - iluCurImage->Height;
    00145                                 break;
    00146                         case ILU_UPPER_RIGHT:
    00147                                 AddX = Width - iluCurImage->Width;
    00148                                 AddY = Height - iluCurImage->Height;
    00149                                 break;
    00150                         case ILU_CENTER:
    00151                                 AddX = (Width - iluCurImage->Width) >> 1;
    00152                                 AddY = (Height - iluCurImage->Height) >> 1;
    00153                                 break;
    00154                         default:
    00155                                 ilSetError(ILU_INVALID_PARAM);
    00156                                 return IL_FALSE;
    00157                 }
    00158         }
    00159         else {  // IL_ORIGIN_UPPER_LEFT
    00160                 switch (iluPlacement)
    00161                 {
    00162                         case ILU_LOWER_LEFT:
    00163                                 AddX = 0;
    00164                                 AddY = Height - iluCurImage->Height;
    00165                                 break;
    00166                         case ILU_LOWER_RIGHT:
    00167                                 AddX = Width - iluCurImage->Width;
    00168                                 AddY = Height - iluCurImage->Height;
    00169                                 break;
    00170                         case ILU_UPPER_LEFT:
    00171                                 AddX = 0;
    00172                                 AddY = 0;
    00173                                 break;
    00174                         case ILU_UPPER_RIGHT:
    00175                                 AddX = Width - iluCurImage->Width;
    00176                                 AddY = 0;
    00177                                 break;
    00178                         case ILU_CENTER:
    00179                                 AddX = (Width - iluCurImage->Width) >> 1;
    00180                                 AddY = (Height - iluCurImage->Height) >> 1;
    00181                                 break;
    00182                         default:
    00183                                 ilSetError(ILU_INVALID_PARAM);
    00184                                 return IL_FALSE;
    00185                 }
    00186         }
    00187
    00188         AddX *= iluCurImage->Bpp;
    00189
    00190         Data = (ILubyte*)ialloc(iluCurImage->SizeOfData);
    00191         if (Data == NULL) {
    00192                 return IL_FALSE;
    00193         }
    00194
    00195         // Preserve old data.
    00196         OldPlane = iluCurImage->SizeOfPlane;
    00197         OldBps   = iluCurImage->Bps;
    00198         OldH     = iluCurImage->Height;
    00199         OldD     = iluCurImage->Depth;
    00200         Origin   = iluCurImage->Origin;
    00201         ilCopyPixels(0, 0, 0, iluCurImage->Width, iluCurImage->Height, OldD, iluCurImage->Format, iluCurImage->Type, Data);
    00202
    00203         ilTexImage(Width, Height, Depth, iluCurImage->Bpp, iluCurImage->Format, iluCurImage->Type, NULL);
    00204         iluCurImage->Origin = Origin;
    00205
    00206         ilClearImage();
    00207         /*ilGetClear(Clear);
    00208         if (iluCurImage->Bpp == 1) {
    00209                 memset(iluCurImage->Data, Clear[3], iluCurImage->SizeOfData);
    00210         }
    00211         else {
    00212                 for (x = 0; x < iluCurImage->SizeOfData; x += iluCurImage->Bpp) {
    00213                         for (y = 0; y < iluCurImage->Bpp; y++) {
    00214                                 iluCurImage->Data[y] = Clear[y];
    00215                         }
    00216                 }
    00217         }*/
    00218
    00219         for (z = 0; z < OldD; z++) {
    00220                 for (y = 0; y < OldH; y++) {
    00221                         for (x = 0; x < OldBps; x++) {
    00222                                 iluCurImage->Data[z * iluCurImage->SizeOfPlane + (y + AddY) * iluCurImage->Bps + x + AddX] =
    00223                                         Data[z * OldPlane + y * OldBps + x];
    00224                         }
    00225                 }
    00226         }
    00227
    00228         ifree(Data);
    00229
    00230         return IL_TRUE;
    00231 }
    00232
    00234 ILboolean ILAPIENTRY iluFlipImage() {
    00235         //ILubyte *StartPtr, *EndPtr;
    00236         //ILuint y, d;
    00237         ILimage *image = ilGetCurImage();
    00238
    00239         if( image == NULL ) {
    00240                 ilSetError(ILU_ILLEGAL_OPERATION);
    00241                 return IL_FALSE;
    00242         }
    00243
    00244         iFlipBuffer(image->Data,image->Depth,image->Bps,image->Height);
    00245         /*
    00246         for( d = 0; d < image->Depth; d++ ) {
    00247                 StartPtr = image->Data + d * image->SizeOfPlane;
    00248                 EndPtr   = image->Data + d * image->SizeOfPlane
    00249                                                 + image->SizeOfPlane;
    00250
    00251                 for( y = 0; y < (image->Height/2); y++ ) {
    00252                         EndPtr -= image->Bps;
    00253                         iMemSwap(StartPtr,EndPtr,image->Bps);
    00254                         StartPtr += image->Bps;
    00255                 }
    00256         }
    00257         */
    00258         return IL_TRUE;
    00259 }
    00260
    00261
    00263 ILboolean ILAPIENTRY iluMirror() {
    00264         return iMirror();
    00265 }
    00266
    00267
    00269 ILboolean ILAPIENTRY iluInvertAlpha() {
    00270         ILuint          i, *IntPtr, NumPix;
    00271         ILubyte         *Data;
    00272         ILushort        *ShortPtr;
    00273         ILfloat         *FltPtr;
    00274         ILdouble        *DblPtr;
    00275         ILubyte         Bpp;
    00276
    00277         iluCurImage = ilGetCurImage();
    00278         if (iluCurImage == NULL) {
    00279                 ilSetError(ILU_ILLEGAL_OPERATION);
    00280                 return IL_FALSE;
    00281         }
    00282
    00283         if (iluCurImage->Format != IL_RGBA &&
    00284                 iluCurImage->Format != IL_BGRA &&
    00285                 iluCurImage->Format != IL_LUMINANCE_ALPHA) {
    00286                         ilSetError(ILU_ILLEGAL_OPERATION);
    00287                         return IL_FALSE;
    00288         }
    00289
    00290         Data = iluCurImage->Data;
    00291         Bpp = iluCurImage->Bpp;
    00292         NumPix = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
    00293
    00294         switch (iluCurImage->Type)
    00295         {
    00296                 case IL_BYTE:
    00297                 case IL_UNSIGNED_BYTE:
    00298                         Data += (Bpp - 1);
    00299                         for( i = Bpp - 1; i < NumPix; i++, Data += Bpp )
    00300                                 *(Data) = ~*(Data);
    00301                         break;
    00302
    00303                 case IL_SHORT:
    00304                 case IL_UNSIGNED_SHORT:
    00305                         ShortPtr = ((ILushort*)Data) + Bpp-1;
    00306                         for (i = Bpp - 1; i < NumPix; i++, ShortPtr += Bpp)
    00307                                 *(ShortPtr) = ~*(ShortPtr);
    00308                         break;
    00309
    00310                 case IL_INT:
    00311                 case IL_UNSIGNED_INT:
    00312                         IntPtr = ((ILuint*)Data) + Bpp-1;
    00313                         for (i = Bpp - 1; i < NumPix; i++, IntPtr += Bpp)
    00314                                 *(IntPtr) = ~*(IntPtr);
    00315                         break;
    00316
    00317                 case IL_FLOAT:
    00318                         FltPtr = ((ILfloat*)Data) + Bpp - 1;
    00319                         for (i = Bpp - 1; i < NumPix; i++, FltPtr += Bpp)
    00320                                 *(FltPtr) = 1.0f - *(FltPtr);
    00321                         break;
    00322
    00323                 case IL_DOUBLE:
    00324                         DblPtr = ((ILdouble*)Data) + Bpp - 1;
    00325                         for (i = Bpp - 1; i < NumPix; i++, DblPtr += Bpp)
    00326                                 *(DblPtr) = 1.0f - *(DblPtr);
    00327                         break;
    00328         }
    00329
    00330         return IL_TRUE;
    00331 }
    00332
    00333
    00335 ILboolean ILAPIENTRY iluNegative()
    00336 {
    00337         ILuint          i, j, c, *IntPtr, NumPix, Bpp;
    00338         ILubyte         *Data;
    00339         ILushort        *ShortPtr;
    00340         ILubyte         *RegionMask;
    00341
    00342         iluCurImage = ilGetCurImage();
    00343         if (iluCurImage == NULL) {
    00344                 ilSetError(ILU_ILLEGAL_OPERATION);
    00345                 return IL_FALSE;
    00346         }
    00347
    00348         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00349                 if (!iluCurImage->Pal.Palette || !iluCurImage->Pal.PalSize || iluCurImage->Pal.PalType == IL_PAL_NONE) {
    00350                         ilSetError(ILU_ILLEGAL_OPERATION);
    00351                         return IL_FALSE;
    00352                 }
    00353                 Data = iluCurImage->Pal.Palette;
    00354                 i = iluCurImage->Pal.PalSize;
    00355         }
    00356         else {
    00357                 Data = iluCurImage->Data;
    00358                 i = iluCurImage->SizeOfData;
    00359         }
    00360
    00361         RegionMask = iScanFill();
    00362
    00363         // @TODO:  Optimize this some.
    00364
    00365         NumPix = i / iluCurImage->Bpc;
    00366         Bpp = iluCurImage->Bpp;
    00367
    00368         if (RegionMask) {
    00369                 switch (iluCurImage->Bpc)
    00370                 {
    00371                         case 1:
    00372                                 for (j = 0, i = 0; j < NumPix; j += Bpp, i++, Data += Bpp) {
    00373                                         for (c = 0; c < Bpp; c++) {
    00374                                                 if (RegionMask[i])
    00375                                                         *(Data+c) = ~*(Data+c);
    00376                                         }
    00377                                 }
    00378                                 break;
    00379
    00380                         case 2:
    00381                                 ShortPtr = (ILushort*)Data;
    00382                                 for (j = 0, i = 0; j < NumPix; j += Bpp, i++, ShortPtr += Bpp) {
    00383                                         for (c = 0; c < Bpp; c++) {
    00384                                                 if (RegionMask[i])
    00385                                                         *(ShortPtr+c) = ~*(ShortPtr+c);
    00386                                         }
    00387                                 }
    00388                                 break;
    00389
    00390                         case 4:
    00391                                 IntPtr = (ILuint*)Data;
    00392                                 for (j = 0, i = 0; j < NumPix; j += Bpp, i++, IntPtr += Bpp) {
    00393                                         for (c = 0; c < Bpp; c++) {
    00394                                                 if (RegionMask[i])
    00395                                                         *(IntPtr+c) = ~*(IntPtr+c);
    00396                                         }
    00397                                 }
    00398                                 break;
    00399                 }
    00400         }
    00401         else {
    00402                 switch (iluCurImage->Bpc)
    00403                 {
    00404                         case 1:
    00405                                 for (j = 0; j < NumPix; j++, Data++) {
    00406                                         *(Data) = ~*(Data);
    00407                                 }
    00408                                 break;
    00409
    00410                         case 2:
    00411                                 ShortPtr = (ILushort*)Data;
    00412                                 for (j = 0; j < NumPix; j++, ShortPtr++) {
    00413                                         *(ShortPtr) = ~*(ShortPtr);
    00414                                 }
    00415                                 break;
    00416
    00417                         case 4:
    00418                                 IntPtr = (ILuint*)Data;
    00419                                 for (j = 0; j < NumPix; j++, IntPtr++) {
    00420                                         *(IntPtr) = ~*(IntPtr);
    00421                                 }
    00422                                 break;
    00423                 }
    00424         }
    00425
    00426         ifree(RegionMask);
    00427
    00428         return IL_TRUE;
    00429 }
    00430
    00431
    00432 // Taken from
    00433 //      http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue2.html#Insight
    00434 //      Hope they don't mind too much. =]
    00435 ILboolean ILAPIENTRY iluWave(ILfloat Angle)
    00436 {
    00437         ILint   Delta;
    00438         ILuint  y;
    00439         ILubyte *DataPtr, *TempBuff;
    00440
    00441         iluCurImage = ilGetCurImage();
    00442         if (iluCurImage == NULL) {
    00443                 ilSetError(ILU_ILLEGAL_OPERATION);
    00444                 return IL_FALSE;
    00445         }
    00446
    00447         TempBuff = (ILubyte*)ialloc(iluCurImage->SizeOfData);
    00448         if (TempBuff == NULL) {
    00449                 return IL_FALSE;
    00450         }
    00451
    00452         for (y = 0; y < iluCurImage->Height; y++) {
    00453                 Delta = (ILint)
    00454                         (30 * sin((10 * Angle + y) * IL_DEGCONV) +
    00455                          15 * sin(( 7 * Angle + 3 * y) * IL_DEGCONV));
    00456
    00457                 DataPtr = iluCurImage->Data + y * iluCurImage->Bps;
    00458
    00459                 if (Delta < 0) {
    00460                         Delta = -Delta;
    00461                         memcpy(TempBuff, DataPtr, iluCurImage->Bpp * Delta);
    00462                         memcpy(DataPtr, DataPtr + iluCurImage->Bpp * Delta, iluCurImage->Bpp * (iluCurImage->Width - Delta));
    00463                         memcpy(DataPtr + iluCurImage->Bpp * (iluCurImage->Width - Delta), TempBuff, iluCurImage->Bpp * Delta);
    00464                 }
    00465                 else if (Delta > 0) {
    00466                         memcpy(TempBuff, DataPtr, iluCurImage->Bpp * (iluCurImage->Width - Delta));
    00467                         memcpy(DataPtr, DataPtr + iluCurImage->Bpp * (iluCurImage->Width - Delta), iluCurImage->Bpp * Delta);
    00468                         memcpy(DataPtr + iluCurImage->Bpp * Delta, TempBuff, iluCurImage->Bpp * (iluCurImage->Width - Delta));
    00469                 }
    00470         }
    00471
    00472         ifree(TempBuff);
    00473
    00474         return IL_TRUE;
    00475 }
    00476
    00477
    00478 // Swaps the colour order of the current image (rgb(a)->bgr(a) or vice-versa).
    00479 //      Must be either an 8, 24 or 32-bit (coloured) image (or palette).
    00480 ILboolean ILAPIENTRY iluSwapColours() {
    00481         // Use ilConvert or other like that to convert the data?
    00482         // and extend that function to work even on paletted data
    00483
    00484         ILimage *img = ilGetCurImage();
    00485         if( img == NULL ) {
    00486                 ilSetError(ILU_ILLEGAL_OPERATION);
    00487                 return IL_FALSE;
    00488         }
    00489
    00490         if (iluCurImage->Bpp == 1) {
    00491                 if (ilGetBppPal(iluCurImage->Pal.PalType) == 0 || iluCurImage->Format != IL_COLOUR_INDEX) {
    00492                         ilSetError(ILU_ILLEGAL_OPERATION);  // Can be luminance.
    00493                         return IL_FALSE;
    00494                 }
    00495
    00496                 switch( img->Pal.PalType ) {
    00497                         case IL_PAL_RGB24:
    00498                                 return ilConvertPal(IL_PAL_BGR24);
    00499                         case IL_PAL_RGB32:
    00500                                 return ilConvertPal(IL_PAL_BGR32);
    00501                         case IL_PAL_RGBA32:
    00502                                 return ilConvertPal(IL_PAL_BGRA32);
    00503                         case IL_PAL_BGR24:
    00504                                 return ilConvertPal(IL_PAL_RGB24);
    00505                         case IL_PAL_BGR32:
    00506                                 return ilConvertPal(IL_PAL_RGB32);
    00507                         case IL_PAL_BGRA32:
    00508                                 return ilConvertPal(IL_PAL_RGBA32);
    00509                         default:
    00510                                 ilSetError(ILU_INTERNAL_ERROR);
    00511                                 return IL_FALSE;
    00512                 }
    00513         }
    00514
    00515         switch( img->Format) {
    00516                 case IL_RGB:
    00517                         return ilConvertImage(IL_BGR, img->Type);
    00518                 case IL_RGBA:
    00519                         return ilConvertImage(IL_BGRA, img->Type);
    00520                 case IL_BGR:
    00521                         return ilConvertImage(IL_RGB, img->Type);
    00522                 case IL_BGRA:
    00523                         return ilConvertImage(IL_RGBA, img->Type);
    00524         }
    00525
    00526         ilSetError(ILU_INTERNAL_ERROR);
    00527         return IL_FALSE;
    00528 }
    00529
    00530
    00531 typedef struct BUCKET { ILubyte Colours[4];  struct BUCKET *Next; } BUCKET;
    00532
    00533 ILuint ILAPIENTRY iluColoursUsed()
    00534 {
    00535         ILuint i, c, Bpp, ColVal, SizeData, BucketPos = 0, NumCols = 0;
    00536         BUCKET Buckets[8192], *Temp;
    00537         ILubyte ColTemp[4];
    00538         ILboolean Matched;
    00539         BUCKET *Heap[9];
    00540         ILuint HeapPos = 0, HeapPtr = 0, HeapSize;
    00541
    00542         imemclear(Buckets, sizeof(BUCKET) * 8192);
    00543         for (c = 0; c < 9; c++) {
    00544                 Heap[c] = 0;
    00545         }
    00546
    00547         iluCurImage = ilGetCurImage();
    00548         if (iluCurImage == NULL) {
    00549                 ilSetError(ILU_ILLEGAL_OPERATION);
    00550                 return 0;
    00551         }
    00552
    00553         Bpp = iluCurImage->Bpp;
    00554         SizeData = iluCurImage->SizeOfData;
    00555
    00556         // Create our miniature memory heap.
    00557         // I have determined that the average number of colours versus
    00558         //      the number of pixels is about a 1:8 ratio, so divide by 8.
    00559         HeapSize = IL_MAX(1, iluCurImage->SizeOfData / iluCurImage->Bpp / 8);
    00560         Heap[0] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
    00561         if (Heap[0] == NULL)
    00562                 return IL_FALSE;
    00563
    00564         for (i = 0; i < SizeData; i += Bpp) {
    00565                 *(ILuint*)ColTemp = 0;
    00566                 /*for (c = 0; c < Bpp; c++) {
    00567                         ColTemp[c] = iluCurImage->Data[i + c];
    00568                 }*/
    00569                 ColTemp[0] = iluCurImage->Data[i];
    00570                 if (Bpp > 1) {
    00571                         ColTemp[1] = iluCurImage->Data[i + 1];
    00572                         ColTemp[2] = iluCurImage->Data[i + 2];
    00573                 }
    00574                 if (Bpp > 3)
    00575                         ColTemp[3] = iluCurImage->Data[i + 3];
    00576
    00577                 BucketPos = *(ILuint*)ColTemp % 8192;
    00578
    00579                 // Add to hash table
    00580                 if (Buckets[BucketPos].Next == NULL) {
    00581                         NumCols++;
    00582                         //Buckets[BucketPos].Next = (BUCKET*)ialloc(sizeof(BUCKET));
    00583                         Buckets[BucketPos].Next = Heap[HeapPos] + HeapPtr++;
    00584                         if (HeapPtr >= HeapSize) {
    00585                                 Heap[++HeapPos] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
    00586                                 if (Heap[HeapPos] == NULL)
    00587                                         goto alloc_error;
    00588                                 HeapPtr = 0;
    00589                         }
    00590                         *(ILuint*)Buckets[BucketPos].Next->Colours = *(ILuint*)ColTemp;
    00591                         Buckets[BucketPos].Next->Next = NULL;
    00592                 }
    00593                 else {
    00594                         Matched = IL_FALSE;
    00595                         Temp = Buckets[BucketPos].Next;
    00596
    00597                         ColVal = *(ILuint*)ColTemp;
    00598                         while (Temp->Next != NULL) {
    00599                                 if (ColVal == *(ILuint*)Temp->Colours) {
    00600                                         Matched = IL_TRUE;
    00601                                         break;
    00602                                 }
    00603                                 Temp = Temp->Next;
    00604                         }
    00605                         if (!Matched) {
    00606                                 if (ColVal != *(ILuint*)Temp->Colours) {  // Check against last entry
    00607                                         NumCols++;
    00608                                         Temp = Buckets[BucketPos].Next;
    00609                                         //Buckets[BucketPos].Next = (BUCKET*)ialloc(sizeof(BUCKET));
    00610                                         Buckets[BucketPos].Next = Heap[HeapPos] + HeapPtr++;
    00611                                         if (HeapPtr >= HeapSize) {
    00612                                                 Heap[++HeapPos] = (BUCKET*)ialloc(HeapSize * sizeof(BUCKET));
    00613                                                 if (Heap[HeapPos] == NULL)
    00614                                                         goto alloc_error;
    00615                                                 HeapPtr = 0;
    00616                                         }
    00617                                         Buckets[BucketPos].Next->Next = Temp;
    00618                                         *(ILuint*)Buckets[BucketPos].Next->Colours = *(ILuint*)ColTemp;
    00619                                 }
    00620                         }
    00621                 }
    00622         }
    00623
    00624         // Delete our mini heap.
    00625         for (i = 0; i < 9; i++) {
    00626                 if (Heap[i] == NULL)
    00627                         break;
    00628                 ifree(Heap[i]);
    00629         }
    00630
    00631         return NumCols;
    00632
    00633 alloc_error:
    00634         for (i = 0; i < 9; i++) {
    00635                 ifree(Heap[i]);
    00636         }
    00637
    00638         return 0;
    00639 }
    00640
    00641
    00642 ILboolean ILAPIENTRY iluCompareImage(ILuint Comp)
    00643 {
    00644         ILimage         *Original;
    00645         ILuint          OrigName, i;
    00646         ILboolean       Same = IL_TRUE;
    00647
    00648         iluCurImage = ilGetCurImage();
    00649         OrigName = ilGetCurName();
    00650
    00651         // Same image, so return true.
    00652         if (ilGetCurName() == Comp)
    00653                 return IL_TRUE;
    00654
    00655         if (iluCurImage == NULL || ilIsImage(Comp) == IL_FALSE) {
    00656                 ilSetError(ILU_ILLEGAL_OPERATION);
    00657                 return 0;
    00658         }
    00659
    00660         ilBindImage(Comp);
    00661     Original = ilGetCurImage();
    00662
    00663         // @TODO:  Should we check palettes, too?
    00664         if (Original->Bpp != iluCurImage->Bpp       ||
    00665                 Original->Depth != iluCurImage->Depth   ||
    00666                 Original->Format != iluCurImage->Format ||
    00667                 Original->Height != iluCurImage->Height ||
    00668                 Original->Origin != iluCurImage->Origin ||
    00669                 Original->Type != iluCurImage->Type ||
    00670                 Original->Width != iluCurImage->Width) {
    00671                         ilBindImage(OrigName);
    00672                         return IL_FALSE;
    00673         }
    00674
    00675         for (i = 0; i < iluCurImage->SizeOfData; i++) {
    00676                 if (Original->Data[i] != iluCurImage->Data[i]) {
    00677                         Same = IL_FALSE;
    00678                         break;
    00679                 }
    00680         }
    00681
    00682         ilBindImage(OrigName);
    00683         return Same;
    00684 }
    00685
    00686
    00687 // @TODO:  FIX ILGETCLEARCALL!
    00688 ILboolean ILAPIENTRY iluReplaceColour(ILubyte Red, ILubyte Green, ILubyte Blue, ILfloat Tolerance)
    00689 {
    00690         ILubyte ClearCol[4];
    00691         ILint   TolVal, Distance, Dist1, Dist2, Dist3;
    00692         ILuint  i, NumPix;
    00693
    00694         iluCurImage = ilGetCurImage();
    00695         if (iluCurImage == NULL) {
    00696                 ilSetError(ILU_ILLEGAL_OPERATION);
    00697                 return 0;
    00698         }
    00699
    00700         ilGetClear(ClearCol, IL_RGBA, IL_UNSIGNED_BYTE);
    00701         if (Tolerance > 1.0f || Tolerance < -1.0f)
    00702                 Tolerance = 1.0f;  // Clamp it.
    00703         TolVal = (ILuint)(fabs(Tolerance) * UCHAR_MAX);  // To be changed.
    00704         NumPix = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
    00705
    00706         if (Tolerance <= FLT_EPSILON && Tolerance >= 0) {
    00707
    00708             //@TODO what is this?
    00709         }
    00710         else {
    00711                 switch (iluCurImage->Format)
    00712                 {
    00713                         case IL_RGB:
    00714                         case IL_RGBA:
    00715                                 for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00716                                         Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
    00717                                         Dist2 = (ILint)iluCurImage->Data[i+1] - (ILint)ClearCol[1];
    00718                                         Dist3 = (ILint)iluCurImage->Data[i+2] - (ILint)ClearCol[2];
    00719                                         Distance = (ILint)sqrt((float)(Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3));
    00720                                         if (Distance >= -TolVal && Distance <= TolVal) {
    00721                                                 iluCurImage->Data[i] = Red;
    00722                                                 iluCurImage->Data[i+1] = Green;
    00723                                                 iluCurImage->Data[i+2] = Blue;
    00724                                         }
    00725                                 }
    00726                                 break;
    00727                         case IL_BGR:
    00728                         case IL_BGRA:
    00729                                 for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00730                                         Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
    00731                                         Dist2 = (ILint)iluCurImage->Data[i+1] - (ILint)ClearCol[1];
    00732                                         Dist3 = (ILint)iluCurImage->Data[i+2] - (ILint)ClearCol[2];
    00733                                         Distance = (ILint)sqrt((float)(Dist1 * Dist1 + Dist2 * Dist2 + Dist3 * Dist3));
    00734                                         if (Distance >= -TolVal && Distance <= TolVal) {
    00735                                                 iluCurImage->Data[i+2] = Red;
    00736                                                 iluCurImage->Data[i+1] = Green;
    00737                                                 iluCurImage->Data[i] = Blue;
    00738                                         }
    00739                                 }
    00740                                 break;
    00741                         case IL_LUMINANCE:
    00742                         case IL_LUMINANCE_ALPHA:
    00743                                 for (i = 0; i < iluCurImage->SizeOfData; i += iluCurImage->Bpp) {
    00744                                         Dist1 = (ILint)iluCurImage->Data[i] - (ILint)ClearCol[0];
    00745                                         if (Dist1 >= -TolVal && Dist1 <= TolVal) {
    00746                                                 iluCurImage->Data[i] = Blue;
    00747                                         }
    00748                                 }
    00749                                 break;
    00750                         //case IL_COLOUR_INDEX:  // @TODO
    00751                 }
    00752         }
    00753
    00754         return IL_TRUE;
    00755 }
    00756
    00757
    00758 // Credit goes to Lionel Brits for this (refer to credits.txt)
    00759 ILboolean ILAPIENTRY iluEqualize() {
    00760         ILuint  Histogram[256]; // image Histogram
    00761         ILuint  SumHistm[256]; // normalized Histogram and LUT
    00762         ILuint  i = 0; // index variable
    00763         ILuint  j = 0; // index variable
    00764         ILuint  Sum=0;
    00765         ILuint  NumPixels, Bpp;
    00766         ILint   Intensity;
    00767         ILfloat Scale;
    00768         ILint   IntensityNew;
    00769         ILimage *LumImage;
    00770         ILuint  NewColour[4];
    00771         ILubyte         *BytePtr;
    00772         ILushort        *ShortPtr;
    00773         ILuint          *IntPtr;
    00774
    00775         NewColour[0] = NewColour[1] = NewColour[2] = NewColour[3] = 0;
    00776
    00777         iluCurImage = ilGetCurImage();
    00778         if (iluCurImage == NULL) {
    00779                 ilSetError(ILU_ILLEGAL_OPERATION);
    00780                 return 0;
    00781         }
    00782
    00783         // @TODO:  Change to work with other types!
    00784         if (iluCurImage->Bpc > 1) {
    00785                 ilSetError(ILU_INTERNAL_ERROR);
    00786                 return IL_FALSE;
    00787         }
    00788
    00789         if (iluCurImage->Format == IL_COLOUR_INDEX) {
    00790                 NumPixels = iluCurImage->Pal.PalSize / ilGetBppPal(iluCurImage->Pal.PalType);
    00791                 Bpp = ilGetBppPal(iluCurImage->Pal.PalType);
    00792         } else {
    00793                 NumPixels = iluCurImage->Width * iluCurImage->Height * iluCurImage->Depth;
    00794                 Bpp = iluCurImage->Bpp;
    00795         }
    00796
    00797         // Clear the tables.
    00798         imemclear(Histogram, 256 * sizeof(ILuint));
    00799         imemclear(SumHistm,  256 * sizeof(ILuint));
    00800
    00801         LumImage = iConvertImage(iluCurImage, IL_LUMINANCE, IL_UNSIGNED_BYTE); // the type must be left as it is!
    00802         if (LumImage == NULL)
    00803                 return IL_FALSE;
    00804         for (i = 0; i < NumPixels; i++) {
    00805                 Histogram[LumImage->Data[i]]++;
    00806         }
    00807
    00808         // Calculate normalized Sum of Histogram.
    00809         for (i = 0; i < 256; i++) {
    00810                 for (j = 0; j < i; j++)
    00811                         Sum += Histogram[j];
    00812
    00813                 SumHistm[i] = (Sum << 8) / NumPixels;
    00814                 Sum = 0;
    00815         }
    00816
    00817
    00818         BytePtr = (iluCurImage->Format == IL_COLOUR_INDEX) ? iluCurImage->Pal.Palette : iluCurImage->Data;
    00819         ShortPtr = (ILushort*)iluCurImage->Data;
    00820         IntPtr = (ILuint*)iluCurImage->Data;
    00821
    00822         // Transform image using new SumHistm as a LUT
    00823         for (i = 0; i < NumPixels; i++) {
    00824                 Intensity = LumImage->Data[i];
    00825
    00826                 // Look up the normalized intensity
    00827                 IntensityNew = (ILint)SumHistm[Intensity];
    00828
    00829                 // Find out by how much the intensity has been Scaled
    00830                 Scale = (ILfloat)IntensityNew / (ILfloat)Intensity;
    00831
    00832                 switch (iluCurImage->Bpc)
    00833                 {
    00834                         case 1:
    00835                                 // Calculate new pixel(s)
    00836                                 NewColour[0] = (ILuint)(BytePtr[i * iluCurImage->Bpp] * Scale);
    00837                                 if (Bpp >= 3) {
    00838                                         NewColour[1] = (ILuint)(BytePtr[i * iluCurImage->Bpp + 1] * Scale);
    00839                                         NewColour[2] = (ILuint)(BytePtr[i * iluCurImage->Bpp + 2] * Scale);
    00840                                 }
    00841
    00842                                 // Clamp values
    00843                                 if (NewColour[0] > UCHAR_MAX)
    00844                                         NewColour[0] = UCHAR_MAX;
    00845                                 if (Bpp >= 3) {
    00846                                         if (NewColour[1] > UCHAR_MAX)
    00847                                                 NewColour[1] = UCHAR_MAX;
    00848                                         if (NewColour[2] > UCHAR_MAX)
    00849                                                 NewColour[2] = UCHAR_MAX;
    00850                                 }
    00851
    00852                                 // Store pixel(s)
    00853                                 BytePtr[i * iluCurImage->Bpp] = (ILubyte)NewColour[0];
    00854                                 if (Bpp >= 3) {
    00855                                         BytePtr[i * iluCurImage->Bpp + 1]       = (ILubyte)NewColour[1];
    00856                                         BytePtr[i * iluCurImage->Bpp + 2]       = (ILubyte)NewColour[2];
    00857                                 }
    00858                                 break;
    00859
    00860                         /*case 2:
    00861                                 // Calculate new pixel
    00862                                 NewColour[0] = (ILuint)(ShortPtr[i * iluCurImage->Bpp] * Scale);
    00863                                 NewColour[1] = (ILuint)(ShortPtr[i * iluCurImage->Bpp + 1] * Scale);
    00864                                 NewColour[2] = (ILuint)(ShortPtr[i * iluCurImage->Bpp + 2] * Scale);
    00865
    00866                                 // Clamp values
    00867                                 if (NewColour[0] > USHRT_MAX)
    00868                                         NewColour[0] = USHRT_MAX;
    00869                                 if (NewColour[1] > USHRT_MAX)
    00870                                         NewColour[1] = USHRT_MAX;
    00871                                 if (NewColour[2] > USHRT_MAX)
    00872                                         NewColour[2] = USHRT_MAX;
    00873
    00874                                 // Store pixel
    00875                                 ShortPtr[i * iluCurImage->Bpp]          = (ILushort)NewColour[0];
    00876                                 ShortPtr[i * iluCurImage->Bpp + 1]      = (ILushort)NewColour[1];
    00877                                 ShortPtr[i * iluCurImage->Bpp + 2]      = (ILushort)NewColour[2];
    00878                                 break;
    00879
    00880                         case 4:
    00881                                 // Calculate new pixel
    00882                                 NewColour[0] = (ILuint)(IntPtr[i * iluCurImage->Bpp] * Scale);
    00883                                 NewColour[1] = (ILuint)(IntPtr[i * iluCurImage->Bpp + 1] * Scale);
    00884                                 NewColour[2] = (ILuint)(IntPtr[i * iluCurImage->Bpp + 2] * Scale);
    00885
    00886                                 // Clamp values
    00887                                 if (NewColour[0] > UINT_MAX)
    00888                                         NewColour[0] = UINT_MAX;
    00889                                 if (NewColour[1] > UINT_MAX)
    00890                                         NewColour[1] = UINT_MAX;
    00891                                 if (NewColour[2] > UINT_MAX)
    00892                                         NewColour[2] = UINT_MAX;
    00893
    00894                                 // Store pixel
    00895                                 IntPtr[i * 4 * iluCurImage->Bpp]                = NewColour[0];
    00896                                 IntPtr[i * 4 * iluCurImage->Bpp + 1]    = NewColour[1];
    00897                                 IntPtr[i * 4 * iluCurImage->Bpp + 2]    = NewColour[2];
    00898                                 break;*/
    00899                 }
    00900         }
    00901
    00902         ilCloseImage(LumImage);
    00903
    00904         return IL_TRUE;
    00905 }