- Main Page
- Data Structures
- Files

- File List

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

    00001 //-----------------------------------------------------------------------------
    00002 //
    00003 // ImageLib Utility Sources
    00004 // Copyright (C) 2000-2002 by Denton Woods
    00005 // Last modified: 08/11/2001 <--Y2K Compliant! =]
    00006 //
    00007 // Filename: src-ILU/src/ilu_manip.c
    00008 //
    00009 // Description: Generates mipmaps for the current image
    00010 //
    00011 //-----------------------------------------------------------------------------
    00012
    00013
    00014 #include "ilu_internal.h"
    00015 #include "ilu_mipmap.h"
    00016 #include "ilu_states.h"
    00017
    00018
    00019 ILimage *Original;  // So we can increment NumMips
    00020
    00021
    00022 // Note:  If any image is a non-power-of-2 image, it will automatically be
    00023 //      converted to a power-of-2 image by iluScaleImage, which is likely to
    00024 //      uglify the image. =]
    00025
    00026
    00027 // @TODO:  Check for 1 bpp textures!
    00028
    00029
    00030 // Currently changes all textures to powers of 2...should we change?
    00031 ILboolean iluBuild2DMipmaps()
    00032 {
    00033         ILimage         *Temp;
    00034         ILboolean       Resized = IL_FALSE;
    00035         ILuint          Width, Height;
    00036         ILenum          OldFilter;
    00037
    00038         iluCurImage = Original = ilGetCurImage();
    00039         if (Original == NULL) {
    00040                 ilSetError(ILU_ILLEGAL_OPERATION);
    00041                 return IL_FALSE;
    00042         }
    00043
    00044         // Get rid of any existing mipmaps.
    00045         if (Original->Mipmaps) {
    00046                 ilCloseImage(Original->Mipmaps);
    00047                 Original->Mipmaps = NULL;
    00048         }
    00049
    00050         Width = ilNextPower2(iluCurImage->Width);
    00051         Height = ilNextPower2(iluCurImage->Height);
    00052         if (iluCurImage->Width != Width || iluCurImage->Height != Height) {
    00053                 Resized = IL_TRUE;
    00054                 Temp = ilCopyImage_(ilGetCurImage());
    00055                 ilSetCurImage(Temp);
    00056                 OldFilter = iluFilter;
    00057                 iluImageParameter(ILU_FILTER, ILU_BILINEAR);
    00058                 iluScale(Width, Height, 1);
    00059                 iluImageParameter(ILU_FILTER, OldFilter);
    00060                 iluCurImage = ilGetCurImage();
    00061         }
    00062
    00063         CurMipMap = NULL;
    00064         iBuild2DMipmaps_(iluCurImage->Width >> 1, iluCurImage->Height >> 1);
    00065
    00066         if (Resized) {
    00067                 Original->Mipmaps = iluCurImage->Mipmaps;
    00068                 iluCurImage->Mipmaps = NULL;
    00069                 ilCloseImage(iluCurImage);
    00070                 ilSetCurImage(Original);
    00071         }
    00072
    00073         return IL_TRUE;
    00074 }
    00075
    00076
    00077 ILboolean iluBuild3DMipmaps()
    00078 {
    00079         ILimage         *Temp;
    00080         ILboolean       Resized = IL_FALSE;
    00081         ILuint          Width, Height, Depth;
    00082
    00083         iluCurImage = Original = ilGetCurImage();
    00084         if (Original == NULL) {
    00085                 ilSetError(ILU_ILLEGAL_OPERATION);
    00086                 return IL_FALSE;
    00087         }
    00088
    00089         // Get rid of any existing mipmaps.
    00090         if (Original->Mipmaps) {
    00091                 ilCloseImage(Original->Mipmaps);
    00092                 Original->Mipmaps = NULL;
    00093         }
    00094
    00095         Width = ilNextPower2(iluCurImage->Width);
    00096         Height = ilNextPower2(iluCurImage->Height);
    00097         Depth = ilNextPower2(iluCurImage->Depth);
    00098         if (iluCurImage->Width != Width || iluCurImage->Height != Height || iluCurImage->Depth != Depth) {
    00099                 Resized = IL_TRUE;
    00100                 Temp = ilCopyImage_(ilGetCurImage());
    00101                 ilSetCurImage(Temp);
    00102                 iluImageParameter(ILU_FILTER, ILU_BILINEAR);
    00103                 iluScale(Width, Height, Depth);
    00104                 iluImageParameter(ILU_FILTER, iluFilter);
    00105                 iluCurImage = ilGetCurImage();
    00106         }
    00107
    00108         CurMipMap = NULL;
    00109         iBuild3DMipmaps_(iluCurImage->Width >> 1, iluCurImage->Height >> 1, iluCurImage->Depth >> 1);
    00110
    00111         if (Resized) {
    00112                 Original->Mipmaps = iluCurImage->Mipmaps;
    00113                 iluCurImage->Mipmaps = NULL;
    00114                 ilCloseImage(iluCurImage);
    00115                 ilSetCurImage(Original);
    00116         }
    00117
    00118         return IL_TRUE;
    00119 }
    00120
    00121
    00122 ILboolean ILAPIENTRY iluBuildMipmaps()
    00123 {
    00124         iluCurImage = ilGetCurImage();
    00125         if (iluCurImage == NULL) {
    00126                 ilSetError(ILU_ILLEGAL_OPERATION);
    00127                 return IL_FALSE;
    00128         }
    00129
    00130         if (iluCurImage->Depth > 1)
    00131                 return iluBuild3DMipmaps();
    00132         /*if (iluCurImage->Height <= 1)
    00133                 return iluBuild1DMipmaps();*/  // 8-8-2001
    00134         return iluBuild2DMipmaps();
    00135 }
    00136
    00137
    00138 ILboolean iBuild1DMipmaps_(ILuint Width)
    00139 {
    00140         ILimage *MipMap;
    00141         ILuint i, j, c;
    00142
    00143         if (CurMipMap != NULL && CurMipMap->Width <= 1) {  // Already at the last mipmap
    00144                 CurMipMap->Next = NULL;  // Terminate the list
    00145                 return IL_TRUE;
    00146         }
    00147
    00148         MipMap = ilNewImage(Width, 1, 1, iluCurImage->Bpp, iluCurImage->Bpc);
    00149         if (MipMap == NULL) {
    00150                 if (CurMipMap != NULL)
    00151                         CurMipMap->Next = NULL;
    00152                 return IL_FALSE;
    00153         }
    00154
    00155         // Copies attributes
    00156         MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
    00157         MipMap->Format = iluCurImage->Format;
    00158         MipMap->Type = iluCurImage->Type;
    00159         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00160         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00161         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00162                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00163                 if (MipMap->Pal.Palette == NULL) {
    00164                         ilCloseImage(MipMap);
    00165                         return IL_FALSE;
    00166                 }
    00167                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00168         }
    00169
    00170         if (CurMipMap == NULL) {  // First mipmap
    00171                 iluCurImage->Mipmaps = MipMap;
    00172                 CurMipMap = iluCurImage;
    00173         }
    00174         else {
    00175                 CurMipMap->Next = MipMap;
    00176         }
    00177
    00178         for (c = 0; c < CurMipMap->Bpp; c++) {  // 8-12-2001
    00179                 for (i = 0, j = 0; i < Width; i++) {
    00180                         //the old code that was here had overflow problems...
    00181                         //(result was clamped to byte before the shift)
    00182                         MipMap->Data[i * MipMap->Bpp + c] =
    00183                                 (CurMipMap->Data[j * MipMap->Bpp + c]
    00184                                  + CurMipMap->Data[(j + 1) * MipMap->Bpp + c]) >> 1;
    00185                         j += 2;
    00186                 }
    00187         }
    00188
    00189         // 8-11-2001
    00190         CurMipMap = MipMap;
    00191         iBuild1DMipmaps_(MipMap->Width >> 1);
    00192
    00193         return IL_TRUE;
    00194 }
    00195
    00196
    00197 ILboolean iBuild1DMipmapsVertical_(ILuint Height)
    00198 {
    00199         ILimage *MipMap, *Src;
    00200         ILuint i = 0, j = 0, c;
    00201
    00202         if (CurMipMap != NULL && CurMipMap->Height <= 1) {  // Already at the last mipmap
    00203                 CurMipMap->Next = NULL;  // Terminate the list
    00204                 return IL_TRUE;
    00205         }
    00206
    00207         MipMap = ilNewImage(1, Height, 1, iluCurImage->Bpp, iluCurImage->Bpc);
    00208         if (MipMap == NULL) {
    00209                 if (CurMipMap != NULL)
    00210                         CurMipMap->Next = NULL;
    00211                 return IL_FALSE;
    00212         }
    00213
    00214         // Copies attributes
    00215         MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
    00216         MipMap->Format = iluCurImage->Format;
    00217         MipMap->Type = iluCurImage->Type;
    00218         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00219         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00220         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00221                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00222                 if (MipMap->Pal.Palette == NULL) {
    00223                         ilCloseImage(MipMap);
    00224                         return IL_FALSE;
    00225                 }
    00226                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00227         }
    00228
    00229         if (CurMipMap == NULL) {  // First mipmap
    00230                 iluCurImage->Mipmaps = MipMap;
    00231                 Src = iluCurImage;
    00232         }
    00233         else {
    00234                 CurMipMap->Next = MipMap;
    00235                 Src = CurMipMap;
    00236         }
    00237
    00238         for (c = 0; c < CurMipMap->Bpp; c++) {  // 8-12-2001
    00239                 //j = 0;
    00240                 for (i = 0, j = 0; i < Height; i++) {
    00241                         //the old code that was here had overflow problems...
    00242                         //(result was clamped to byte before the shift)
    00243                         MipMap->Data[i * MipMap->Bpp + c] =
    00244                                 (CurMipMap->Data[j * MipMap->Bpp + c]
    00245                                  + CurMipMap->Data[(j + 1) * MipMap->Bpp + c]) >> 1;
    00246                         j += 2;
    00247                 }
    00248         }
    00249         // 8-11-2001
    00250         CurMipMap = MipMap;
    00251         iBuild1DMipmapsVertical_(MipMap->Height >> 1);
    00252
    00253         return IL_TRUE;
    00254 }
    00255
    00256
    00257 ILboolean iBuild2DMipmaps_(ILuint Width, ILuint Height)
    00258 {
    00259         ILimage *MipMap, *Src;
    00260         ILuint  x1 = 0, x2 = 0, y1 = 0, y2 = 0, c;
    00261
    00262         if (CurMipMap) {
    00263                 if (CurMipMap->Width == 1 && CurMipMap->Height == 1) {  // Already at the last mipmap
    00264                         CurMipMap->Next = NULL;  // Terminate the list
    00265                         return IL_TRUE;
    00266                 }
    00267
    00268                 if (/*CurMipMap->*/Height == 1) {
    00269                         return iBuild1DMipmaps_(Width);
    00270                 }
    00271
    00272                 if (/*CurMipMap->*/Width == 1) {
    00273                         return iBuild1DMipmapsVertical_(Height);
    00274                 }
    00275         }
    00276         else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1) {  // 8-9-2001 - Not sure...
    00277                 ilSetError(ILU_ILLEGAL_OPERATION);
    00278                 return IL_FALSE;
    00279         }
    00280
    00281         if (Height == 0 && Width == 0) {
    00282                 ilSetError(ILU_INTERNAL_ERROR);
    00283                 return IL_FALSE;
    00284         }
    00285         // 8-9-2001 - Should these two if statements read == 0 || == 1?
    00286         if (Height == 0) {
    00287                 return iBuild1DMipmaps_(Width);
    00288         }
    00289         if (Width == 0) {
    00290                 return iBuild1DMipmapsVertical_(Height);  // 8-9-2001
    00291         }
    00292
    00293         MipMap = ilNewImage(Width, Height, 1, iluCurImage->Bpp, iluCurImage->Bpc);
    00294         if (MipMap == NULL) {
    00295                 if (CurMipMap != NULL)
    00296                         CurMipMap->Next = NULL;
    00297                 return IL_FALSE;
    00298         }
    00299
    00300         // Copies attributes
    00301         MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
    00302         MipMap->Format = iluCurImage->Format;
    00303         MipMap->Type = iluCurImage->Type;
    00304         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00305         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00306         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00307                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00308                 if (MipMap->Pal.Palette == NULL) {
    00309                         ilCloseImage(MipMap);
    00310                         return IL_FALSE;
    00311                 }
    00312                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00313         }
    00314
    00315         if (CurMipMap == NULL) {  // First mipmap
    00316                 iluCurImage->Mipmaps = MipMap;
    00317                 Src = iluCurImage;
    00318         }
    00319         else {
    00320                 CurMipMap->Next = MipMap;
    00321                 Src = CurMipMap;
    00322         }
    00323
    00324         if (MipMap->Type == IL_FLOAT) {
    00325                 ILfloat *DestFData = (ILfloat*)MipMap->Data;
    00326                 ILfloat *SrcFData = (ILfloat*)Src->Data;
    00327                 ILuint DestStride = MipMap->Bps / 4;
    00328                 ILuint SrcStride = Src->Bps / 4;
    00329                 for (y1 = 0; y1 < Height; y1++, y2 += 2) {
    00330                         x1 = 0;  x2 = 0;
    00331                         for (; x1 < Width; x1++, x2 += 2) {
    00332                                 for (c = 0; c < MipMap->Bpp; c++) {
    00333                                         DestFData[y1 * DestStride + x1 * MipMap->Bpp + c] = (
    00334                                                 SrcFData[y2 * SrcStride + x2 * MipMap->Bpp + c] +
    00335                                                 SrcFData[y2 * SrcStride + (x2 + 1) * MipMap->Bpp + c] +
    00336                                                 SrcFData[(y2 + 1) * SrcStride + x2 * MipMap->Bpp + c] +
    00337                                                 SrcFData[(y2 + 1) * SrcStride + (x2 + 1) * MipMap->Bpp + c]) * .25f;
    00338                                 }
    00339                         }
    00340                 }
    00341         }
    00342         else {
    00343                 for (y1 = 0; y1 < Height; y1++, y2 += 2) {
    00344                         x1 = 0;  x2 = 0;
    00345                         for (; x1 < Width; x1++, x2 += 2) {
    00346                                 for (c = 0; c < MipMap->Bpp; c++) {
    00347                                         MipMap->Data[y1 * MipMap->Bps + x1 * MipMap->Bpp + c] = (
    00348                                                 Src->Data[y2 * Src->Bps + x2 * MipMap->Bpp + c] +
    00349                                                 Src->Data[y2 * Src->Bps + (x2 + 1) * MipMap->Bpp + c] +
    00350                                                 Src->Data[(y2 + 1) * Src->Bps + x2 * MipMap->Bpp + c] +
    00351                                                 Src->Data[(y2 + 1) * Src->Bps + (x2 + 1) * MipMap->Bpp + c]) >> 2;
    00352                                 }
    00353                         }
    00354                 }
    00355         }
    00356
    00357         CurMipMap = MipMap;
    00358         iBuild2DMipmaps_(MipMap->Width >> 1, MipMap->Height >> 1);
    00359
    00360         return IL_TRUE;
    00361 }
    00362
    00363
    00364 ILboolean iBuild3DMipmaps_(ILuint Width, ILuint Height, ILuint Depth)
    00365 {
    00366         ILimage *MipMap, *Src;
    00367         ILuint  x1 = 0, x2 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
    00368
    00369         if (CurMipMap) {
    00370                 // Already at the last mipmap
    00371                 if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
    00372                         CurMipMap->Next = NULL;  // Terminate the list
    00373                         return IL_TRUE;
    00374                 }
    00375
    00376                 if (CurMipMap->Depth == 1) {
    00377                         return iBuild2DMipmaps_(Width, Height);
    00378                 }
    00379                 if (CurMipMap->Height == 1) {
    00380                         return iBuild3DMipmapsHorizontal_(Width, Depth);
    00381                 }
    00382
    00383                 if (CurMipMap->Width == 1) {
    00384                         return iBuild3DMipmapsVertical_(Height, Depth);
    00385                 }
    00386         }
    00387         else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1 && iluCurImage->Height <= 1) {
    00388                 ilSetError(ILU_ILLEGAL_OPERATION);
    00389                 return IL_FALSE;
    00390         }
    00391
    00392         if (Height == 0 && Width == 0 && Depth == 0) {
    00393                 ilSetError(ILU_INTERNAL_ERROR);
    00394                 return IL_FALSE;
    00395         }
    00396         if (Depth == 0) {
    00397                 return iBuild2DMipmaps_(Width, Height);
    00398         }
    00399         if (Height == 0) {
    00400                 return iBuild3DMipmapsHorizontal_(Width, Depth);
    00401         }
    00402         if (Width == 0) {
    00403                 return iBuild3DMipmapsVertical_(Height, Depth);
    00404         }
    00405
    00406         MipMap = ilNewImage(Width, Height, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
    00407         if (MipMap == NULL) {
    00408                 if (CurMipMap != NULL)
    00409                         CurMipMap->Next = NULL;
    00410                 return IL_FALSE;
    00411         }
    00412
    00413         // Copies attributes
    00414         MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
    00415         MipMap->Format = iluCurImage->Format;
    00416         MipMap->Type = iluCurImage->Type;
    00417         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00418         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00419         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00420                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00421                 if (MipMap->Pal.Palette == NULL) {
    00422                         ilCloseImage(MipMap);
    00423                         return IL_FALSE;
    00424                 }
    00425                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00426         }
    00427
    00428         if (CurMipMap == NULL) {  // First mipmap
    00429                 iluCurImage->Mipmaps = MipMap;
    00430                 Src = iluCurImage;
    00431         }
    00432         else {
    00433                 CurMipMap->Next = MipMap;
    00434                 Src = CurMipMap;
    00435         }
    00436
    00437         for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
    00438                 z3 = z1 * MipMap->SizeOfPlane;
    00439                 z4 = z2 * Src->SizeOfPlane;
    00440                 z5 = (z2 + 1) * Src->SizeOfPlane;
    00441
    00442                 y1 = 0;  y2 = 0;
    00443                 for (; y1 < Height; y1++, y2 += 2) {
    00444                         x1 = 0;  x2 = 0;
    00445                         for (; x1 < Width; x1++, x2 += 2) {
    00446                                 for (c = 0; c < MipMap->Bpp; c++) {
    00447                                         MipMap->Data[z1 * MipMap->SizeOfPlane + y1 * MipMap->Bps + x1 * MipMap->Bpp + c] = (
    00448                                                 Src->Data[z2 * Src->SizeOfPlane + y2 * Src->Bps + x2 * Src->Bpp + c] +
    00449                                                 Src->Data[z2 * Src->SizeOfPlane + y2 * Src->Bps + (x2 + 1) * Src->Bpp + c] +
    00450                                                 Src->Data[z2 * Src->SizeOfPlane + (y2 + 1) * Src->Bps + x2 * Src->Bpp + c] +
    00451                                                 Src->Data[z2 * Src->SizeOfPlane + (y2 + 1) * Src->Bps + (x2 + 1) * Src->Bpp + c] +
    00452                                                 Src->Data[(z2 + 1) * Src->SizeOfPlane + y2 * Src->Bps + x2 * Src->Bpp + c] +
    00453                                                 Src->Data[(z2 + 1) * Src->SizeOfPlane + y2 * Src->Bps + (x2 + 1) * Src->Bpp + c] +
    00454                                                 Src->Data[(z2 + 1) * Src->SizeOfPlane + (y2 + 1) * Src->Bps + x2 * Src->Bpp + c] +
    00455                                                 Src->Data[(z2 + 1) * Src->SizeOfPlane + (y2 + 1) * Src->Bps + (x2 + 1) * Src->Bpp + c]) / 8;
    00456                                 }
    00457                         }
    00458                 }
    00459         }
    00460
    00461         CurMipMap = MipMap;
    00462         iBuild3DMipmaps_(MipMap->Width >> 1, MipMap->Height >> 1, MipMap->Depth >> 1);
    00463
    00464         return IL_TRUE;
    00465 }
    00466
    00467
    00468 ILboolean iBuild3DMipmapsVertical_(ILuint Height, ILuint Depth)
    00469 {
    00470         ILimage *MipMap, *Src;
    00471         ILuint  y1 = 0, y2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
    00472
    00473         if (CurMipMap) {
    00474                 // Already at the last mipmap
    00475                 if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
    00476                         CurMipMap->Next = NULL;  // Terminate the list
    00477                         return IL_TRUE;
    00478                 }
    00479
    00480                 if (CurMipMap->Depth == 1) {
    00481                         return iBuild1DMipmapsVertical_(Height);
    00482                 }
    00483         }
    00484         else if (iluCurImage->Height <= 1 && iluCurImage->Height <= 1) {
    00485                 ilSetError(ILU_ILLEGAL_OPERATION);
    00486                 return IL_FALSE;
    00487         }
    00488
    00489         if (Height == 0 && Depth == 0) {
    00490                 ilSetError(ILU_INTERNAL_ERROR);
    00491                 return IL_FALSE;
    00492         }
    00493         if (Depth == 0) {
    00494                 return iBuild1DMipmapsVertical_(Height);
    00495         }
    00496
    00497         MipMap = ilNewImage(1, Height, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
    00498         if (MipMap == NULL) {
    00499                 if (CurMipMap != NULL)
    00500                         CurMipMap->Next = NULL;
    00501                 return IL_FALSE;
    00502         }
    00503
    00504         // Copies attributes
    00505         MipMap->Format = iluCurImage->Format;
    00506         MipMap->Type = iluCurImage->Type;
    00507         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00508         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00509         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00510                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00511                 if (MipMap->Pal.Palette == NULL) {
    00512                         ilCloseImage(MipMap);
    00513                         return IL_FALSE;
    00514                 }
    00515                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00516         }
    00517
    00518         if (CurMipMap == NULL) {  // First mipmap
    00519                 iluCurImage->Mipmaps = MipMap;
    00520                 Src = iluCurImage;
    00521         }
    00522         else {
    00523                 CurMipMap->Next = MipMap;
    00524                 Src = CurMipMap;
    00525         }
    00526
    00527         for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
    00528                 z3 = z1 * iluCurImage->SizeOfPlane;
    00529                 z4 = z2 * iluCurImage->SizeOfPlane;
    00530                 z5 = (z2 + 1) * iluCurImage->SizeOfPlane;
    00531
    00532                 for (y1 = 0; y1 < Height; y1++, y2 += 2) {
    00533                         for (c = 0; c < MipMap->Bpp; c++) {
    00534                                 MipMap->Data[z3 + y1 * MipMap->Bps + c] = (
    00535                                         Src->Data[z4 + y2 * Src->Bps + c] +
    00536                                         Src->Data[z4 + y2 * Src->Bps + c] +
    00537                                         Src->Data[z4 + (y2 + 1) * Src->Bps + c] +
    00538                                         Src->Data[z4 + (y2 + 1) * Src->Bps + c]) >> 2;
    00539                         }
    00540                 }
    00541         }
    00542
    00543         CurMipMap = MipMap;
    00544         iBuild3DMipmapsVertical_(MipMap->Height >> 1, MipMap->Depth >> 1);
    00545
    00546         return IL_TRUE;
    00547 }
    00548
    00549
    00550 ILboolean iBuild3DMipmapsHorizontal_(ILuint Width, ILuint Depth)
    00551 {
    00552         ILimage *MipMap, *Src;
    00553         ILuint  x1 = 0, x2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
    00554
    00555         if (CurMipMap) {
    00556                 // Already at the last mipmap
    00557                 if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
    00558                         CurMipMap->Next = NULL;  // Terminate the list
    00559                         return IL_TRUE;
    00560                 }
    00561
    00562                 if (CurMipMap->Depth == 1) {
    00563                         return iBuild1DMipmaps_(Width);
    00564                 }
    00565         }
    00566         else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1) {
    00567                 ilSetError(ILU_ILLEGAL_OPERATION);
    00568                 return IL_FALSE;
    00569         }
    00570
    00571         if (Width == 0 && Depth == 0) {
    00572                 ilSetError(ILU_INTERNAL_ERROR);
    00573                 return IL_FALSE;
    00574         }
    00575         if (Depth == 0) {
    00576                 return iBuild1DMipmaps_(Width);
    00577         }
    00578
    00579         MipMap = ilNewImage(Width, 1, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
    00580         if (MipMap == NULL) {
    00581                 if (CurMipMap != NULL)
    00582                         CurMipMap->Next = NULL;
    00583                 return IL_FALSE;
    00584         }
    00585
    00586         // Copies attributes
    00587         MipMap->Format = iluCurImage->Format;
    00588         MipMap->Type = iluCurImage->Type;
    00589         MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
    00590         MipMap->Pal.PalType = iluCurImage->Pal.PalType;
    00591         if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
    00592                 MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
    00593                 if (MipMap->Pal.Palette == NULL) {
    00594                         ilCloseImage(MipMap);
    00595                         return IL_FALSE;
    00596                 }
    00597                 memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
    00598         }
    00599
    00600         if (CurMipMap == NULL) {  // First mipmap
    00601                 iluCurImage->Mipmaps = MipMap;
    00602                 Src = iluCurImage;
    00603         }
    00604         else {
    00605                 CurMipMap->Next = MipMap;
    00606                 Src = CurMipMap;
    00607         }
    00608
    00609         for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
    00610                 z3 = z1 * iluCurImage->SizeOfPlane;
    00611                 z4 = z2 * iluCurImage->SizeOfPlane;
    00612                 z5 = (z2 + 1) * iluCurImage->SizeOfPlane;
    00613
    00614                 x1 = 0;  x2 = 0;
    00615                 for (; x1 < Width; x1++, x2 += 2) {
    00616                         for (c = 0; c < MipMap->Bpp; c++) {
    00617                                 MipMap->Data[z3 + x1 * MipMap->Bpp + c] = (
    00618                                         Src->Data[z4 + x2 * MipMap->Bpp + c] +
    00619                                         Src->Data[z4 + (x2 + 1) * MipMap->Bpp + c] +
    00620                                         Src->Data[z4 + x2 * MipMap->Bpp + c] +
    00621                                         Src->Data[z4 + (x2 + 1) * MipMap->Bpp + c]) >> 2;
    00622                         }
    00623                 }
    00624         }
    00625
    00626         CurMipMap = MipMap;
    00627         iBuild3DMipmapsHorizontal_(MipMap->Width >> 1, MipMap->Depth >> 1);
    00628
    00629         return IL_TRUE;
    00630 }