Tizen 2.1 base
[sdk/emulator/qemu.git] / target-i386 / mesa_mipmap.c
1
2 /*
3  * Mesa 3-D graphics library
4  * Version:  3.4
5  * Copyright (C) 1995-2000  Brian Paul
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the Free
19  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22
23 #ifdef PC_HEADER
24 #include "all.h"
25 #else
26 #include <assert.h>
27 #include <math.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 //#include "gluP.h"
31 #endif
32
33
34 /*
35  * Compute ceiling of integer quotient of A divided by B:
36  */
37 #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
38
39
40
41 #ifdef EPSILON
42 #undef EPSILON
43 #endif
44 #define EPSILON 0.001
45
46
47 /* To work around optimizer bug in MSVC4.1 */
48 #if defined(__WIN32__) && !defined(OPENSTEP)
49 void dummy(GLuint j, GLuint k);
50 void dummy(GLuint j, GLuint k)
51 {
52 }
53 #else
54 #define dummy(J, K)
55 #endif
56
57
58 static GLint GLAPIENTRY
59 mesa_gluScaleImage(GLenum format,
60               GLsizei widthin, GLsizei heightin,
61               GLenum typein, const void *datain,
62               GLsizei widthout, GLsizei heightout,
63               GLenum typeout, void *dataout)
64 {
65    GLint components, i, j, k;
66    GLfloat *tempin, *tempout;
67    GLfloat sx, sy;
68    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
69    GLint packrowlength, packalignment, packskiprows, packskippixels;
70    GLint sizein, sizeout;
71    GLint rowstride, rowlen;
72
73
74    /* Determine number of components per pixel */
75    switch (format) {
76    case GL_COLOR_INDEX:
77    case GL_STENCIL_INDEX:
78    case GL_DEPTH_COMPONENT:
79    case GL_RED:
80    case GL_GREEN:
81    case GL_BLUE:
82    case GL_ALPHA:
83    case GL_LUMINANCE:
84       components = 1;
85       break;
86    case GL_LUMINANCE_ALPHA:
87       components = 2;
88       break;
89    case GL_RGB:
90    case GL_BGR:
91       components = 3;
92       break;
93    case GL_RGBA:
94    case GL_BGRA:
95 #ifdef GL_EXT_abgr
96    case GL_ABGR_EXT:
97 #endif
98       components = 4;
99       break;
100    default:
101       return GLU_INVALID_ENUM;
102    }
103
104    /* Determine bytes per input datum */
105    switch (typein) {
106    case GL_UNSIGNED_BYTE:
107       sizein = sizeof(GLubyte);
108       break;
109    case GL_BYTE:
110       sizein = sizeof(GLbyte);
111       break;
112    case GL_UNSIGNED_SHORT:
113       sizein = sizeof(GLushort);
114       break;
115    case GL_SHORT:
116       sizein = sizeof(GLshort);
117       break;
118    case GL_UNSIGNED_INT:
119       sizein = sizeof(GLuint);
120       break;
121    case GL_INT:
122       sizein = sizeof(GLint);
123       break;
124    case GL_FLOAT:
125       sizein = sizeof(GLfloat);
126       break;
127    case GL_BITMAP:
128       /* not implemented yet */
129    default:
130       return GL_INVALID_ENUM;
131    }
132
133    /* Determine bytes per output datum */
134    switch (typeout) {
135    case GL_UNSIGNED_BYTE:
136       sizeout = sizeof(GLubyte);
137       break;
138    case GL_BYTE:
139       sizeout = sizeof(GLbyte);
140       break;
141    case GL_UNSIGNED_SHORT:
142       sizeout = sizeof(GLushort);
143       break;
144    case GL_SHORT:
145       sizeout = sizeof(GLshort);
146       break;
147    case GL_UNSIGNED_INT:
148       sizeout = sizeof(GLuint);
149       break;
150    case GL_INT:
151       sizeout = sizeof(GLint);
152       break;
153    case GL_FLOAT:
154       sizeout = sizeof(GLfloat);
155       break;
156    case GL_BITMAP:
157       /* not implemented yet */
158    default:
159       return GL_INVALID_ENUM;
160    }
161
162    /* Get glPixelStore state */
163    glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
164    glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
165    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
166    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
167    glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
168    glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
169    glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
170    glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
171
172    /* Allocate storage for intermediate images */
173    tempin = (GLfloat *) malloc(widthin * heightin
174                                * components * sizeof(GLfloat));
175    if (!tempin) {
176       return GLU_OUT_OF_MEMORY;
177    }
178    tempout = (GLfloat *) malloc(widthout * heightout
179                                 * components * sizeof(GLfloat));
180    if (!tempout) {
181       free(tempin);
182       return GLU_OUT_OF_MEMORY;
183    }
184
185
186    /*
187     * Unpack the pixel data and convert to floating point
188     */
189
190    if (unpackrowlength > 0) {
191       rowlen = unpackrowlength;
192    }
193    else {
194       rowlen = widthin;
195    }
196    if (sizein >= unpackalignment) {
197       rowstride = components * rowlen;
198    }
199    else {
200       rowstride = unpackalignment / sizein
201          * CEILING(components * rowlen * sizein, unpackalignment);
202    }
203
204    switch (typein) {
205    case GL_UNSIGNED_BYTE:
206       k = 0;
207       for (i = 0; i < heightin; i++) {
208          GLubyte *ubptr = (GLubyte *) datain
209             + i * rowstride
210             + unpackskiprows * rowstride + unpackskippixels * components;
211          for (j = 0; j < widthin * components; j++) {
212             dummy(j, k);
213             tempin[k++] = (GLfloat) * ubptr++;
214          }
215       }
216       break;
217    case GL_BYTE:
218       k = 0;
219       for (i = 0; i < heightin; i++) {
220          GLbyte *bptr = (GLbyte *) datain
221             + i * rowstride
222             + unpackskiprows * rowstride + unpackskippixels * components;
223          for (j = 0; j < widthin * components; j++) {
224             dummy(j, k);
225             tempin[k++] = (GLfloat) * bptr++;
226          }
227       }
228       break;
229    case GL_UNSIGNED_SHORT:
230       k = 0;
231       for (i = 0; i < heightin; i++) {
232          GLushort *usptr = (GLushort *) datain
233             + i * rowstride
234             + unpackskiprows * rowstride + unpackskippixels * components;
235          for (j = 0; j < widthin * components; j++) {
236             dummy(j, k);
237             tempin[k++] = (GLfloat) * usptr++;
238          }
239       }
240       break;
241    case GL_SHORT:
242       k = 0;
243       for (i = 0; i < heightin; i++) {
244          GLshort *sptr = (GLshort *) datain
245             + i * rowstride
246             + unpackskiprows * rowstride + unpackskippixels * components;
247          for (j = 0; j < widthin * components; j++) {
248             dummy(j, k);
249             tempin[k++] = (GLfloat) * sptr++;
250          }
251       }
252       break;
253    case GL_UNSIGNED_INT:
254       k = 0;
255       for (i = 0; i < heightin; i++) {
256          GLuint *uiptr = (GLuint *) datain
257             + i * rowstride
258             + unpackskiprows * rowstride + unpackskippixels * components;
259          for (j = 0; j < widthin * components; j++) {
260             dummy(j, k);
261             tempin[k++] = (GLfloat) * uiptr++;
262          }
263       }
264       break;
265    case GL_INT:
266       k = 0;
267       for (i = 0; i < heightin; i++) {
268          GLint *iptr = (GLint *) datain
269             + i * rowstride
270             + unpackskiprows * rowstride + unpackskippixels * components;
271          for (j = 0; j < widthin * components; j++) {
272             dummy(j, k);
273             tempin[k++] = (GLfloat) * iptr++;
274          }
275       }
276       break;
277    case GL_FLOAT:
278       k = 0;
279       for (i = 0; i < heightin; i++) {
280          GLfloat *fptr = (GLfloat *) datain
281             + i * rowstride
282             + unpackskiprows * rowstride + unpackskippixels * components;
283          for (j = 0; j < widthin * components; j++) {
284             dummy(j, k);
285             tempin[k++] = *fptr++;
286          }
287       }
288       break;
289    default:
290       return GLU_INVALID_ENUM;
291    }
292
293
294    /*
295     * Scale the image!
296     */
297
298    if (widthout > 1)
299       sx = (GLfloat) (widthin - 1) / (GLfloat) (widthout - 1);
300    else
301       sx = (GLfloat) (widthin - 1);
302    if (heightout > 1)
303       sy = (GLfloat) (heightin - 1) / (GLfloat) (heightout - 1);
304    else
305       sy = (GLfloat) (heightin - 1);
306
307 /*#define POINT_SAMPLE*/
308 #ifdef POINT_SAMPLE
309    for (i = 0; i < heightout; i++) {
310       GLint ii = i * sy;
311       for (j = 0; j < widthout; j++) {
312          GLint jj = j * sx;
313
314          GLfloat *src = tempin + (ii * widthin + jj) * components;
315          GLfloat *dst = tempout + (i * widthout + j) * components;
316
317          for (k = 0; k < components; k++) {
318             *dst++ = *src++;
319          }
320       }
321    }
322 #else
323    if (sx < 1.0 && sy < 1.0) {
324       /* magnify both width and height:  use weighted sample of 4 pixels */
325       GLint i0, i1, j0, j1;
326       GLfloat alpha, beta;
327       GLfloat *src00, *src01, *src10, *src11;
328       GLfloat s1, s2;
329       GLfloat *dst;
330
331       for (i = 0; i < heightout; i++) {
332          i0 = i * sy;
333          i1 = i0 + 1;
334          if (i1 >= heightin)
335             i1 = heightin - 1;
336 /*       i1 = (i+1) * sy - EPSILON;*/
337          alpha = i * sy - i0;
338          for (j = 0; j < widthout; j++) {
339             j0 = j * sx;
340             j1 = j0 + 1;
341             if (j1 >= widthin)
342                j1 = widthin - 1;
343 /*          j1 = (j+1) * sx - EPSILON; */
344             beta = j * sx - j0;
345
346             /* compute weighted average of pixels in rect (i0,j0)-(i1,j1) */
347             src00 = tempin + (i0 * widthin + j0) * components;
348             src01 = tempin + (i0 * widthin + j1) * components;
349             src10 = tempin + (i1 * widthin + j0) * components;
350             src11 = tempin + (i1 * widthin + j1) * components;
351
352             dst = tempout + (i * widthout + j) * components;
353
354             for (k = 0; k < components; k++) {
355                s1 = *src00++ * (1.0 - beta) + *src01++ * beta;
356                s2 = *src10++ * (1.0 - beta) + *src11++ * beta;
357                *dst++ = s1 * (1.0 - alpha) + s2 * alpha;
358             }
359          }
360       }
361    }
362    else {
363       /* shrink width and/or height:  use an unweighted box filter */
364       GLint i0, i1;
365       GLint j0, j1;
366       GLint ii, jj;
367       GLfloat sum, *dst;
368
369       for (i = 0; i < heightout; i++) {
370          i0 = i * sy;
371          i1 = i0 + 1;
372          if (i1 >= heightin)
373             i1 = heightin - 1;
374 /*       i1 = (i+1) * sy - EPSILON; */
375          for (j = 0; j < widthout; j++) {
376             j0 = j * sx;
377             j1 = j0 + 1;
378             if (j1 >= widthin)
379                j1 = widthin - 1;
380 /*          j1 = (j+1) * sx - EPSILON; */
381
382             dst = tempout + (i * widthout + j) * components;
383
384             /* compute average of pixels in the rectangle (i0,j0)-(i1,j1) */
385             for (k = 0; k < components; k++) {
386                sum = 0.0;
387                for (ii = i0; ii <= i1; ii++) {
388                   for (jj = j0; jj <= j1; jj++) {
389                      sum += *(tempin + (ii * widthin + jj) * components + k);
390                   }
391                }
392                sum /= (j1 - j0 + 1) * (i1 - i0 + 1);
393                *dst++ = sum;
394             }
395          }
396       }
397    }
398 #endif
399
400
401    /*
402     * Return output image
403     */
404
405    if (packrowlength > 0) {
406       rowlen = packrowlength;
407    }
408    else {
409       rowlen = widthout;
410    }
411    if (sizeout >= packalignment) {
412       rowstride = components * rowlen;
413    }
414    else {
415       rowstride = packalignment / sizeout
416          * CEILING(components * rowlen * sizeout, packalignment);
417    }
418
419    switch (typeout) {
420    case GL_UNSIGNED_BYTE:
421       k = 0;
422       for (i = 0; i < heightout; i++) {
423          GLubyte *ubptr = (GLubyte *) dataout
424             + i * rowstride
425             + packskiprows * rowstride + packskippixels * components;
426          for (j = 0; j < widthout * components; j++) {
427             dummy(j, k + i);
428             *ubptr++ = (GLubyte) tempout[k++];
429          }
430       }
431       break;
432    case GL_BYTE:
433       k = 0;
434       for (i = 0; i < heightout; i++) {
435          GLbyte *bptr = (GLbyte *) dataout
436             + i * rowstride
437             + packskiprows * rowstride + packskippixels * components;
438          for (j = 0; j < widthout * components; j++) {
439             dummy(j, k + i);
440             *bptr++ = (GLbyte) tempout[k++];
441          }
442       }
443       break;
444    case GL_UNSIGNED_SHORT:
445       k = 0;
446       for (i = 0; i < heightout; i++) {
447          GLushort *usptr = (GLushort *) dataout
448             + i * rowstride
449             + packskiprows * rowstride + packskippixels * components;
450          for (j = 0; j < widthout * components; j++) {
451             dummy(j, k + i);
452             *usptr++ = (GLushort) tempout[k++];
453          }
454       }
455       break;
456    case GL_SHORT:
457       k = 0;
458       for (i = 0; i < heightout; i++) {
459          GLshort *sptr = (GLshort *) dataout
460             + i * rowstride
461             + packskiprows * rowstride + packskippixels * components;
462          for (j = 0; j < widthout * components; j++) {
463             dummy(j, k + i);
464             *sptr++ = (GLshort) tempout[k++];
465          }
466       }
467       break;
468    case GL_UNSIGNED_INT:
469       k = 0;
470       for (i = 0; i < heightout; i++) {
471          GLuint *uiptr = (GLuint *) dataout
472             + i * rowstride
473             + packskiprows * rowstride + packskippixels * components;
474          for (j = 0; j < widthout * components; j++) {
475             dummy(j, k + i);
476             *uiptr++ = (GLuint) tempout[k++];
477          }
478       }
479       break;
480    case GL_INT:
481       k = 0;
482       for (i = 0; i < heightout; i++) {
483          GLint *iptr = (GLint *) dataout
484             + i * rowstride
485             + packskiprows * rowstride + packskippixels * components;
486          for (j = 0; j < widthout * components; j++) {
487             dummy(j, k + i);
488             *iptr++ = (GLint) tempout[k++];
489          }
490       }
491       break;
492    case GL_FLOAT:
493       k = 0;
494       for (i = 0; i < heightout; i++) {
495          GLfloat *fptr = (GLfloat *) dataout
496             + i * rowstride
497             + packskiprows * rowstride + packskippixels * components;
498          for (j = 0; j < widthout * components; j++) {
499             dummy(j, k + i);
500             *fptr++ = tempout[k++];
501          }
502       }
503       break;
504    default:
505       return GLU_INVALID_ENUM;
506    }
507
508
509    /* free temporary image storage */
510    free(tempin);
511    free(tempout);
512
513    return 0;
514 }
515
516
517
518 #if 0
519 /*
520  * Return the largest k such that 2^k <= n.
521  */
522 static GLint
523 ilog2(GLint n)
524 {
525    GLint k;
526
527    if (n <= 0)
528       return 0;
529    for (k = 0; n >>= 1; k++);
530    return k;
531 }
532 #endif
533
534
535
536 /*
537  * Find the value nearest to n which is also a power of two.
538  */
539 static GLint
540 round2(GLint n)
541 {
542    GLint m;
543
544    for (m = 1; m < n; m *= 2);
545
546    /* m>=n */
547    if (m - n <= n - m / 2) {
548       return m;
549    }
550    else {
551       return m / 2;
552    }
553 }
554
555
556 /*
557  * Given an pixel format and datatype, return the number of bytes to
558  * store one pixel.
559  */
560 static GLint
561 bytes_per_pixel(GLenum format, GLenum type)
562 {
563    GLint n, m;
564
565    switch (format) {
566    case GL_COLOR_INDEX:
567    case GL_STENCIL_INDEX:
568    case GL_DEPTH_COMPONENT:
569    case GL_RED:
570    case GL_GREEN:
571    case GL_BLUE:
572    case GL_ALPHA:
573    case GL_LUMINANCE:
574       n = 1;
575       break;
576    case GL_LUMINANCE_ALPHA:
577       n = 2;
578       break;
579    case GL_RGB:
580    case GL_BGR:
581       n = 3;
582       break;
583    case GL_RGBA:
584    case GL_BGRA:
585 #ifdef GL_EXT_abgr
586    case GL_ABGR_EXT:
587 #endif
588       n = 4;
589       break;
590    default:
591       n = 0;
592    }
593
594    switch (type) {
595    case GL_UNSIGNED_BYTE:
596       m = sizeof(GLubyte);
597       break;
598    case GL_BYTE:
599       m = sizeof(GLbyte);
600       break;
601    case GL_BITMAP:
602       m = 1;
603       break;
604    case GL_UNSIGNED_SHORT:
605       m = sizeof(GLushort);
606       break;
607    case GL_SHORT:
608       m = sizeof(GLshort);
609       break;
610    case GL_UNSIGNED_INT:
611       m = sizeof(GLuint);
612       break;
613    case GL_INT:
614       m = sizeof(GLint);
615       break;
616    case GL_FLOAT:
617       m = sizeof(GLfloat);
618       break;
619    default:
620       m = 0;
621    }
622
623    return n * m;
624 }
625
626
627
628 #if 0
629 /*
630  * WARNING: This function isn't finished and has never been tested!!!!
631  */
632 GLint GLAPIENTRY
633 mesa_gluBuild1DMipmaps(GLenum target, GLint components,
634                   GLsizei width, GLenum format, GLenum type, const void *data)
635 {
636    GLubyte *texture;
637    GLint levels, max_levels;
638    GLint new_width, max_width;
639    GLint i, j, k, l;
640
641    if (width < 1)
642       return GLU_INVALID_VALUE;
643
644    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_width);
645    max_levels = ilog2(max_width) + 1;
646
647    /* Compute how many mipmap images to make */
648    levels = ilog2(width) + 1;
649    if (levels > max_levels) {
650       levels = max_levels;
651    }
652
653    new_width = 1 << (levels - 1);
654
655    texture = (GLubyte *) malloc(new_width * components);
656    if (!texture) {
657       return GLU_OUT_OF_MEMORY;
658    }
659
660    if (width != new_width) {
661       /* initial rescaling */
662       switch (type) {
663       case GL_UNSIGNED_BYTE:
664          {
665             GLubyte *ub_data = (GLubyte *) data;
666             for (i = 0; i < new_width; i++) {
667                j = i * width / new_width;
668                for (k = 0; k < components; k++) {
669                   texture[i * components + k] = ub_data[j * components + k];
670                }
671             }
672          }
673          break;
674       default:
675          /* Not implemented */
676          return GLU_ERROR;
677       }
678    }
679
680    /* generate and load mipmap images */
681    for (l = 0; l < levels; l++) {
682       glTexImage1D(GL_TEXTURE_1D, l, components, new_width, 0,
683                    format, GL_UNSIGNED_BYTE, texture);
684
685       /* Scale image down to 1/2 size */
686       new_width = new_width / 2;
687       for (i = 0; i < new_width; i++) {
688          for (k = 0; k < components; k++) {
689             GLint sample1, sample2;
690             sample1 = (GLint) texture[i * 2 * components + k];
691             sample2 = (GLint) texture[(i * 2 + 1) * components + k];
692             texture[i * components + k] = (GLubyte) ((sample1 + sample2) / 2);
693          }
694       }
695    }
696
697    free(texture);
698
699    return 0;
700 }
701 #endif
702
703
704
705 static GLint GLAPIENTRY
706 mesa_gluBuild2DMipmaps(GLenum target, GLint components,
707                   GLsizei width, GLsizei height, GLenum format,
708                   GLenum type, const void *data)
709 {
710    GLint w, h, maxsize;
711    void *image, *newimage;
712    GLint neww, newh, level, bpp;
713    int error;
714    GLboolean done;
715    GLint retval = 0;
716    GLint unpackrowlength, unpackalignment, unpackskiprows, unpackskippixels;
717    GLint packrowlength, packalignment, packskiprows, packskippixels;
718
719    if (width < 1 || height < 1)
720       return GLU_INVALID_VALUE;
721
722    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
723
724    w = round2(width);
725    if (w > maxsize) {
726       w = maxsize;
727    }
728    h = round2(height);
729    if (h > maxsize) {
730       h = maxsize;
731    }
732
733    bpp = bytes_per_pixel(format, type);
734    if (bpp == 0) {
735       /* probably a bad format or type enum */
736       return GLU_INVALID_ENUM;
737    }
738
739    /* Get current glPixelStore values */
740    glGetIntegerv(GL_UNPACK_ROW_LENGTH, &unpackrowlength);
741    glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpackalignment);
742    glGetIntegerv(GL_UNPACK_SKIP_ROWS, &unpackskiprows);
743    glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &unpackskippixels);
744    glGetIntegerv(GL_PACK_ROW_LENGTH, &packrowlength);
745    glGetIntegerv(GL_PACK_ALIGNMENT, &packalignment);
746    glGetIntegerv(GL_PACK_SKIP_ROWS, &packskiprows);
747    glGetIntegerv(GL_PACK_SKIP_PIXELS, &packskippixels);
748
749    /* set pixel packing */
750    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
751    glPixelStorei(GL_PACK_ALIGNMENT, 1);
752    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
753    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
754
755    done = GL_FALSE;
756
757    if (w != width || h != height) {
758       /* must rescale image to get "top" mipmap texture image */
759       image = malloc((w + 4) * h * bpp);
760       if (!image) {
761          return GLU_OUT_OF_MEMORY;
762       }
763       error = mesa_gluScaleImage(format, width, height, type, data,
764                             w, h, type, image);
765       if (error) {
766          retval = error;
767          done = GL_TRUE;
768       }
769    }
770    else {
771       image = (void *) data;
772    }
773
774    level = 0;
775    while (!done) {
776       if (image != data) {
777          /* set pixel unpacking */
778          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
779          glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
780          glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
781          glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
782       }
783
784       glTexImage2D(target, level, components, w, h, 0, format, type, image);
785
786       if (w == 1 && h == 1)
787          break;
788
789       neww = (w < 2) ? 1 : w / 2;
790       newh = (h < 2) ? 1 : h / 2;
791       newimage = malloc((neww + 4) * newh * bpp);
792       if (!newimage) {
793          return GLU_OUT_OF_MEMORY;
794       }
795
796       error = mesa_gluScaleImage(format, w, h, type, image,
797                             neww, newh, type, newimage);
798       if (error) {
799          retval = error;
800          done = GL_TRUE;
801       }
802
803       if (image != data) {
804          free(image);
805       }
806       image = newimage;
807
808       w = neww;
809       h = newh;
810       level++;
811    }
812
813    if (image != data) {
814       free(image);
815    }
816
817    /* Restore original glPixelStore state */
818    glPixelStorei(GL_UNPACK_ROW_LENGTH, unpackrowlength);
819    glPixelStorei(GL_UNPACK_ALIGNMENT, unpackalignment);
820    glPixelStorei(GL_UNPACK_SKIP_ROWS, unpackskiprows);
821    glPixelStorei(GL_UNPACK_SKIP_PIXELS, unpackskippixels);
822    glPixelStorei(GL_PACK_ROW_LENGTH, packrowlength);
823    glPixelStorei(GL_PACK_ALIGNMENT, packalignment);
824    glPixelStorei(GL_PACK_SKIP_ROWS, packskiprows);
825    glPixelStorei(GL_PACK_SKIP_PIXELS, packskippixels);
826
827    return retval;
828 }