~ubuntu-branches/ubuntu/hoary/devil/hoary

« back to all changes in this revision

Viewing changes to src-ILU/src/ilu_mipmap.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2005-01-03 19:57:42 UTC
  • Revision ID: james.westby@ubuntu.com-20050103195742-4ipkplcwygu3irv0
Tags: upstream-1.6.7
ImportĀ upstreamĀ versionĀ 1.6.7

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//-----------------------------------------------------------------------------
 
2
//
 
3
// ImageLib Utility Sources
 
4
// Copyright (C) 2000-2002 by Denton Woods
 
5
// Last modified: 08/11/2001 <--Y2K Compliant! =]
 
6
//
 
7
// Filename: src-ILU/src/ilu_manip.c
 
8
//
 
9
// Description: Generates mipmaps for the current image
 
10
//
 
11
//-----------------------------------------------------------------------------
 
12
 
 
13
 
 
14
#include "ilu_internal.h"
 
15
#include "ilu_mipmap.h"
 
16
#include "ilu_states.h"
 
17
 
 
18
 
 
19
ILimage *Original;  // So we can increment NumMips
 
20
 
 
21
 
 
22
// Note:  If any image is a non-power-of-2 image, it will automatically be
 
23
//      converted to a power-of-2 image by iluScaleImage, which is likely to
 
24
//      uglify the image. =]
 
25
 
 
26
 
 
27
// @TODO:  Check for 1 bpp textures!
 
28
 
 
29
 
 
30
// Currently changes all textures to powers of 2...should we change?
 
31
ILboolean iluBuild2DMipmaps()
 
32
{
 
33
        ILimage         *Temp;
 
34
        ILboolean       Resized = IL_FALSE;
 
35
        ILuint          Width, Height;
 
36
        ILenum          OldFilter;
 
37
 
 
38
        iluCurImage = Original = ilGetCurImage();
 
39
        if (Original == NULL) {
 
40
                ilSetError(ILU_ILLEGAL_OPERATION);
 
41
                return IL_FALSE;
 
42
        }
 
43
 
 
44
        // Get rid of any existing mipmaps.
 
45
        if (Original->Mipmaps) {
 
46
                ilCloseImage(Original->Mipmaps);
 
47
                Original->Mipmaps = NULL;
 
48
        }
 
49
        Original->NumMips = 0;
 
50
 
 
51
        Width = ilNextPower2(iluCurImage->Width);
 
52
        Height = ilNextPower2(iluCurImage->Height);
 
53
        if (iluCurImage->Width != Width || iluCurImage->Height != Height) {
 
54
                Resized = IL_TRUE;
 
55
                Temp = ilCopyImage_(ilGetCurImage());
 
56
                ilSetCurImage(Temp);
 
57
                OldFilter = iluFilter;
 
58
                iluImageParameter(ILU_FILTER, ILU_BILINEAR);
 
59
                iluScale(Width, Height, 1);
 
60
                iluImageParameter(ILU_FILTER, OldFilter);
 
61
                iluCurImage = ilGetCurImage();
 
62
        }
 
63
 
 
64
        CurMipMap = NULL;
 
65
        iBuild2DMipmaps_(iluCurImage->Width >> 1, iluCurImage->Height >> 1);
 
66
 
 
67
        if (Resized) {
 
68
                Original->Mipmaps = iluCurImage->Mipmaps;
 
69
                iluCurImage->Mipmaps = NULL;
 
70
                ilCloseImage(iluCurImage);
 
71
                ilSetCurImage(Original);
 
72
        }
 
73
 
 
74
        return IL_TRUE;
 
75
}
 
76
 
 
77
 
 
78
ILboolean iluBuild3DMipmaps()
 
79
{
 
80
        ILimage         *Temp;
 
81
        ILboolean       Resized = IL_FALSE;
 
82
        ILuint          Width, Height, Depth;
 
83
 
 
84
        iluCurImage = Original = ilGetCurImage();
 
85
        if (Original == NULL) {
 
86
                ilSetError(ILU_ILLEGAL_OPERATION);
 
87
                return IL_FALSE;
 
88
        }
 
89
 
 
90
        // Get rid of any existing mipmaps.
 
91
        if (Original->Mipmaps) {
 
92
                ilCloseImage(Original->Mipmaps);
 
93
                Original->Mipmaps = NULL;
 
94
        }
 
95
        Original->NumMips = 0;
 
96
 
 
97
        Width = ilNextPower2(iluCurImage->Width);
 
98
        Height = ilNextPower2(iluCurImage->Height);
 
99
        Depth = ilNextPower2(iluCurImage->Depth);
 
100
        if (iluCurImage->Width != Width || iluCurImage->Height != Height || iluCurImage->Depth != Depth) {
 
101
                Resized = IL_TRUE;
 
102
                Temp = ilCopyImage_(ilGetCurImage());
 
103
                ilSetCurImage(Temp);
 
104
                iluImageParameter(ILU_FILTER, ILU_BILINEAR);
 
105
                iluScale(Width, Height, Depth);
 
106
                iluImageParameter(ILU_FILTER, iluFilter);
 
107
                iluCurImage = ilGetCurImage();
 
108
        }
 
109
 
 
110
        CurMipMap = NULL;
 
111
        iBuild3DMipmaps_(iluCurImage->Width >> 1, iluCurImage->Height >> 1, iluCurImage->Depth >> 1);
 
112
 
 
113
        if (Resized) {
 
114
                Original->Mipmaps = iluCurImage->Mipmaps;
 
115
                iluCurImage->Mipmaps = NULL;
 
116
                ilCloseImage(iluCurImage);
 
117
                ilSetCurImage(Original);
 
118
        }
 
119
 
 
120
        return IL_TRUE;
 
121
}
 
122
 
 
123
 
 
124
ILboolean ILAPIENTRY iluBuildMipmaps()
 
125
{
 
126
        iluCurImage = ilGetCurImage();
 
127
        if (iluCurImage == NULL) {
 
128
                ilSetError(ILU_ILLEGAL_OPERATION);
 
129
                return IL_FALSE;
 
130
        }
 
131
 
 
132
        if (iluCurImage->Depth > 1)
 
133
                return iluBuild3DMipmaps();
 
134
        /*if (iluCurImage->Height <= 1)
 
135
                return iluBuild1DMipmaps();*/  // 8-8-2001
 
136
        return iluBuild2DMipmaps();
 
137
}
 
138
 
 
139
 
 
140
ILboolean iBuild1DMipmaps_(ILuint Width)
 
141
{
 
142
        ILimage *MipMap;
 
143
        ILuint i, j, c;
 
144
 
 
145
        if (CurMipMap->Width <= 1) {  // Already at the last mipmap
 
146
                CurMipMap->Next = NULL;  // Terminate the list
 
147
                return IL_TRUE;
 
148
        }
 
149
 
 
150
        MipMap = ilNewImage(Width, 1, 1, iluCurImage->Bpp, iluCurImage->Bpc);
 
151
        if (MipMap == NULL) {
 
152
                if (CurMipMap != NULL)
 
153
                        CurMipMap->Next = NULL;
 
154
                return IL_FALSE;
 
155
        }
 
156
 
 
157
        // Copies attributes
 
158
        MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
 
159
        MipMap->Format = iluCurImage->Format;
 
160
        MipMap->Type = iluCurImage->Type;
 
161
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
162
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
163
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
164
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
165
                if (MipMap->Pal.Palette == NULL) {
 
166
                        ilCloseImage(MipMap);
 
167
                        return IL_FALSE;
 
168
                }
 
169
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
170
        }
 
171
 
 
172
        if (CurMipMap == NULL) {  // First mipmap
 
173
                iluCurImage->Mipmaps = MipMap;
 
174
        }
 
175
        else {
 
176
                CurMipMap->Next = MipMap;
 
177
        }
 
178
 
 
179
        for (c = 0; c < CurMipMap->Bpp; c++) {  // 8-12-2001
 
180
                for (i = 0, j = 0; i < Width; i++) {
 
181
                        MipMap->Data[i * MipMap->Bpp + c] =  CurMipMap->Data[(j++ * MipMap->Bpp) + c];
 
182
                                                MipMap->Data[i * MipMap->Bpp + c] += CurMipMap->Data[(j++ * MipMap->Bpp) + c];
 
183
                                                MipMap->Data[i * MipMap->Bpp + c] >>= 1;
 
184
                }
 
185
        }
 
186
        // 8-11-2001
 
187
        CurMipMap = MipMap;
 
188
        iBuild1DMipmaps_(MipMap->Width >> 1);
 
189
        Original->NumMips++;
 
190
 
 
191
        return IL_TRUE;
 
192
}
 
193
 
 
194
 
 
195
ILboolean iBuild1DMipmapsVertical_(ILuint Height)
 
196
{
 
197
        ILimage *MipMap, *Src;
 
198
        ILuint i = 0, j = 0, c;
 
199
 
 
200
        if (CurMipMap->Height <= 1) {  // Already at the last mipmap
 
201
                CurMipMap->Next = NULL;  // Terminate the list
 
202
                return IL_TRUE;
 
203
        }
 
204
 
 
205
        MipMap = ilNewImage(1, Height, 1, iluCurImage->Bpp, iluCurImage->Bpc);
 
206
        if (MipMap == NULL) {
 
207
                if (CurMipMap != NULL)
 
208
                        CurMipMap->Next = NULL;
 
209
                return IL_FALSE;
 
210
        }
 
211
 
 
212
        // Copies attributes
 
213
        MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
 
214
        MipMap->Format = iluCurImage->Format;
 
215
        MipMap->Type = iluCurImage->Type;
 
216
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
217
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
218
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
219
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
220
                if (MipMap->Pal.Palette == NULL) {
 
221
                        ilCloseImage(MipMap);
 
222
                        return IL_FALSE;
 
223
                }
 
224
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
225
        }
 
226
 
 
227
        if (CurMipMap == NULL) {  // First mipmap
 
228
                iluCurImage->Mipmaps = MipMap;
 
229
                Src = iluCurImage;
 
230
        }
 
231
        else {
 
232
                CurMipMap->Next = MipMap;
 
233
                Src = CurMipMap;
 
234
        }
 
235
 
 
236
        for (c = 0; c < CurMipMap->Bpp; c++) {  // 8-12-2001
 
237
                //j = 0;
 
238
                for (i = 0, j = 0; i < Height; i++) {
 
239
                        MipMap->Data[i * MipMap->Bpp + c] =  CurMipMap->Data[(j++ * MipMap->Bpp) + c];
 
240
                                                MipMap->Data[i * MipMap->Bpp + c] += CurMipMap->Data[(j++ * MipMap->Bpp) + c];
 
241
                                                MipMap->Data[i * MipMap->Bpp + c] >>= 1;
 
242
                }
 
243
        }
 
244
        // 8-11-2001
 
245
        CurMipMap = MipMap;
 
246
        iBuild1DMipmapsVertical_(MipMap->Height >> 1);
 
247
        Original->NumMips++;
 
248
 
 
249
        return IL_TRUE;
 
250
}
 
251
 
 
252
 
 
253
ILboolean iBuild2DMipmaps_(ILuint Width, ILuint Height)
 
254
{
 
255
        ILimage *MipMap, *Src;
 
256
        ILuint  x1 = 0, x2 = 0, y1 = 0, y2 = 0, c;
 
257
 
 
258
        if (CurMipMap) {
 
259
                if (CurMipMap->Width == 1 && CurMipMap->Height == 1) {  // Already at the last mipmap
 
260
                        CurMipMap->Next = NULL;  // Terminate the list
 
261
                        return IL_TRUE;
 
262
                }
 
263
 
 
264
                if (/*CurMipMap->*/Height == 1) {
 
265
                        return iBuild1DMipmaps_(Width);
 
266
                }
 
267
 
 
268
                if (/*CurMipMap->*/Width == 1) {
 
269
                        return iBuild1DMipmapsVertical_(Height);
 
270
                }
 
271
        }
 
272
        else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1) {  // 8-9-2001 - Not sure...
 
273
                ilSetError(ILU_ILLEGAL_OPERATION);
 
274
                return IL_FALSE;
 
275
        }
 
276
 
 
277
        if (Height == 0 && Width == 0) {
 
278
                ilSetError(ILU_INTERNAL_ERROR);
 
279
                return IL_FALSE;
 
280
        }
 
281
        // 8-9-2001 - Should these two if statements read == 0 || == 1?
 
282
        if (Height == 0) {
 
283
                return iBuild1DMipmaps_(Width);
 
284
        }
 
285
        if (Width == 0) {
 
286
                return iBuild1DMipmapsVertical_(Height);  // 8-9-2001
 
287
        }
 
288
 
 
289
        MipMap = ilNewImage(Width, Height, 1, iluCurImage->Bpp, iluCurImage->Bpc);
 
290
        if (MipMap == NULL) {
 
291
                if (CurMipMap != NULL)
 
292
                        CurMipMap->Next = NULL;
 
293
                return IL_FALSE;
 
294
        }
 
295
 
 
296
        // Copies attributes
 
297
        MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
 
298
        MipMap->Format = iluCurImage->Format;
 
299
        MipMap->Type = iluCurImage->Type;
 
300
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
301
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
302
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
303
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
304
                if (MipMap->Pal.Palette == NULL) {
 
305
                        ilCloseImage(MipMap);
 
306
                        return IL_FALSE;
 
307
                }
 
308
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
309
        }
 
310
 
 
311
        if (CurMipMap == NULL) {  // First mipmap
 
312
                iluCurImage->Mipmaps = MipMap;
 
313
                Src = iluCurImage;
 
314
        }
 
315
        else {
 
316
                CurMipMap->Next = MipMap;
 
317
                Src = CurMipMap;
 
318
        }
 
319
 
 
320
        if (MipMap->Type == IL_FLOAT) {
 
321
                ILfloat *DestFData = (ILfloat*)MipMap->Data;
 
322
                ILfloat *SrcFData = (ILfloat*)Src->Data;
 
323
                ILuint DestStride = MipMap->Bps / 4;
 
324
                ILuint SrcStride = Src->Bps / 4;
 
325
                for (y1 = 0; y1 < Height; y1++, y2 += 2) {
 
326
                        x1 = 0;  x2 = 0;
 
327
                        for (; x1 < Width; x1++, x2 += 2) {
 
328
                                for (c = 0; c < MipMap->Bpp; c++) {
 
329
                                        DestFData[y1 * DestStride + x1 * MipMap->Bpp + c] = (
 
330
                                                SrcFData[y2 * SrcStride + x2 * MipMap->Bpp + c] +
 
331
                                                SrcFData[y2 * SrcStride + (x2 + 1) * MipMap->Bpp + c] +
 
332
                                                SrcFData[(y2 + 1) * SrcStride + x2 * MipMap->Bpp + c] +
 
333
                                                SrcFData[(y2 + 1) * SrcStride + (x2 + 1) * MipMap->Bpp + c]) * .25f;
 
334
                                }
 
335
                        }
 
336
                }
 
337
        }
 
338
        else {
 
339
                for (y1 = 0; y1 < Height; y1++, y2 += 2) {
 
340
                        x1 = 0;  x2 = 0;
 
341
                        for (; x1 < Width; x1++, x2 += 2) {
 
342
                                for (c = 0; c < MipMap->Bpp; c++) {
 
343
                                        MipMap->Data[y1 * MipMap->Bps + x1 * MipMap->Bpp + c] = (
 
344
                                                Src->Data[y2 * Src->Bps + x2 * MipMap->Bpp + c] +
 
345
                                                Src->Data[y2 * Src->Bps + (x2 + 1) * MipMap->Bpp + c] +
 
346
                                                Src->Data[(y2 + 1) * Src->Bps + x2 * MipMap->Bpp + c] +
 
347
                                                Src->Data[(y2 + 1) * Src->Bps + (x2 + 1) * MipMap->Bpp + c]) >> 2;
 
348
                                }
 
349
                        }
 
350
                }
 
351
        }
 
352
 
 
353
        CurMipMap = MipMap;
 
354
        iBuild2DMipmaps_(MipMap->Width >> 1, MipMap->Height >> 1);
 
355
        Original->NumMips++;
 
356
 
 
357
        return IL_TRUE;
 
358
}
 
359
 
 
360
 
 
361
ILboolean iBuild3DMipmaps_(ILuint Width, ILuint Height, ILuint Depth)
 
362
{
 
363
        ILimage *MipMap, *Src;
 
364
        ILuint  x1 = 0, x2 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
 
365
 
 
366
        if (CurMipMap) {
 
367
                // Already at the last mipmap
 
368
                if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
 
369
                        CurMipMap->Next = NULL;  // Terminate the list
 
370
                        return IL_TRUE;
 
371
                }
 
372
 
 
373
                if (CurMipMap->Depth == 1) {
 
374
                        return iBuild2DMipmaps_(Width, Height);
 
375
                }
 
376
                if (CurMipMap->Height == 1) {
 
377
                        return iBuild3DMipmapsHorizontal_(Width, Depth);
 
378
                }
 
379
 
 
380
                if (CurMipMap->Width == 1) {
 
381
                        return iBuild3DMipmapsVertical_(Height, Depth);
 
382
                }
 
383
        }
 
384
        else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1 && iluCurImage->Height <= 1) {
 
385
                ilSetError(ILU_ILLEGAL_OPERATION);
 
386
                return IL_FALSE;
 
387
        }
 
388
 
 
389
        if (Height == 0 && Width == 0 && Depth == 0) {
 
390
                ilSetError(ILU_INTERNAL_ERROR);
 
391
                return IL_FALSE;
 
392
        }
 
393
        if (Depth == 0) {
 
394
                return iBuild2DMipmaps_(Width, Height);
 
395
        }
 
396
        if (Height == 0) {
 
397
                return iBuild3DMipmapsHorizontal_(Width, Depth);
 
398
        }
 
399
        if (Width == 0) {
 
400
                return iBuild3DMipmapsVertical_(Height, Depth);
 
401
        }
 
402
 
 
403
        MipMap = ilNewImage(Width, Height, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
 
404
        if (MipMap == NULL) {
 
405
                if (CurMipMap != NULL)
 
406
                        CurMipMap->Next = NULL;
 
407
                return IL_FALSE;
 
408
        }
 
409
 
 
410
        // Copies attributes
 
411
        MipMap->Origin = iluCurImage->Origin;  // 8-11-2001
 
412
        MipMap->Format = iluCurImage->Format;
 
413
        MipMap->Type = iluCurImage->Type;
 
414
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
415
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
416
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
417
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
418
                if (MipMap->Pal.Palette == NULL) {
 
419
                        ilCloseImage(MipMap);
 
420
                        return IL_FALSE;
 
421
                }
 
422
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
423
        }
 
424
 
 
425
        if (CurMipMap == NULL) {  // First mipmap
 
426
                iluCurImage->Mipmaps = MipMap;
 
427
                Src = iluCurImage;
 
428
        }
 
429
        else {
 
430
                CurMipMap->Next = MipMap;
 
431
                Src = CurMipMap;
 
432
        }
 
433
 
 
434
        for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
 
435
                z3 = z1 * MipMap->SizeOfPlane;
 
436
                z4 = z2 * Src->SizeOfPlane;
 
437
                z5 = (z2 + 1) * Src->SizeOfPlane;
 
438
 
 
439
                y1 = 0;  y2 = 0;
 
440
                for (; y1 < Height; y1++, y2 += 2) {
 
441
                        x1 = 0;  x2 = 0;
 
442
                        for (; x1 < Width; x1++, x2 += 2) {
 
443
                                for (c = 0; c < MipMap->Bpp; c++) {
 
444
                                        MipMap->Data[z1 * MipMap->SizeOfPlane + y1 * MipMap->Bps + x1 * MipMap->Bpp + c] = (
 
445
                                                Src->Data[z2 * Src->SizeOfPlane + y2 * Src->Bps + x2 * Src->Bpp + c] +
 
446
                                                Src->Data[z2 * Src->SizeOfPlane + y2 * Src->Bps + (x2 + 1) * Src->Bpp + c] +
 
447
                                                Src->Data[z2 * Src->SizeOfPlane + (y2 + 1) * Src->Bps + x2 * Src->Bpp + c] +
 
448
                                                Src->Data[z2 * Src->SizeOfPlane + (y2 + 1) * Src->Bps + (x2 + 1) * Src->Bpp + c] +
 
449
                                                Src->Data[(z2 + 1) * Src->SizeOfPlane + y2 * Src->Bps + x2 * Src->Bpp + c] +
 
450
                                                Src->Data[(z2 + 1) * Src->SizeOfPlane + y2 * Src->Bps + (x2 + 1) * Src->Bpp + c] +
 
451
                                                Src->Data[(z2 + 1) * Src->SizeOfPlane + (y2 + 1) * Src->Bps + x2 * Src->Bpp + c] +
 
452
                                                Src->Data[(z2 + 1) * Src->SizeOfPlane + (y2 + 1) * Src->Bps + (x2 + 1) * Src->Bpp + c]) / 8;
 
453
                                }
 
454
                        }
 
455
                }
 
456
        }
 
457
 
 
458
        CurMipMap = MipMap;
 
459
        iBuild3DMipmaps_(MipMap->Width >> 1, MipMap->Height >> 1, MipMap->Depth >> 1);
 
460
        Original->NumMips++;
 
461
 
 
462
        return IL_TRUE;
 
463
}
 
464
 
 
465
 
 
466
ILboolean iBuild3DMipmapsVertical_(ILuint Height, ILuint Depth)
 
467
{
 
468
        ILimage *MipMap, *Src;
 
469
        ILuint  y1 = 0, y2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
 
470
 
 
471
        if (CurMipMap) {
 
472
                // Already at the last mipmap
 
473
                if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
 
474
                        CurMipMap->Next = NULL;  // Terminate the list
 
475
                        return IL_TRUE;
 
476
                }
 
477
 
 
478
                if (CurMipMap->Depth == 1) {
 
479
                        return iBuild1DMipmapsVertical_(Height);
 
480
                }
 
481
        }
 
482
        else if (iluCurImage->Height <= 1 && iluCurImage->Height <= 1) {
 
483
                ilSetError(ILU_ILLEGAL_OPERATION);
 
484
                return IL_FALSE;
 
485
        }
 
486
 
 
487
        if (Height == 0 && Depth == 0) {
 
488
                ilSetError(ILU_INTERNAL_ERROR);
 
489
                return IL_FALSE;
 
490
        }
 
491
        if (Depth == 0) {
 
492
                return iBuild1DMipmapsVertical_(Height);
 
493
        }
 
494
 
 
495
        MipMap = ilNewImage(1, Height, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
 
496
        if (MipMap == NULL) {
 
497
                if (CurMipMap != NULL)
 
498
                        CurMipMap->Next = NULL;
 
499
                return IL_FALSE;
 
500
        }
 
501
 
 
502
        // Copies attributes
 
503
        MipMap->Format = iluCurImage->Format;
 
504
        MipMap->Type = iluCurImage->Type;
 
505
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
506
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
507
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
508
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
509
                if (MipMap->Pal.Palette == NULL) {
 
510
                        ilCloseImage(MipMap);
 
511
                        return IL_FALSE;
 
512
                }
 
513
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
514
        }
 
515
 
 
516
        if (CurMipMap == NULL) {  // First mipmap
 
517
                iluCurImage->Mipmaps = MipMap;
 
518
                Src = iluCurImage;
 
519
        }
 
520
        else {
 
521
                CurMipMap->Next = MipMap;
 
522
                Src = CurMipMap;
 
523
        }
 
524
 
 
525
        for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
 
526
                z3 = z1 * iluCurImage->SizeOfPlane;
 
527
                z4 = z2 * iluCurImage->SizeOfPlane;
 
528
                z5 = (z2 + 1) * iluCurImage->SizeOfPlane;
 
529
 
 
530
                for (y1 = 0; y1 < Height; y1++, y2 += 2) {
 
531
                        for (c = 0; c < MipMap->Bpp; c++) {
 
532
                                MipMap->Data[z3 + y1 * MipMap->Bps + c] = (
 
533
                                        Src->Data[z4 + y2 * Src->Bps + c] +
 
534
                                        Src->Data[z4 + y2 * Src->Bps + c] +
 
535
                                        Src->Data[z4 + (y2 + 1) * Src->Bps + c] +
 
536
                                        Src->Data[z4 + (y2 + 1) * Src->Bps + c]) >> 2;
 
537
                        }
 
538
                }
 
539
        }
 
540
 
 
541
        CurMipMap = MipMap;
 
542
        iBuild3DMipmapsVertical_(MipMap->Height >> 1, MipMap->Depth >> 1);
 
543
        Original->NumMips++;
 
544
 
 
545
        return IL_TRUE;
 
546
}
 
547
 
 
548
 
 
549
ILboolean iBuild3DMipmapsHorizontal_(ILuint Width, ILuint Depth)
 
550
{
 
551
        ILimage *MipMap, *Src;
 
552
        ILuint  x1 = 0, x2 = 0, z1 = 0, z2 = 0, z3, z4, z5, c;
 
553
 
 
554
        if (CurMipMap) {
 
555
                // Already at the last mipmap
 
556
                if (CurMipMap->Width == 1 && CurMipMap->Height == 1 && CurMipMap->Depth == 1) {
 
557
                        CurMipMap->Next = NULL;  // Terminate the list
 
558
                        return IL_TRUE;
 
559
                }
 
560
 
 
561
                if (CurMipMap->Depth == 1) {
 
562
                        return iBuild1DMipmaps_(Width);
 
563
                }
 
564
        }
 
565
        else if (iluCurImage->Width <= 1 && iluCurImage->Height <= 1) {
 
566
                ilSetError(ILU_ILLEGAL_OPERATION);
 
567
                return IL_FALSE;
 
568
        }
 
569
 
 
570
        if (Width == 0 && Depth == 0) {
 
571
                ilSetError(ILU_INTERNAL_ERROR);
 
572
                return IL_FALSE;
 
573
        }
 
574
        if (Depth == 0) {
 
575
                return iBuild1DMipmaps_(Width);
 
576
        }
 
577
 
 
578
        MipMap = ilNewImage(Width, 1, Depth, iluCurImage->Bpp, iluCurImage->Bpc);
 
579
        if (MipMap == NULL) {
 
580
                if (CurMipMap != NULL)
 
581
                        CurMipMap->Next = NULL;
 
582
                return IL_FALSE;
 
583
        }
 
584
 
 
585
        // Copies attributes
 
586
        MipMap->Format = iluCurImage->Format;
 
587
        MipMap->Type = iluCurImage->Type;
 
588
        MipMap->Pal.PalSize = iluCurImage->Pal.PalSize;
 
589
        MipMap->Pal.PalType = iluCurImage->Pal.PalType;
 
590
        if (iluCurImage->Pal.Palette && MipMap->Pal.PalSize > 0 && MipMap->Pal.PalType != IL_PAL_NONE) {
 
591
                MipMap->Pal.Palette = (ILubyte*)ialloc(iluCurImage->Pal.PalSize);
 
592
                if (MipMap->Pal.Palette == NULL) {
 
593
                        ilCloseImage(MipMap);
 
594
                        return IL_FALSE;
 
595
                }
 
596
                memcpy(MipMap->Pal.Palette, iluCurImage->Pal.Palette, MipMap->Pal.PalSize);
 
597
        }
 
598
 
 
599
        if (CurMipMap == NULL) {  // First mipmap
 
600
                iluCurImage->Mipmaps = MipMap;
 
601
                Src = iluCurImage;
 
602
        }
 
603
        else {
 
604
                CurMipMap->Next = MipMap;
 
605
                Src = CurMipMap;
 
606
        }
 
607
 
 
608
        for (z1 = 0; z1 < Depth; z1++, z2 += 2) {
 
609
                z3 = z1 * iluCurImage->SizeOfPlane;
 
610
                z4 = z2 * iluCurImage->SizeOfPlane;
 
611
                z5 = (z2 + 1) * iluCurImage->SizeOfPlane;
 
612
 
 
613
                x1 = 0;  x2 = 0;
 
614
                for (; x1 < Width; x1++, x2 += 2) {
 
615
                        for (c = 0; c < MipMap->Bpp; c++) {
 
616
                                MipMap->Data[z3 + x1 * MipMap->Bpp + c] = (
 
617
                                        Src->Data[z4 + x2 * MipMap->Bpp + c] +
 
618
                                        Src->Data[z4 + (x2 + 1) * MipMap->Bpp + c] +
 
619
                                        Src->Data[z4 + x2 * MipMap->Bpp + c] +
 
620
                                        Src->Data[z4 + (x2 + 1) * MipMap->Bpp + c]) >> 2;
 
621
                        }
 
622
                }
 
623
        }
 
624
 
 
625
        CurMipMap = MipMap;
 
626
        iBuild3DMipmapsHorizontal_(MipMap->Width >> 1, MipMap->Depth >> 1);
 
627
        Original->NumMips++;
 
628
 
 
629
        return IL_TRUE;
 
630
}