Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /* |
2 | * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) |
||
3 | * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved. |
||
4 | * |
||
5 | * Permission is hereby granted, free of charge, to any person obtaining a |
||
6 | * copy of this software and associated documentation files (the "Software"), |
||
7 | * to deal in the Software without restriction, including without limitation |
||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
||
9 | * and/or sell copies of the Software, and to permit persons to whom the |
||
10 | * Software is furnished to do so, subject to the following conditions: |
||
11 | * |
||
12 | * The above copyright notice including the dates of first publication and |
||
13 | * either this permission notice or a reference to |
||
14 | * http://oss.sgi.com/projects/FreeB/ |
||
15 | * shall be included in all copies or substantial portions of the Software. |
||
16 | * |
||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
||
18 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
||
20 | * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
||
21 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
||
22 | * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||
23 | * SOFTWARE. |
||
24 | * |
||
25 | * Except as contained in this notice, the name of Silicon Graphics, Inc. |
||
26 | * shall not be used in advertising or otherwise to promote the sale, use or |
||
27 | * other dealings in this Software without prior written authorization from |
||
28 | * Silicon Graphics, Inc. |
||
29 | */ |
||
30 | |||
31 | #include "gluos.h" |
||
32 | #include |
||
33 | #include |
||
34 | #include |
||
35 | #include |
||
36 | #include |
||
37 | #include |
||
38 | #include |
||
39 | |||
40 | typedef union { |
||
41 | unsigned char ub[4]; |
||
42 | unsigned short us[2]; |
||
43 | unsigned int ui; |
||
44 | char b[4]; |
||
45 | short s[2]; |
||
46 | int i; |
||
47 | float f; |
||
48 | } Type_Widget; |
||
49 | |||
50 | /* Pixel storage modes */ |
||
51 | typedef struct { |
||
52 | GLint pack_alignment; |
||
53 | GLint pack_row_length; |
||
54 | GLint pack_skip_rows; |
||
55 | GLint pack_skip_pixels; |
||
56 | GLint pack_lsb_first; |
||
57 | GLint pack_swap_bytes; |
||
58 | GLint pack_skip_images; |
||
59 | GLint pack_image_height; |
||
60 | |||
61 | GLint unpack_alignment; |
||
62 | GLint unpack_row_length; |
||
63 | GLint unpack_skip_rows; |
||
64 | GLint unpack_skip_pixels; |
||
65 | GLint unpack_lsb_first; |
||
66 | GLint unpack_swap_bytes; |
||
67 | GLint unpack_skip_images; |
||
68 | GLint unpack_image_height; |
||
69 | } PixelStorageModes; |
||
70 | |||
71 | static int gluBuild1DMipmapLevelsCore(GLenum, GLint, |
||
72 | GLsizei, |
||
73 | GLsizei, |
||
74 | GLenum, GLenum, GLint, GLint, GLint, |
||
75 | const void *); |
||
76 | static int gluBuild2DMipmapLevelsCore(GLenum, GLint, |
||
77 | GLsizei, GLsizei, |
||
78 | GLsizei, GLsizei, |
||
79 | GLenum, GLenum, GLint, GLint, GLint, |
||
80 | const void *); |
||
81 | static int gluBuild3DMipmapLevelsCore(GLenum, GLint, |
||
82 | GLsizei, GLsizei, GLsizei, |
||
83 | GLsizei, GLsizei, GLsizei, |
||
84 | GLenum, GLenum, GLint, GLint, GLint, |
||
85 | const void *); |
||
86 | |||
87 | /* |
||
88 | * internal function declarations |
||
89 | */ |
||
90 | static GLfloat bytes_per_element(GLenum type); |
||
91 | static GLint elements_per_group(GLenum format, GLenum type); |
||
92 | static GLint is_index(GLenum format); |
||
93 | static GLint image_size(GLint width, GLint height, GLenum format, GLenum type); |
||
94 | static void fill_image(const PixelStorageModes *, |
||
95 | GLint width, GLint height, GLenum format, |
||
96 | GLenum type, GLboolean index_format, |
||
97 | const void *userdata, GLushort *newimage); |
||
98 | static void empty_image(const PixelStorageModes *, |
||
99 | GLint width, GLint height, GLenum format, |
||
100 | GLenum type, GLboolean index_format, |
||
101 | const GLushort *oldimage, void *userdata); |
||
102 | static void scale_internal(GLint components, GLint widthin, GLint heightin, |
||
103 | const GLushort *datain, |
||
104 | GLint widthout, GLint heightout, |
||
105 | GLushort *dataout); |
||
106 | |||
107 | static void scale_internal_ubyte(GLint components, GLint widthin, |
||
108 | GLint heightin, const GLubyte *datain, |
||
109 | GLint widthout, GLint heightout, |
||
110 | GLubyte *dataout, GLint element_size, |
||
111 | GLint ysize, GLint group_size); |
||
112 | static void scale_internal_byte(GLint components, GLint widthin, |
||
113 | GLint heightin, const GLbyte *datain, |
||
114 | GLint widthout, GLint heightout, |
||
115 | GLbyte *dataout, GLint element_size, |
||
116 | GLint ysize, GLint group_size); |
||
117 | static void scale_internal_ushort(GLint components, GLint widthin, |
||
118 | GLint heightin, const GLushort *datain, |
||
119 | GLint widthout, GLint heightout, |
||
120 | GLushort *dataout, GLint element_size, |
||
121 | GLint ysize, GLint group_size, |
||
122 | GLint myswap_bytes); |
||
123 | static void scale_internal_short(GLint components, GLint widthin, |
||
124 | GLint heightin, const GLshort *datain, |
||
125 | GLint widthout, GLint heightout, |
||
126 | GLshort *dataout, GLint element_size, |
||
127 | GLint ysize, GLint group_size, |
||
128 | GLint myswap_bytes); |
||
129 | static void scale_internal_uint(GLint components, GLint widthin, |
||
130 | GLint heightin, const GLuint *datain, |
||
131 | GLint widthout, GLint heightout, |
||
132 | GLuint *dataout, GLint element_size, |
||
133 | GLint ysize, GLint group_size, |
||
134 | GLint myswap_bytes); |
||
135 | static void scale_internal_int(GLint components, GLint widthin, |
||
136 | GLint heightin, const GLint *datain, |
||
137 | GLint widthout, GLint heightout, |
||
138 | GLint *dataout, GLint element_size, |
||
139 | GLint ysize, GLint group_size, |
||
140 | GLint myswap_bytes); |
||
141 | static void scale_internal_float(GLint components, GLint widthin, |
||
142 | GLint heightin, const GLfloat *datain, |
||
143 | GLint widthout, GLint heightout, |
||
144 | GLfloat *dataout, GLint element_size, |
||
145 | GLint ysize, GLint group_size, |
||
146 | GLint myswap_bytes); |
||
147 | |||
148 | static int checkMipmapArgs(GLenum, GLenum, GLenum); |
||
149 | static GLboolean legalFormat(GLenum); |
||
150 | static GLboolean legalType(GLenum); |
||
151 | static GLboolean isTypePackedPixel(GLenum); |
||
152 | static GLboolean isLegalFormatForPackedPixelType(GLenum, GLenum); |
||
153 | static GLboolean isLegalLevels(GLint, GLint, GLint, GLint); |
||
154 | static void closestFit(GLenum, GLint, GLint, GLint, GLenum, GLenum, |
||
155 | GLint *, GLint *); |
||
156 | |||
157 | /* all extract/shove routines must return double to handle unsigned ints */ |
||
158 | static GLdouble extractUbyte(int, const void *); |
||
159 | static void shoveUbyte(GLdouble, int, void *); |
||
160 | static GLdouble extractSbyte(int, const void *); |
||
161 | static void shoveSbyte(GLdouble, int, void *); |
||
162 | static GLdouble extractUshort(int, const void *); |
||
163 | static void shoveUshort(GLdouble, int, void *); |
||
164 | static GLdouble extractSshort(int, const void *); |
||
165 | static void shoveSshort(GLdouble, int, void *); |
||
166 | static GLdouble extractUint(int, const void *); |
||
167 | static void shoveUint(GLdouble, int, void *); |
||
168 | static GLdouble extractSint(int, const void *); |
||
169 | static void shoveSint(GLdouble, int, void *); |
||
170 | static GLdouble extractFloat(int, const void *); |
||
171 | static void shoveFloat(GLdouble, int, void *); |
||
172 | static void halveImageSlice(int, GLdouble (*)(int, const void *), |
||
173 | void (*)(GLdouble, int, void *), |
||
174 | GLint, GLint, GLint, |
||
175 | const void *, void *, |
||
176 | GLint, GLint, GLint, GLint, GLint); |
||
177 | static void halveImage3D(int, GLdouble (*)(int, const void *), |
||
178 | void (*)(GLdouble, int, void *), |
||
179 | GLint, GLint, GLint, |
||
180 | const void *, void *, |
||
181 | GLint, GLint, GLint, GLint, GLint); |
||
182 | |||
183 | /* packedpixel type scale routines */ |
||
184 | static void extract332(int,const void *, GLfloat []); |
||
185 | static void shove332(const GLfloat [],int ,void *); |
||
186 | static void extract233rev(int,const void *, GLfloat []); |
||
187 | static void shove233rev(const GLfloat [],int ,void *); |
||
188 | static void extract565(int,const void *, GLfloat []); |
||
189 | static void shove565(const GLfloat [],int ,void *); |
||
190 | static void extract565rev(int,const void *, GLfloat []); |
||
191 | static void shove565rev(const GLfloat [],int ,void *); |
||
192 | static void extract4444(int,const void *, GLfloat []); |
||
193 | static void shove4444(const GLfloat [],int ,void *); |
||
194 | static void extract4444rev(int,const void *, GLfloat []); |
||
195 | static void shove4444rev(const GLfloat [],int ,void *); |
||
196 | static void extract5551(int,const void *, GLfloat []); |
||
197 | static void shove5551(const GLfloat [],int ,void *); |
||
198 | static void extract1555rev(int,const void *, GLfloat []); |
||
199 | static void shove1555rev(const GLfloat [],int ,void *); |
||
200 | static void extract8888(int,const void *, GLfloat []); |
||
201 | static void shove8888(const GLfloat [],int ,void *); |
||
202 | static void extract8888rev(int,const void *, GLfloat []); |
||
203 | static void shove8888rev(const GLfloat [],int ,void *); |
||
204 | static void extract1010102(int,const void *, GLfloat []); |
||
205 | static void shove1010102(const GLfloat [],int ,void *); |
||
206 | static void extract2101010rev(int,const void *, GLfloat []); |
||
207 | static void shove2101010rev(const GLfloat [],int ,void *); |
||
208 | static void scaleInternalPackedPixel(int, |
||
209 | void (*)(int, const void *,GLfloat []), |
||
210 | void (*)(const GLfloat [],int, void *), |
||
211 | GLint,GLint, const void *, |
||
212 | GLint,GLint,void *,GLint,GLint,GLint); |
||
213 | static void halveImagePackedPixel(int, |
||
214 | void (*)(int, const void *,GLfloat []), |
||
215 | void (*)(const GLfloat [],int, void *), |
||
216 | GLint, GLint, const void *, |
||
217 | void *, GLint, GLint, GLint); |
||
218 | static void halve1DimagePackedPixel(int, |
||
219 | void (*)(int, const void *,GLfloat []), |
||
220 | void (*)(const GLfloat [],int, void *), |
||
221 | GLint, GLint, const void *, |
||
222 | void *, GLint, GLint, GLint); |
||
223 | |||
224 | static void halve1Dimage_ubyte(GLint, GLuint, GLuint,const GLubyte *, |
||
225 | GLubyte *, GLint, GLint, GLint); |
||
226 | static void halve1Dimage_byte(GLint, GLuint, GLuint,const GLbyte *, GLbyte *, |
||
227 | GLint, GLint, GLint); |
||
228 | static void halve1Dimage_ushort(GLint, GLuint, GLuint, const GLushort *, |
||
229 | GLushort *, GLint, GLint, GLint, GLint); |
||
230 | static void halve1Dimage_short(GLint, GLuint, GLuint,const GLshort *, GLshort *, |
||
231 | GLint, GLint, GLint, GLint); |
||
232 | static void halve1Dimage_uint(GLint, GLuint, GLuint, const GLuint *, GLuint *, |
||
233 | GLint, GLint, GLint, GLint); |
||
234 | static void halve1Dimage_int(GLint, GLuint, GLuint, const GLint *, GLint *, |
||
235 | GLint, GLint, GLint, GLint); |
||
236 | static void halve1Dimage_float(GLint, GLuint, GLuint, const GLfloat *, GLfloat *, |
||
237 | GLint, GLint, GLint, GLint); |
||
238 | |||
239 | static GLint imageSize3D(GLint, GLint, GLint, GLenum,GLenum); |
||
240 | static void fillImage3D(const PixelStorageModes *, GLint, GLint, GLint,GLenum, |
||
241 | GLenum, GLboolean, const void *, GLushort *); |
||
242 | static void emptyImage3D(const PixelStorageModes *, |
||
243 | GLint, GLint, GLint, GLenum, |
||
244 | GLenum, GLboolean, |
||
245 | const GLushort *, void *); |
||
246 | static void scaleInternal3D(GLint, GLint, GLint, GLint, const GLushort *, |
||
247 | GLint, GLint, GLint, GLushort *); |
||
248 | |||
249 | static void retrieveStoreModes(PixelStorageModes *psm) |
||
250 | { |
||
251 | glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment); |
||
252 | glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length); |
||
253 | glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows); |
||
254 | glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels); |
||
255 | glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first); |
||
256 | glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes); |
||
257 | |||
258 | glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment); |
||
259 | glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length); |
||
260 | glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows); |
||
261 | glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels); |
||
262 | glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first); |
||
263 | glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes); |
||
264 | } |
||
265 | |||
266 | static void retrieveStoreModes3D(PixelStorageModes *psm) |
||
267 | { |
||
268 | glGetIntegerv(GL_UNPACK_ALIGNMENT, &psm->unpack_alignment); |
||
269 | glGetIntegerv(GL_UNPACK_ROW_LENGTH, &psm->unpack_row_length); |
||
270 | glGetIntegerv(GL_UNPACK_SKIP_ROWS, &psm->unpack_skip_rows); |
||
271 | glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &psm->unpack_skip_pixels); |
||
272 | glGetIntegerv(GL_UNPACK_LSB_FIRST, &psm->unpack_lsb_first); |
||
273 | glGetIntegerv(GL_UNPACK_SWAP_BYTES, &psm->unpack_swap_bytes); |
||
274 | glGetIntegerv(GL_UNPACK_SKIP_IMAGES, &psm->unpack_skip_images); |
||
275 | glGetIntegerv(GL_UNPACK_IMAGE_HEIGHT, &psm->unpack_image_height); |
||
276 | |||
277 | glGetIntegerv(GL_PACK_ALIGNMENT, &psm->pack_alignment); |
||
278 | glGetIntegerv(GL_PACK_ROW_LENGTH, &psm->pack_row_length); |
||
279 | glGetIntegerv(GL_PACK_SKIP_ROWS, &psm->pack_skip_rows); |
||
280 | glGetIntegerv(GL_PACK_SKIP_PIXELS, &psm->pack_skip_pixels); |
||
281 | glGetIntegerv(GL_PACK_LSB_FIRST, &psm->pack_lsb_first); |
||
282 | glGetIntegerv(GL_PACK_SWAP_BYTES, &psm->pack_swap_bytes); |
||
283 | glGetIntegerv(GL_PACK_SKIP_IMAGES, &psm->pack_skip_images); |
||
284 | glGetIntegerv(GL_PACK_IMAGE_HEIGHT, &psm->pack_image_height); |
||
285 | } |
||
286 | |||
287 | static int computeLog(GLuint value) |
||
288 | { |
||
289 | int i; |
||
290 | |||
291 | i = 0; |
||
292 | |||
293 | /* Error! */ |
||
294 | if (value == 0) return -1; |
||
295 | |||
296 | for (;;) { |
||
297 | if (value & 1) { |
||
298 | /* Error ! */ |
||
299 | if (value != 1) return -1; |
||
300 | return i; |
||
301 | } |
||
302 | value = value >> 1; |
||
303 | i++; |
||
304 | } |
||
305 | } |
||
306 | |||
307 | /* |
||
308 | ** Compute the nearest power of 2 number. This algorithm is a little |
||
309 | ** strange, but it works quite well. |
||
310 | */ |
||
311 | static int nearestPower(GLuint value) |
||
312 | { |
||
313 | int i; |
||
314 | |||
315 | i = 1; |
||
316 | |||
317 | /* Error! */ |
||
318 | if (value == 0) return -1; |
||
319 | |||
320 | for (;;) { |
||
321 | if (value == 1) { |
||
322 | return i; |
||
323 | } else if (value == 3) { |
||
324 | return i*4; |
||
325 | } |
||
326 | value = value >> 1; |
||
327 | i *= 2; |
||
328 | } |
||
329 | } |
||
330 | |||
331 | #define __GLU_SWAP_2_BYTES(s)\ |
||
332 | (GLushort)(((GLushort)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) |
||
333 | |||
334 | #define __GLU_SWAP_4_BYTES(s)\ |
||
335 | (GLuint)(((GLuint)((const GLubyte*)(s))[3])<<24 | \ |
||
336 | ((GLuint)((const GLubyte*)(s))[2])<<16 | \ |
||
337 | ((GLuint)((const GLubyte*)(s))[1])<<8 | ((const GLubyte*)(s))[0]) |
||
338 | |||
339 | static void halveImage(GLint components, GLuint width, GLuint height, |
||
340 | const GLushort *datain, GLushort *dataout) |
||
341 | { |
||
342 | int i, j, k; |
||
343 | int newwidth, newheight; |
||
344 | int delta; |
||
345 | GLushort *s; |
||
346 | const GLushort *t; |
||
347 | |||
348 | newwidth = width / 2; |
||
349 | newheight = height / 2; |
||
350 | delta = width * components; |
||
351 | s = dataout; |
||
352 | t = datain; |
||
353 | |||
354 | /* Piece o' cake! */ |
||
355 | for (i = 0; i < newheight; i++) { |
||
356 | for (j = 0; j < newwidth; j++) { |
||
357 | for (k = 0; k < components; k++) { |
||
358 | s[0] = (t[0] + t[components] + t[delta] + |
||
359 | t[delta+components] + 2) / 4; |
||
360 | s++; t++; |
||
361 | } |
||
362 | t += components; |
||
363 | } |
||
364 | t += delta; |
||
365 | } |
||
366 | } |
||
367 | |||
368 | static void halveImage_ubyte(GLint components, GLuint width, GLuint height, |
||
369 | const GLubyte *datain, GLubyte *dataout, |
||
370 | GLint element_size, GLint ysize, GLint group_size) |
||
371 | { |
||
372 | int i, j, k; |
||
373 | int newwidth, newheight; |
||
374 | int padBytes; |
||
375 | GLubyte *s; |
||
376 | const char *t; |
||
377 | |||
378 | /* handle case where there is only 1 column/row */ |
||
379 | if (width == 1 || height == 1) { |
||
380 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
381 | halve1Dimage_ubyte(components,width,height,datain,dataout, |
||
382 | element_size,ysize,group_size); |
||
383 | return; |
||
384 | } |
||
385 | |||
386 | newwidth = width / 2; |
||
387 | newheight = height / 2; |
||
388 | padBytes = ysize - (width*group_size); |
||
389 | s = dataout; |
||
390 | t = (const char *)datain; |
||
391 | |||
392 | /* Piece o' cake! */ |
||
393 | for (i = 0; i < newheight; i++) { |
||
394 | for (j = 0; j < newwidth; j++) { |
||
395 | for (k = 0; k < components; k++) { |
||
396 | s[0] = (*(const GLubyte*)t + |
||
397 | *(const GLubyte*)(t+group_size) + |
||
398 | *(const GLubyte*)(t+ysize) + |
||
399 | *(const GLubyte*)(t+ysize+group_size) + 2) / 4; |
||
400 | s++; t += element_size; |
||
401 | } |
||
402 | t += group_size; |
||
403 | } |
||
404 | t += padBytes; |
||
405 | t += ysize; |
||
406 | } |
||
407 | } |
||
408 | |||
409 | /* */ |
||
410 | static void halve1Dimage_ubyte(GLint components, GLuint width, GLuint height, |
||
411 | const GLubyte *dataIn, GLubyte *dataOut, |
||
412 | GLint element_size, GLint ysize, |
||
413 | GLint group_size) |
||
414 | { |
||
415 | GLint halfWidth= width / 2; |
||
416 | GLint halfHeight= height / 2; |
||
417 | const char *src= (const char *) dataIn; |
||
418 | GLubyte *dest= dataOut; |
||
419 | int jj; |
||
420 | |||
421 | assert(width == 1 || height == 1); /* must be 1D */ |
||
422 | assert(width != height); /* can't be square */ |
||
423 | |||
424 | if (height == 1) { /* 1 row */ |
||
425 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
426 | halfHeight= 1; |
||
427 | |||
428 | for (jj= 0; jj< halfWidth; jj++) { |
||
429 | int kk; |
||
430 | for (kk= 0; kk< components; kk++) { |
||
431 | *dest= (*(const GLubyte*)src + |
||
432 | *(const GLubyte*)(src+group_size)) / 2; |
||
433 | |||
434 | src+= element_size; |
||
435 | dest++; |
||
436 | } |
||
437 | src+= group_size; /* skip to next 2 */ |
||
438 | } |
||
439 | { |
||
440 | int padBytes= ysize - (width*group_size); |
||
441 | src+= padBytes; /* for assertion only */ |
||
442 | } |
||
443 | } |
||
444 | else if (width == 1) { /* 1 column */ |
||
445 | int padBytes= ysize - (width * group_size); |
||
446 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
447 | halfWidth= 1; |
||
448 | /* one vertical column with possible pad bytes per row */ |
||
449 | /* average two at a time */ |
||
450 | |||
451 | for (jj= 0; jj< halfHeight; jj++) { |
||
452 | int kk; |
||
453 | for (kk= 0; kk< components; kk++) { |
||
454 | *dest= (*(const GLubyte*)src + *(const GLubyte*)(src+ysize)) / 2; |
||
455 | |||
456 | src+= element_size; |
||
457 | dest++; |
||
458 | } |
||
459 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
460 | src+= ysize; |
||
461 | } |
||
462 | } |
||
463 | |||
464 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
465 | assert((char *)dest == &((char *)dataOut) |
||
466 | [components * element_size * halfWidth * halfHeight]); |
||
467 | } /* halve1Dimage_ubyte() */ |
||
468 | |||
469 | static void halveImage_byte(GLint components, GLuint width, GLuint height, |
||
470 | const GLbyte *datain, GLbyte *dataout, |
||
471 | GLint element_size, |
||
472 | GLint ysize, GLint group_size) |
||
473 | { |
||
474 | int i, j, k; |
||
475 | int newwidth, newheight; |
||
476 | int padBytes; |
||
477 | GLbyte *s; |
||
478 | const char *t; |
||
479 | |||
480 | /* handle case where there is only 1 column/row */ |
||
481 | if (width == 1 || height == 1) { |
||
482 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
483 | halve1Dimage_byte(components,width,height,datain,dataout, |
||
484 | element_size,ysize,group_size); |
||
485 | return; |
||
486 | } |
||
487 | |||
488 | newwidth = width / 2; |
||
489 | newheight = height / 2; |
||
490 | padBytes = ysize - (width*group_size); |
||
491 | s = dataout; |
||
492 | t = (const char *)datain; |
||
493 | |||
494 | /* Piece o' cake! */ |
||
495 | for (i = 0; i < newheight; i++) { |
||
496 | for (j = 0; j < newwidth; j++) { |
||
497 | for (k = 0; k < components; k++) { |
||
498 | s[0] = (*(const GLbyte*)t + |
||
499 | *(const GLbyte*)(t+group_size) + |
||
500 | *(const GLbyte*)(t+ysize) + |
||
501 | *(const GLbyte*)(t+ysize+group_size) + 2) / 4; |
||
502 | s++; t += element_size; |
||
503 | } |
||
504 | t += group_size; |
||
505 | } |
||
506 | t += padBytes; |
||
507 | t += ysize; |
||
508 | } |
||
509 | } |
||
510 | |||
511 | static void halve1Dimage_byte(GLint components, GLuint width, GLuint height, |
||
512 | const GLbyte *dataIn, GLbyte *dataOut, |
||
513 | GLint element_size,GLint ysize, GLint group_size) |
||
514 | { |
||
515 | GLint halfWidth= width / 2; |
||
516 | GLint halfHeight= height / 2; |
||
517 | const char *src= (const char *) dataIn; |
||
518 | GLbyte *dest= dataOut; |
||
519 | int jj; |
||
520 | |||
521 | assert(width == 1 || height == 1); /* must be 1D */ |
||
522 | assert(width != height); /* can't be square */ |
||
523 | |||
524 | if (height == 1) { /* 1 row */ |
||
525 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
526 | halfHeight= 1; |
||
527 | |||
528 | for (jj= 0; jj< halfWidth; jj++) { |
||
529 | int kk; |
||
530 | for (kk= 0; kk< components; kk++) { |
||
531 | *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+group_size)) / 2; |
||
532 | |||
533 | src+= element_size; |
||
534 | dest++; |
||
535 | } |
||
536 | src+= group_size; /* skip to next 2 */ |
||
537 | } |
||
538 | { |
||
539 | int padBytes= ysize - (width*group_size); |
||
540 | src+= padBytes; /* for assertion only */ |
||
541 | } |
||
542 | } |
||
543 | else if (width == 1) { /* 1 column */ |
||
544 | int padBytes= ysize - (width * group_size); |
||
545 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
546 | halfWidth= 1; |
||
547 | /* one vertical column with possible pad bytes per row */ |
||
548 | /* average two at a time */ |
||
549 | |||
550 | for (jj= 0; jj< halfHeight; jj++) { |
||
551 | int kk; |
||
552 | for (kk= 0; kk< components; kk++) { |
||
553 | *dest= (*(const GLbyte*)src + *(const GLbyte*)(src+ysize)) / 2; |
||
554 | |||
555 | src+= element_size; |
||
556 | dest++; |
||
557 | } |
||
558 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
559 | src+= ysize; |
||
560 | } |
||
561 | |||
562 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
563 | } |
||
564 | |||
565 | assert((char *)dest == &((char *)dataOut) |
||
566 | [components * element_size * halfWidth * halfHeight]); |
||
567 | } /* halve1Dimage_byte() */ |
||
568 | |||
569 | static void halveImage_ushort(GLint components, GLuint width, GLuint height, |
||
570 | const GLushort *datain, GLushort *dataout, |
||
571 | GLint element_size, GLint ysize, GLint group_size, |
||
572 | GLint myswap_bytes) |
||
573 | { |
||
574 | int i, j, k; |
||
575 | int newwidth, newheight; |
||
576 | int padBytes; |
||
577 | GLushort *s; |
||
578 | const char *t; |
||
579 | |||
580 | /* handle case where there is only 1 column/row */ |
||
581 | if (width == 1 || height == 1) { |
||
582 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
583 | halve1Dimage_ushort(components,width,height,datain,dataout, |
||
584 | element_size,ysize,group_size, myswap_bytes); |
||
585 | return; |
||
586 | } |
||
587 | |||
588 | newwidth = width / 2; |
||
589 | newheight = height / 2; |
||
590 | padBytes = ysize - (width*group_size); |
||
591 | s = dataout; |
||
592 | t = (const char *)datain; |
||
593 | |||
594 | /* Piece o' cake! */ |
||
595 | if (!myswap_bytes) |
||
596 | for (i = 0; i < newheight; i++) { |
||
597 | for (j = 0; j < newwidth; j++) { |
||
598 | for (k = 0; k < components; k++) { |
||
599 | s[0] = (*(const GLushort*)t + |
||
600 | *(const GLushort*)(t+group_size) + |
||
601 | *(const GLushort*)(t+ysize) + |
||
602 | *(const GLushort*)(t+ysize+group_size) + 2) / 4; |
||
603 | s++; t += element_size; |
||
604 | } |
||
605 | t += group_size; |
||
606 | } |
||
607 | t += padBytes; |
||
608 | t += ysize; |
||
609 | } |
||
610 | else |
||
611 | for (i = 0; i < newheight; i++) { |
||
612 | for (j = 0; j < newwidth; j++) { |
||
613 | for (k = 0; k < components; k++) { |
||
614 | s[0] = (__GLU_SWAP_2_BYTES(t) + |
||
615 | __GLU_SWAP_2_BYTES(t+group_size) + |
||
616 | __GLU_SWAP_2_BYTES(t+ysize) + |
||
617 | __GLU_SWAP_2_BYTES(t+ysize+group_size)+ 2)/4; |
||
618 | s++; t += element_size; |
||
619 | } |
||
620 | t += group_size; |
||
621 | } |
||
622 | t += padBytes; |
||
623 | t += ysize; |
||
624 | } |
||
625 | } |
||
626 | |||
627 | static void halve1Dimage_ushort(GLint components, GLuint width, GLuint height, |
||
628 | const GLushort *dataIn, GLushort *dataOut, |
||
629 | GLint element_size, GLint ysize, |
||
630 | GLint group_size, GLint myswap_bytes) |
||
631 | { |
||
632 | GLint halfWidth= width / 2; |
||
633 | GLint halfHeight= height / 2; |
||
634 | const char *src= (const char *) dataIn; |
||
635 | GLushort *dest= dataOut; |
||
636 | int jj; |
||
637 | |||
638 | assert(width == 1 || height == 1); /* must be 1D */ |
||
639 | assert(width != height); /* can't be square */ |
||
640 | |||
641 | if (height == 1) { /* 1 row */ |
||
642 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
643 | halfHeight= 1; |
||
644 | |||
645 | for (jj= 0; jj< halfWidth; jj++) { |
||
646 | int kk; |
||
647 | for (kk= 0; kk< components; kk++) { |
||
648 | #define BOX2 2 |
||
649 | GLushort ushort[BOX2]; |
||
650 | if (myswap_bytes) { |
||
651 | ushort[0]= __GLU_SWAP_2_BYTES(src); |
||
652 | ushort[1]= __GLU_SWAP_2_BYTES(src+group_size); |
||
653 | } |
||
654 | else { |
||
655 | ushort[0]= *(const GLushort*)src; |
||
656 | ushort[1]= *(const GLushort*)(src+group_size); |
||
657 | } |
||
658 | |||
659 | *dest= (ushort[0] + ushort[1]) / 2; |
||
660 | src+= element_size; |
||
661 | dest++; |
||
662 | } |
||
663 | src+= group_size; /* skip to next 2 */ |
||
664 | } |
||
665 | { |
||
666 | int padBytes= ysize - (width*group_size); |
||
667 | src+= padBytes; /* for assertion only */ |
||
668 | } |
||
669 | } |
||
670 | else if (width == 1) { /* 1 column */ |
||
671 | int padBytes= ysize - (width * group_size); |
||
672 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
673 | halfWidth= 1; |
||
674 | /* one vertical column with possible pad bytes per row */ |
||
675 | /* average two at a time */ |
||
676 | |||
677 | for (jj= 0; jj< halfHeight; jj++) { |
||
678 | int kk; |
||
679 | for (kk= 0; kk< components; kk++) { |
||
680 | #define BOX2 2 |
||
681 | GLushort ushort[BOX2]; |
||
682 | if (myswap_bytes) { |
||
683 | ushort[0]= __GLU_SWAP_2_BYTES(src); |
||
684 | ushort[1]= __GLU_SWAP_2_BYTES(src+ysize); |
||
685 | } |
||
686 | else { |
||
687 | ushort[0]= *(const GLushort*)src; |
||
688 | ushort[1]= *(const GLushort*)(src+ysize); |
||
689 | } |
||
690 | *dest= (ushort[0] + ushort[1]) / 2; |
||
691 | |||
692 | src+= element_size; |
||
693 | dest++; |
||
694 | } |
||
695 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
696 | src+= ysize; |
||
697 | } |
||
698 | |||
699 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
700 | } |
||
701 | |||
702 | assert((char *)dest == &((char *)dataOut) |
||
703 | [components * element_size * halfWidth * halfHeight]); |
||
704 | |||
705 | } /* halve1Dimage_ushort() */ |
||
706 | |||
707 | |||
708 | static void halveImage_short(GLint components, GLuint width, GLuint height, |
||
709 | const GLshort *datain, GLshort *dataout, |
||
710 | GLint element_size, GLint ysize, GLint group_size, |
||
711 | GLint myswap_bytes) |
||
712 | { |
||
713 | int i, j, k; |
||
714 | int newwidth, newheight; |
||
715 | int padBytes; |
||
716 | GLshort *s; |
||
717 | const char *t; |
||
718 | |||
719 | /* handle case where there is only 1 column/row */ |
||
720 | if (width == 1 || height == 1) { |
||
721 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
722 | halve1Dimage_short(components,width,height,datain,dataout, |
||
723 | element_size,ysize,group_size, myswap_bytes); |
||
724 | return; |
||
725 | } |
||
726 | |||
727 | newwidth = width / 2; |
||
728 | newheight = height / 2; |
||
729 | padBytes = ysize - (width*group_size); |
||
730 | s = dataout; |
||
731 | t = (const char *)datain; |
||
732 | |||
733 | /* Piece o' cake! */ |
||
734 | if (!myswap_bytes) |
||
735 | for (i = 0; i < newheight; i++) { |
||
736 | for (j = 0; j < newwidth; j++) { |
||
737 | for (k = 0; k < components; k++) { |
||
738 | s[0] = (*(const GLshort*)t + |
||
739 | *(const GLshort*)(t+group_size) + |
||
740 | *(const GLshort*)(t+ysize) + |
||
741 | *(const GLshort*)(t+ysize+group_size) + 2) / 4; |
||
742 | s++; t += element_size; |
||
743 | } |
||
744 | t += group_size; |
||
745 | } |
||
746 | t += padBytes; |
||
747 | t += ysize; |
||
748 | } |
||
749 | else |
||
750 | for (i = 0; i < newheight; i++) { |
||
751 | for (j = 0; j < newwidth; j++) { |
||
752 | for (k = 0; k < components; k++) { |
||
753 | GLushort b; |
||
754 | GLint buf; |
||
755 | b = __GLU_SWAP_2_BYTES(t); |
||
756 | buf = *(const GLshort*)&b; |
||
757 | b = __GLU_SWAP_2_BYTES(t+group_size); |
||
758 | buf += *(const GLshort*)&b; |
||
759 | b = __GLU_SWAP_2_BYTES(t+ysize); |
||
760 | buf += *(const GLshort*)&b; |
||
761 | b = __GLU_SWAP_2_BYTES(t+ysize+group_size); |
||
762 | buf += *(const GLshort*)&b; |
||
763 | s[0] = (GLshort)((buf+2)/4); |
||
764 | s++; t += element_size; |
||
765 | } |
||
766 | t += group_size; |
||
767 | } |
||
768 | t += padBytes; |
||
769 | t += ysize; |
||
770 | } |
||
771 | } |
||
772 | |||
773 | static void halve1Dimage_short(GLint components, GLuint width, GLuint height, |
||
774 | const GLshort *dataIn, GLshort *dataOut, |
||
775 | GLint element_size, GLint ysize, |
||
776 | GLint group_size, GLint myswap_bytes) |
||
777 | { |
||
778 | GLint halfWidth= width / 2; |
||
779 | GLint halfHeight= height / 2; |
||
780 | const char *src= (const char *) dataIn; |
||
781 | GLshort *dest= dataOut; |
||
782 | int jj; |
||
783 | |||
784 | assert(width == 1 || height == 1); /* must be 1D */ |
||
785 | assert(width != height); /* can't be square */ |
||
786 | |||
787 | if (height == 1) { /* 1 row */ |
||
788 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
789 | halfHeight= 1; |
||
790 | |||
791 | for (jj= 0; jj< halfWidth; jj++) { |
||
792 | int kk; |
||
793 | for (kk= 0; kk< components; kk++) { |
||
794 | #define BOX2 2 |
||
795 | GLshort sshort[BOX2]; |
||
796 | if (myswap_bytes) { |
||
797 | sshort[0]= __GLU_SWAP_2_BYTES(src); |
||
798 | sshort[1]= __GLU_SWAP_2_BYTES(src+group_size); |
||
799 | } |
||
800 | else { |
||
801 | sshort[0]= *(const GLshort*)src; |
||
802 | sshort[1]= *(const GLshort*)(src+group_size); |
||
803 | } |
||
804 | |||
805 | *dest= (sshort[0] + sshort[1]) / 2; |
||
806 | src+= element_size; |
||
807 | dest++; |
||
808 | } |
||
809 | src+= group_size; /* skip to next 2 */ |
||
810 | } |
||
811 | { |
||
812 | int padBytes= ysize - (width*group_size); |
||
813 | src+= padBytes; /* for assertion only */ |
||
814 | } |
||
815 | } |
||
816 | else if (width == 1) { /* 1 column */ |
||
817 | int padBytes= ysize - (width * group_size); |
||
818 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
819 | halfWidth= 1; |
||
820 | /* one vertical column with possible pad bytes per row */ |
||
821 | /* average two at a time */ |
||
822 | |||
823 | for (jj= 0; jj< halfHeight; jj++) { |
||
824 | int kk; |
||
825 | for (kk= 0; kk< components; kk++) { |
||
826 | #define BOX2 2 |
||
827 | GLshort sshort[BOX2]; |
||
828 | if (myswap_bytes) { |
||
829 | sshort[0]= __GLU_SWAP_2_BYTES(src); |
||
830 | sshort[1]= __GLU_SWAP_2_BYTES(src+ysize); |
||
831 | } |
||
832 | else { |
||
833 | sshort[0]= *(const GLshort*)src; |
||
834 | sshort[1]= *(const GLshort*)(src+ysize); |
||
835 | } |
||
836 | *dest= (sshort[0] + sshort[1]) / 2; |
||
837 | |||
838 | src+= element_size; |
||
839 | dest++; |
||
840 | } |
||
841 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
842 | src+= ysize; |
||
843 | } |
||
844 | |||
845 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
846 | } |
||
847 | |||
848 | assert((char *)dest == &((char *)dataOut) |
||
849 | [components * element_size * halfWidth * halfHeight]); |
||
850 | |||
851 | } /* halve1Dimage_short() */ |
||
852 | |||
853 | |||
854 | static void halveImage_uint(GLint components, GLuint width, GLuint height, |
||
855 | const GLuint *datain, GLuint *dataout, |
||
856 | GLint element_size, GLint ysize, GLint group_size, |
||
857 | GLint myswap_bytes) |
||
858 | { |
||
859 | int i, j, k; |
||
860 | int newwidth, newheight; |
||
861 | int padBytes; |
||
862 | GLuint *s; |
||
863 | const char *t; |
||
864 | |||
865 | /* handle case where there is only 1 column/row */ |
||
866 | if (width == 1 || height == 1) { |
||
867 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
868 | halve1Dimage_uint(components,width,height,datain,dataout, |
||
869 | element_size,ysize,group_size, myswap_bytes); |
||
870 | return; |
||
871 | } |
||
872 | |||
873 | newwidth = width / 2; |
||
874 | newheight = height / 2; |
||
875 | padBytes = ysize - (width*group_size); |
||
876 | s = dataout; |
||
877 | t = (const char *)datain; |
||
878 | |||
879 | /* Piece o' cake! */ |
||
880 | if (!myswap_bytes) |
||
881 | for (i = 0; i < newheight; i++) { |
||
882 | for (j = 0; j < newwidth; j++) { |
||
883 | for (k = 0; k < components; k++) { |
||
884 | /* need to cast to double to hold large unsigned ints */ |
||
885 | s[0] = ((double)*(const GLuint*)t + |
||
886 | (double)*(const GLuint*)(t+group_size) + |
||
887 | (double)*(const GLuint*)(t+ysize) + |
||
888 | (double)*(const GLuint*)(t+ysize+group_size))/4 + 0.5; |
||
889 | s++; t += element_size; |
||
890 | |||
891 | } |
||
892 | t += group_size; |
||
893 | } |
||
894 | t += padBytes; |
||
895 | t += ysize; |
||
896 | } |
||
897 | else |
||
898 | for (i = 0; i < newheight; i++) { |
||
899 | for (j = 0; j < newwidth; j++) { |
||
900 | for (k = 0; k < components; k++) { |
||
901 | /* need to cast to double to hold large unsigned ints */ |
||
902 | GLdouble buf; |
||
903 | buf = (GLdouble)__GLU_SWAP_4_BYTES(t) + |
||
904 | (GLdouble)__GLU_SWAP_4_BYTES(t+group_size) + |
||
905 | (GLdouble)__GLU_SWAP_4_BYTES(t+ysize) + |
||
906 | (GLdouble)__GLU_SWAP_4_BYTES(t+ysize+group_size); |
||
907 | s[0] = (GLuint)(buf/4 + 0.5); |
||
908 | |||
909 | s++; t += element_size; |
||
910 | } |
||
911 | t += group_size; |
||
912 | } |
||
913 | t += padBytes; |
||
914 | t += ysize; |
||
915 | } |
||
916 | } |
||
917 | |||
918 | /* */ |
||
919 | static void halve1Dimage_uint(GLint components, GLuint width, GLuint height, |
||
920 | const GLuint *dataIn, GLuint *dataOut, |
||
921 | GLint element_size, GLint ysize, |
||
922 | GLint group_size, GLint myswap_bytes) |
||
923 | { |
||
924 | GLint halfWidth= width / 2; |
||
925 | GLint halfHeight= height / 2; |
||
926 | const char *src= (const char *) dataIn; |
||
927 | GLuint *dest= dataOut; |
||
928 | int jj; |
||
929 | |||
930 | assert(width == 1 || height == 1); /* must be 1D */ |
||
931 | assert(width != height); /* can't be square */ |
||
932 | |||
933 | if (height == 1) { /* 1 row */ |
||
934 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
935 | halfHeight= 1; |
||
936 | |||
937 | for (jj= 0; jj< halfWidth; jj++) { |
||
938 | int kk; |
||
939 | for (kk= 0; kk< components; kk++) { |
||
940 | #define BOX2 2 |
||
941 | GLuint uint[BOX2]; |
||
942 | if (myswap_bytes) { |
||
943 | uint[0]= __GLU_SWAP_4_BYTES(src); |
||
944 | uint[1]= __GLU_SWAP_4_BYTES(src+group_size); |
||
945 | } |
||
946 | else { |
||
947 | uint[0]= *(const GLuint*)src; |
||
948 | uint[1]= *(const GLuint*)(src+group_size); |
||
949 | } |
||
950 | *dest= ((double)uint[0]+(double)uint[1])/2.0; |
||
951 | |||
952 | src+= element_size; |
||
953 | dest++; |
||
954 | } |
||
955 | src+= group_size; /* skip to next 2 */ |
||
956 | } |
||
957 | { |
||
958 | int padBytes= ysize - (width*group_size); |
||
959 | src+= padBytes; /* for assertion only */ |
||
960 | } |
||
961 | } |
||
962 | else if (width == 1) { /* 1 column */ |
||
963 | int padBytes= ysize - (width * group_size); |
||
964 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
965 | halfWidth= 1; |
||
966 | /* one vertical column with possible pad bytes per row */ |
||
967 | /* average two at a time */ |
||
968 | |||
969 | for (jj= 0; jj< halfHeight; jj++) { |
||
970 | int kk; |
||
971 | for (kk= 0; kk< components; kk++) { |
||
972 | #define BOX2 2 |
||
973 | GLuint uint[BOX2]; |
||
974 | if (myswap_bytes) { |
||
975 | uint[0]= __GLU_SWAP_4_BYTES(src); |
||
976 | uint[1]= __GLU_SWAP_4_BYTES(src+ysize); |
||
977 | } |
||
978 | else { |
||
979 | uint[0]= *(const GLuint*)src; |
||
980 | uint[1]= *(const GLuint*)(src+ysize); |
||
981 | } |
||
982 | *dest= ((double)uint[0]+(double)uint[1])/2.0; |
||
983 | |||
984 | src+= element_size; |
||
985 | dest++; |
||
986 | } |
||
987 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
988 | src+= ysize; |
||
989 | } |
||
990 | |||
991 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
992 | } |
||
993 | |||
994 | assert((char *)dest == &((char *)dataOut) |
||
995 | [components * element_size * halfWidth * halfHeight]); |
||
996 | |||
997 | } /* halve1Dimage_uint() */ |
||
998 | |||
999 | static void halveImage_int(GLint components, GLuint width, GLuint height, |
||
1000 | const GLint *datain, GLint *dataout, GLint element_size, |
||
1001 | GLint ysize, GLint group_size, GLint myswap_bytes) |
||
1002 | { |
||
1003 | int i, j, k; |
||
1004 | int newwidth, newheight; |
||
1005 | int padBytes; |
||
1006 | GLint *s; |
||
1007 | const char *t; |
||
1008 | |||
1009 | /* handle case where there is only 1 column/row */ |
||
1010 | if (width == 1 || height == 1) { |
||
1011 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
1012 | halve1Dimage_int(components,width,height,datain,dataout, |
||
1013 | element_size,ysize,group_size, myswap_bytes); |
||
1014 | return; |
||
1015 | } |
||
1016 | |||
1017 | newwidth = width / 2; |
||
1018 | newheight = height / 2; |
||
1019 | padBytes = ysize - (width*group_size); |
||
1020 | s = dataout; |
||
1021 | t = (const char *)datain; |
||
1022 | |||
1023 | /* Piece o' cake! */ |
||
1024 | if (!myswap_bytes) |
||
1025 | for (i = 0; i < newheight; i++) { |
||
1026 | for (j = 0; j < newwidth; j++) { |
||
1027 | for (k = 0; k < components; k++) { |
||
1028 | s[0] = ((float)*(const GLint*)t + |
||
1029 | (float)*(const GLint*)(t+group_size) + |
||
1030 | (float)*(const GLint*)(t+ysize) + |
||
1031 | (float)*(const GLint*)(t+ysize+group_size))/4 + 0.5; |
||
1032 | s++; t += element_size; |
||
1033 | } |
||
1034 | t += group_size; |
||
1035 | } |
||
1036 | t += padBytes; |
||
1037 | t += ysize; |
||
1038 | } |
||
1039 | else |
||
1040 | for (i = 0; i < newheight; i++) { |
||
1041 | for (j = 0; j < newwidth; j++) { |
||
1042 | for (k = 0; k < components; k++) { |
||
1043 | GLuint b; |
||
1044 | GLfloat buf; |
||
1045 | b = __GLU_SWAP_4_BYTES(t); |
||
1046 | buf = *(GLint*)&b; |
||
1047 | b = __GLU_SWAP_4_BYTES(t+group_size); |
||
1048 | buf += *(GLint*)&b; |
||
1049 | b = __GLU_SWAP_4_BYTES(t+ysize); |
||
1050 | buf += *(GLint*)&b; |
||
1051 | b = __GLU_SWAP_4_BYTES(t+ysize+group_size); |
||
1052 | buf += *(GLint*)&b; |
||
1053 | s[0] = (GLint)(buf/4 + 0.5); |
||
1054 | |||
1055 | s++; t += element_size; |
||
1056 | } |
||
1057 | t += group_size; |
||
1058 | } |
||
1059 | t += padBytes; |
||
1060 | t += ysize; |
||
1061 | } |
||
1062 | } |
||
1063 | |||
1064 | /* */ |
||
1065 | static void halve1Dimage_int(GLint components, GLuint width, GLuint height, |
||
1066 | const GLint *dataIn, GLint *dataOut, |
||
1067 | GLint element_size, GLint ysize, |
||
1068 | GLint group_size, GLint myswap_bytes) |
||
1069 | { |
||
1070 | GLint halfWidth= width / 2; |
||
1071 | GLint halfHeight= height / 2; |
||
1072 | const char *src= (const char *) dataIn; |
||
1073 | GLint *dest= dataOut; |
||
1074 | int jj; |
||
1075 | |||
1076 | assert(width == 1 || height == 1); /* must be 1D */ |
||
1077 | assert(width != height); /* can't be square */ |
||
1078 | |||
1079 | if (height == 1) { /* 1 row */ |
||
1080 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
1081 | halfHeight= 1; |
||
1082 | |||
1083 | for (jj= 0; jj< halfWidth; jj++) { |
||
1084 | int kk; |
||
1085 | for (kk= 0; kk< components; kk++) { |
||
1086 | #define BOX2 2 |
||
1087 | GLuint uint[BOX2]; |
||
1088 | if (myswap_bytes) { |
||
1089 | uint[0]= __GLU_SWAP_4_BYTES(src); |
||
1090 | uint[1]= __GLU_SWAP_4_BYTES(src+group_size); |
||
1091 | } |
||
1092 | else { |
||
1093 | uint[0]= *(const GLuint*)src; |
||
1094 | uint[1]= *(const GLuint*)(src+group_size); |
||
1095 | } |
||
1096 | *dest= ((float)uint[0]+(float)uint[1])/2.0; |
||
1097 | |||
1098 | src+= element_size; |
||
1099 | dest++; |
||
1100 | } |
||
1101 | src+= group_size; /* skip to next 2 */ |
||
1102 | } |
||
1103 | { |
||
1104 | int padBytes= ysize - (width*group_size); |
||
1105 | src+= padBytes; /* for assertion only */ |
||
1106 | } |
||
1107 | } |
||
1108 | else if (width == 1) { /* 1 column */ |
||
1109 | int padBytes= ysize - (width * group_size); |
||
1110 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
1111 | halfWidth= 1; |
||
1112 | /* one vertical column with possible pad bytes per row */ |
||
1113 | /* average two at a time */ |
||
1114 | |||
1115 | for (jj= 0; jj< halfHeight; jj++) { |
||
1116 | int kk; |
||
1117 | for (kk= 0; kk< components; kk++) { |
||
1118 | #define BOX2 2 |
||
1119 | GLuint uint[BOX2]; |
||
1120 | if (myswap_bytes) { |
||
1121 | uint[0]= __GLU_SWAP_4_BYTES(src); |
||
1122 | uint[1]= __GLU_SWAP_4_BYTES(src+ysize); |
||
1123 | } |
||
1124 | else { |
||
1125 | uint[0]= *(const GLuint*)src; |
||
1126 | uint[1]= *(const GLuint*)(src+ysize); |
||
1127 | } |
||
1128 | *dest= ((float)uint[0]+(float)uint[1])/2.0; |
||
1129 | |||
1130 | src+= element_size; |
||
1131 | dest++; |
||
1132 | } |
||
1133 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
1134 | src+= ysize; |
||
1135 | } |
||
1136 | |||
1137 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
1138 | } |
||
1139 | |||
1140 | assert((char *)dest == &((char *)dataOut) |
||
1141 | [components * element_size * halfWidth * halfHeight]); |
||
1142 | |||
1143 | } /* halve1Dimage_int() */ |
||
1144 | |||
1145 | |||
1146 | static void halveImage_float(GLint components, GLuint width, GLuint height, |
||
1147 | const GLfloat *datain, GLfloat *dataout, |
||
1148 | GLint element_size, GLint ysize, GLint group_size, |
||
1149 | GLint myswap_bytes) |
||
1150 | { |
||
1151 | int i, j, k; |
||
1152 | int newwidth, newheight; |
||
1153 | int padBytes; |
||
1154 | GLfloat *s; |
||
1155 | const char *t; |
||
1156 | |||
1157 | /* handle case where there is only 1 column/row */ |
||
1158 | if (width == 1 || height == 1) { |
||
1159 | assert( !(width == 1 && height == 1) ); /* can't be 1x1 */ |
||
1160 | halve1Dimage_float(components,width,height,datain,dataout, |
||
1161 | element_size,ysize,group_size, myswap_bytes); |
||
1162 | return; |
||
1163 | } |
||
1164 | |||
1165 | newwidth = width / 2; |
||
1166 | newheight = height / 2; |
||
1167 | padBytes = ysize - (width*group_size); |
||
1168 | s = dataout; |
||
1169 | t = (const char *)datain; |
||
1170 | |||
1171 | /* Piece o' cake! */ |
||
1172 | if (!myswap_bytes) |
||
1173 | for (i = 0; i < newheight; i++) { |
||
1174 | for (j = 0; j < newwidth; j++) { |
||
1175 | for (k = 0; k < components; k++) { |
||
1176 | s[0] = (*(const GLfloat*)t + |
||
1177 | *(const GLfloat*)(t+group_size) + |
||
1178 | *(const GLfloat*)(t+ysize) + |
||
1179 | *(const GLfloat*)(t+ysize+group_size)) / 4; |
||
1180 | s++; t += element_size; |
||
1181 | } |
||
1182 | t += group_size; |
||
1183 | } |
||
1184 | t += padBytes; |
||
1185 | t += ysize; |
||
1186 | } |
||
1187 | else |
||
1188 | for (i = 0; i < newheight; i++) { |
||
1189 | for (j = 0; j < newwidth; j++) { |
||
1190 | for (k = 0; k < components; k++) { |
||
1191 | union { GLuint b; GLfloat f; } swapbuf; |
||
1192 | swapbuf.b = __GLU_SWAP_4_BYTES(t); |
||
1193 | s[0] = swapbuf.f; |
||
1194 | swapbuf.b = __GLU_SWAP_4_BYTES(t+group_size); |
||
1195 | s[0] += swapbuf.f; |
||
1196 | swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize); |
||
1197 | s[0] += swapbuf.f; |
||
1198 | swapbuf.b = __GLU_SWAP_4_BYTES(t+ysize+group_size); |
||
1199 | s[0] += swapbuf.f; |
||
1200 | s[0] /= 4; |
||
1201 | s++; t += element_size; |
||
1202 | } |
||
1203 | t += group_size; |
||
1204 | } |
||
1205 | t += padBytes; |
||
1206 | t += ysize; |
||
1207 | } |
||
1208 | } |
||
1209 | |||
1210 | /* */ |
||
1211 | static void halve1Dimage_float(GLint components, GLuint width, GLuint height, |
||
1212 | const GLfloat *dataIn, GLfloat *dataOut, |
||
1213 | GLint element_size, GLint ysize, |
||
1214 | GLint group_size, GLint myswap_bytes) |
||
1215 | { |
||
1216 | GLint halfWidth= width / 2; |
||
1217 | GLint halfHeight= height / 2; |
||
1218 | const char *src= (const char *) dataIn; |
||
1219 | GLfloat *dest= dataOut; |
||
1220 | int jj; |
||
1221 | |||
1222 | assert(width == 1 || height == 1); /* must be 1D */ |
||
1223 | assert(width != height); /* can't be square */ |
||
1224 | |||
1225 | if (height == 1) { /* 1 row */ |
||
1226 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
1227 | halfHeight= 1; |
||
1228 | |||
1229 | for (jj= 0; jj< halfWidth; jj++) { |
||
1230 | int kk; |
||
1231 | for (kk= 0; kk< components; kk++) { |
||
1232 | #define BOX2 2 |
||
1233 | GLfloat sfloat[BOX2]; |
||
1234 | if (myswap_bytes) { |
||
1235 | sfloat[0]= __GLU_SWAP_4_BYTES(src); |
||
1236 | sfloat[1]= __GLU_SWAP_4_BYTES(src+group_size); |
||
1237 | } |
||
1238 | else { |
||
1239 | sfloat[0]= *(const GLfloat*)src; |
||
1240 | sfloat[1]= *(const GLfloat*)(src+group_size); |
||
1241 | } |
||
1242 | |||
1243 | *dest= (sfloat[0] + sfloat[1]) / 2.0; |
||
1244 | src+= element_size; |
||
1245 | dest++; |
||
1246 | } |
||
1247 | src+= group_size; /* skip to next 2 */ |
||
1248 | } |
||
1249 | { |
||
1250 | int padBytes= ysize - (width*group_size); |
||
1251 | src+= padBytes; /* for assertion only */ |
||
1252 | } |
||
1253 | } |
||
1254 | else if (width == 1) { /* 1 column */ |
||
1255 | int padBytes= ysize - (width * group_size); |
||
1256 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
1257 | halfWidth= 1; |
||
1258 | /* one vertical column with possible pad bytes per row */ |
||
1259 | /* average two at a time */ |
||
1260 | |||
1261 | for (jj= 0; jj< halfHeight; jj++) { |
||
1262 | int kk; |
||
1263 | for (kk= 0; kk< components; kk++) { |
||
1264 | #define BOX2 2 |
||
1265 | GLfloat sfloat[BOX2]; |
||
1266 | if (myswap_bytes) { |
||
1267 | sfloat[0]= __GLU_SWAP_4_BYTES(src); |
||
1268 | sfloat[1]= __GLU_SWAP_4_BYTES(src+ysize); |
||
1269 | } |
||
1270 | else { |
||
1271 | sfloat[0]= *(const GLfloat*)src; |
||
1272 | sfloat[1]= *(const GLfloat*)(src+ysize); |
||
1273 | } |
||
1274 | *dest= (sfloat[0] + sfloat[1]) / 2.0; |
||
1275 | |||
1276 | src+= element_size; |
||
1277 | dest++; |
||
1278 | } |
||
1279 | src+= padBytes; /* add pad bytes, if any, to get to end to row */ |
||
1280 | src+= ysize; /* skip to odd row */ |
||
1281 | } |
||
1282 | } |
||
1283 | |||
1284 | assert(src == &((const char *)dataIn)[ysize*height]); |
||
1285 | assert((char *)dest == &((char *)dataOut) |
||
1286 | [components * element_size * halfWidth * halfHeight]); |
||
1287 | } /* halve1Dimage_float() */ |
||
1288 | |||
1289 | static void scale_internal(GLint components, GLint widthin, GLint heightin, |
||
1290 | const GLushort *datain, |
||
1291 | GLint widthout, GLint heightout, |
||
1292 | GLushort *dataout) |
||
1293 | { |
||
1294 | float x, lowx, highx, convx, halfconvx; |
||
1295 | float y, lowy, highy, convy, halfconvy; |
||
1296 | float xpercent,ypercent; |
||
1297 | float percent; |
||
1298 | /* Max components in a format is 4, so... */ |
||
1299 | float totals[4]; |
||
1300 | float area; |
||
1301 | int i,j,k,yint,xint,xindex,yindex; |
||
1302 | int temp; |
||
1303 | |||
1304 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
1305 | halveImage(components, widthin, heightin, datain, dataout); |
||
1306 | return; |
||
1307 | } |
||
1308 | convy = (float) heightin/heightout; |
||
1309 | convx = (float) widthin/widthout; |
||
1310 | halfconvx = convx/2; |
||
1311 | halfconvy = convy/2; |
||
1312 | for (i = 0; i < heightout; i++) { |
||
1313 | y = convy * (i+0.5); |
||
1314 | if (heightin > heightout) { |
||
1315 | highy = y + halfconvy; |
||
1316 | lowy = y - halfconvy; |
||
1317 | } else { |
||
1318 | highy = y + 0.5; |
||
1319 | lowy = y - 0.5; |
||
1320 | } |
||
1321 | for (j = 0; j < widthout; j++) { |
||
1322 | x = convx * (j+0.5); |
||
1323 | if (widthin > widthout) { |
||
1324 | highx = x + halfconvx; |
||
1325 | lowx = x - halfconvx; |
||
1326 | } else { |
||
1327 | highx = x + 0.5; |
||
1328 | lowx = x - 0.5; |
||
1329 | } |
||
1330 | |||
1331 | /* |
||
1332 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
1333 | ** to (highx, highy) on input data into this pixel on output |
||
1334 | ** data. |
||
1335 | */ |
||
1336 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
1337 | area = 0.0; |
||
1338 | |||
1339 | y = lowy; |
||
1340 | yint = floor(y); |
||
1341 | while (y < highy) { |
||
1342 | yindex = (yint + heightin) % heightin; |
||
1343 | if (highy < yint+1) { |
||
1344 | ypercent = highy - y; |
||
1345 | } else { |
||
1346 | ypercent = yint+1 - y; |
||
1347 | } |
||
1348 | |||
1349 | x = lowx; |
||
1350 | xint = floor(x); |
||
1351 | |||
1352 | while (x < highx) { |
||
1353 | xindex = (xint + widthin) % widthin; |
||
1354 | if (highx < xint+1) { |
||
1355 | xpercent = highx - x; |
||
1356 | } else { |
||
1357 | xpercent = xint+1 - x; |
||
1358 | } |
||
1359 | |||
1360 | percent = xpercent * ypercent; |
||
1361 | area += percent; |
||
1362 | temp = (xindex + (yindex * widthin)) * components; |
||
1363 | for (k = 0; k < components; k++) { |
||
1364 | totals[k] += datain[temp + k] * percent; |
||
1365 | } |
||
1366 | |||
1367 | xint++; |
||
1368 | x = xint; |
||
1369 | } |
||
1370 | yint++; |
||
1371 | y = yint; |
||
1372 | } |
||
1373 | |||
1374 | temp = (j + (i * widthout)) * components; |
||
1375 | for (k = 0; k < components; k++) { |
||
1376 | /* totals[] should be rounded in the case of enlarging an RGB |
||
1377 | * ramp when the type is 332 or 4444 |
||
1378 | */ |
||
1379 | dataout[temp + k] = (totals[k]+0.5)/area; |
||
1380 | } |
||
1381 | } |
||
1382 | } |
||
1383 | } |
||
1384 | |||
1385 | static void scale_internal_ubyte(GLint components, GLint widthin, |
||
1386 | GLint heightin, const GLubyte *datain, |
||
1387 | GLint widthout, GLint heightout, |
||
1388 | GLubyte *dataout, GLint element_size, |
||
1389 | GLint ysize, GLint group_size) |
||
1390 | { |
||
1391 | float convx; |
||
1392 | float convy; |
||
1393 | float percent; |
||
1394 | /* Max components in a format is 4, so... */ |
||
1395 | float totals[4]; |
||
1396 | float area; |
||
1397 | int i,j,k,xindex; |
||
1398 | |||
1399 | const char *temp, *temp0; |
||
1400 | const char *temp_index; |
||
1401 | int outindex; |
||
1402 | |||
1403 | int lowx_int, highx_int, lowy_int, highy_int; |
||
1404 | float x_percent, y_percent; |
||
1405 | float lowx_float, highx_float, lowy_float, highy_float; |
||
1406 | float convy_float, convx_float; |
||
1407 | int convy_int, convx_int; |
||
1408 | int l, m; |
||
1409 | const char *left, *right; |
||
1410 | |||
1411 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
1412 | halveImage_ubyte(components, widthin, heightin, |
||
1413 | (const GLubyte *)datain, (GLubyte *)dataout, |
||
1414 | element_size, ysize, group_size); |
||
1415 | return; |
||
1416 | } |
||
1417 | convy = (float) heightin/heightout; |
||
1418 | convx = (float) widthin/widthout; |
||
1419 | convy_int = floor(convy); |
||
1420 | convy_float = convy - convy_int; |
||
1421 | convx_int = floor(convx); |
||
1422 | convx_float = convx - convx_int; |
||
1423 | |||
1424 | area = convx * convy; |
||
1425 | |||
1426 | lowy_int = 0; |
||
1427 | lowy_float = 0; |
||
1428 | highy_int = convy_int; |
||
1429 | highy_float = convy_float; |
||
1430 | |||
1431 | for (i = 0; i < heightout; i++) { |
||
1432 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
1433 | if (highy_int >= heightin) |
||
1434 | highy_int = heightin - 1; |
||
1435 | lowx_int = 0; |
||
1436 | lowx_float = 0; |
||
1437 | highx_int = convx_int; |
||
1438 | highx_float = convx_float; |
||
1439 | |||
1440 | for (j = 0; j < widthout; j++) { |
||
1441 | |||
1442 | /* |
||
1443 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
1444 | ** to (highx, highy) on input data into this pixel on output |
||
1445 | ** data. |
||
1446 | */ |
||
1447 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
1448 | |||
1449 | /* calculate the value for pixels in the 1st row */ |
||
1450 | xindex = lowx_int*group_size; |
||
1451 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
1452 | |||
1453 | y_percent = 1-lowy_float; |
||
1454 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
1455 | percent = y_percent * (1-lowx_float); |
||
1456 | for (k = 0, temp_index = temp; k < components; |
||
1457 | k++, temp_index += element_size) { |
||
1458 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1459 | } |
||
1460 | left = temp; |
||
1461 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1462 | temp += group_size; |
||
1463 | for (k = 0, temp_index = temp; k < components; |
||
1464 | k++, temp_index += element_size) { |
||
1465 | totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
||
1466 | } |
||
1467 | } |
||
1468 | temp += group_size; |
||
1469 | right = temp; |
||
1470 | percent = y_percent * highx_float; |
||
1471 | for (k = 0, temp_index = temp; k < components; |
||
1472 | k++, temp_index += element_size) { |
||
1473 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1474 | } |
||
1475 | |||
1476 | /* calculate the value for pixels in the last row */ |
||
1477 | y_percent = highy_float; |
||
1478 | percent = y_percent * (1-lowx_float); |
||
1479 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
1480 | for (k = 0, temp_index = temp; k < components; |
||
1481 | k++, temp_index += element_size) { |
||
1482 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1483 | } |
||
1484 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1485 | temp += group_size; |
||
1486 | for (k = 0, temp_index = temp; k < components; |
||
1487 | k++, temp_index += element_size) { |
||
1488 | totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
||
1489 | } |
||
1490 | } |
||
1491 | temp += group_size; |
||
1492 | percent = y_percent * highx_float; |
||
1493 | for (k = 0, temp_index = temp; k < components; |
||
1494 | k++, temp_index += element_size) { |
||
1495 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1496 | } |
||
1497 | |||
1498 | |||
1499 | /* calculate the value for pixels in the 1st and last column */ |
||
1500 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1501 | left += ysize; |
||
1502 | right += ysize; |
||
1503 | for (k = 0; k < components; |
||
1504 | k++, left += element_size, right += element_size) { |
||
1505 | totals[k] += (GLubyte)(*(left))*(1-lowx_float) |
||
1506 | +(GLubyte)(*(right))*highx_float; |
||
1507 | } |
||
1508 | } |
||
1509 | } else if (highy_int > lowy_int) { |
||
1510 | x_percent = highx_float - lowx_float; |
||
1511 | percent = (1-lowy_float)*x_percent; |
||
1512 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
1513 | for (k = 0, temp_index = temp; k < components; |
||
1514 | k++, temp_index += element_size) { |
||
1515 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1516 | } |
||
1517 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1518 | temp += ysize; |
||
1519 | for (k = 0, temp_index = temp; k < components; |
||
1520 | k++, temp_index += element_size) { |
||
1521 | totals[k] += (GLubyte)(*(temp_index)) * x_percent; |
||
1522 | } |
||
1523 | } |
||
1524 | percent = x_percent * highy_float; |
||
1525 | temp += ysize; |
||
1526 | for (k = 0, temp_index = temp; k < components; |
||
1527 | k++, temp_index += element_size) { |
||
1528 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1529 | } |
||
1530 | } else if (highx_int > lowx_int) { |
||
1531 | y_percent = highy_float - lowy_float; |
||
1532 | percent = (1-lowx_float)*y_percent; |
||
1533 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
1534 | for (k = 0, temp_index = temp; k < components; |
||
1535 | k++, temp_index += element_size) { |
||
1536 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1537 | } |
||
1538 | for (l = lowx_int+1; l < highx_int; l++) { |
||
1539 | temp += group_size; |
||
1540 | for (k = 0, temp_index = temp; k < components; |
||
1541 | k++, temp_index += element_size) { |
||
1542 | totals[k] += (GLubyte)(*(temp_index)) * y_percent; |
||
1543 | } |
||
1544 | } |
||
1545 | temp += group_size; |
||
1546 | percent = y_percent * highx_float; |
||
1547 | for (k = 0, temp_index = temp; k < components; |
||
1548 | k++, temp_index += element_size) { |
||
1549 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1550 | } |
||
1551 | } else { |
||
1552 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
1553 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
1554 | for (k = 0, temp_index = temp; k < components; |
||
1555 | k++, temp_index += element_size) { |
||
1556 | totals[k] += (GLubyte)(*(temp_index)) * percent; |
||
1557 | } |
||
1558 | } |
||
1559 | |||
1560 | |||
1561 | |||
1562 | /* this is for the pixels in the body */ |
||
1563 | temp0 = (const char *)datain + xindex + group_size + |
||
1564 | (lowy_int+1)*ysize; |
||
1565 | for (m = lowy_int+1; m < highy_int; m++) { |
||
1566 | temp = temp0; |
||
1567 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1568 | for (k = 0, temp_index = temp; k < components; |
||
1569 | k++, temp_index += element_size) { |
||
1570 | totals[k] += (GLubyte)(*(temp_index)); |
||
1571 | } |
||
1572 | temp += group_size; |
||
1573 | } |
||
1574 | temp0 += ysize; |
||
1575 | } |
||
1576 | |||
1577 | outindex = (j + (i * widthout)) * components; |
||
1578 | for (k = 0; k < components; k++) { |
||
1579 | dataout[outindex + k] = totals[k]/area; |
||
1580 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
1581 | } |
||
1582 | lowx_int = highx_int; |
||
1583 | lowx_float = highx_float; |
||
1584 | highx_int += convx_int; |
||
1585 | highx_float += convx_float; |
||
1586 | if(highx_float > 1) { |
||
1587 | highx_float -= 1.0; |
||
1588 | highx_int++; |
||
1589 | } |
||
1590 | } |
||
1591 | lowy_int = highy_int; |
||
1592 | lowy_float = highy_float; |
||
1593 | highy_int += convy_int; |
||
1594 | highy_float += convy_float; |
||
1595 | if(highy_float > 1) { |
||
1596 | highy_float -= 1.0; |
||
1597 | highy_int++; |
||
1598 | } |
||
1599 | } |
||
1600 | } |
||
1601 | |||
1602 | static void scale_internal_byte(GLint components, GLint widthin, |
||
1603 | GLint heightin, const GLbyte *datain, |
||
1604 | GLint widthout, GLint heightout, |
||
1605 | GLbyte *dataout, GLint element_size, |
||
1606 | GLint ysize, GLint group_size) |
||
1607 | { |
||
1608 | float convx; |
||
1609 | float convy; |
||
1610 | float percent; |
||
1611 | /* Max components in a format is 4, so... */ |
||
1612 | float totals[4]; |
||
1613 | float area; |
||
1614 | int i,j,k,xindex; |
||
1615 | |||
1616 | const char *temp, *temp0; |
||
1617 | const char *temp_index; |
||
1618 | int outindex; |
||
1619 | |||
1620 | int lowx_int, highx_int, lowy_int, highy_int; |
||
1621 | float x_percent, y_percent; |
||
1622 | float lowx_float, highx_float, lowy_float, highy_float; |
||
1623 | float convy_float, convx_float; |
||
1624 | int convy_int, convx_int; |
||
1625 | int l, m; |
||
1626 | const char *left, *right; |
||
1627 | |||
1628 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
1629 | halveImage_byte(components, widthin, heightin, |
||
1630 | (const GLbyte *)datain, (GLbyte *)dataout, |
||
1631 | element_size, ysize, group_size); |
||
1632 | return; |
||
1633 | } |
||
1634 | convy = (float) heightin/heightout; |
||
1635 | convx = (float) widthin/widthout; |
||
1636 | convy_int = floor(convy); |
||
1637 | convy_float = convy - convy_int; |
||
1638 | convx_int = floor(convx); |
||
1639 | convx_float = convx - convx_int; |
||
1640 | |||
1641 | area = convx * convy; |
||
1642 | |||
1643 | lowy_int = 0; |
||
1644 | lowy_float = 0; |
||
1645 | highy_int = convy_int; |
||
1646 | highy_float = convy_float; |
||
1647 | |||
1648 | for (i = 0; i < heightout; i++) { |
||
1649 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
1650 | if (highy_int >= heightin) |
||
1651 | highy_int = heightin - 1; |
||
1652 | lowx_int = 0; |
||
1653 | lowx_float = 0; |
||
1654 | highx_int = convx_int; |
||
1655 | highx_float = convx_float; |
||
1656 | |||
1657 | for (j = 0; j < widthout; j++) { |
||
1658 | |||
1659 | /* |
||
1660 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
1661 | ** to (highx, highy) on input data into this pixel on output |
||
1662 | ** data. |
||
1663 | */ |
||
1664 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
1665 | |||
1666 | /* calculate the value for pixels in the 1st row */ |
||
1667 | xindex = lowx_int*group_size; |
||
1668 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
1669 | |||
1670 | y_percent = 1-lowy_float; |
||
1671 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
1672 | percent = y_percent * (1-lowx_float); |
||
1673 | for (k = 0, temp_index = temp; k < components; |
||
1674 | k++, temp_index += element_size) { |
||
1675 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1676 | } |
||
1677 | left = temp; |
||
1678 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1679 | temp += group_size; |
||
1680 | for (k = 0, temp_index = temp; k < components; |
||
1681 | k++, temp_index += element_size) { |
||
1682 | totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
||
1683 | } |
||
1684 | } |
||
1685 | temp += group_size; |
||
1686 | right = temp; |
||
1687 | percent = y_percent * highx_float; |
||
1688 | for (k = 0, temp_index = temp; k < components; |
||
1689 | k++, temp_index += element_size) { |
||
1690 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1691 | } |
||
1692 | |||
1693 | /* calculate the value for pixels in the last row */ |
||
1694 | y_percent = highy_float; |
||
1695 | percent = y_percent * (1-lowx_float); |
||
1696 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
1697 | for (k = 0, temp_index = temp; k < components; |
||
1698 | k++, temp_index += element_size) { |
||
1699 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1700 | } |
||
1701 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1702 | temp += group_size; |
||
1703 | for (k = 0, temp_index = temp; k < components; |
||
1704 | k++, temp_index += element_size) { |
||
1705 | totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
||
1706 | } |
||
1707 | } |
||
1708 | temp += group_size; |
||
1709 | percent = y_percent * highx_float; |
||
1710 | for (k = 0, temp_index = temp; k < components; |
||
1711 | k++, temp_index += element_size) { |
||
1712 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1713 | } |
||
1714 | |||
1715 | |||
1716 | /* calculate the value for pixels in the 1st and last column */ |
||
1717 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1718 | left += ysize; |
||
1719 | right += ysize; |
||
1720 | for (k = 0; k < components; |
||
1721 | k++, left += element_size, right += element_size) { |
||
1722 | totals[k] += (GLbyte)(*(left))*(1-lowx_float) |
||
1723 | +(GLbyte)(*(right))*highx_float; |
||
1724 | } |
||
1725 | } |
||
1726 | } else if (highy_int > lowy_int) { |
||
1727 | x_percent = highx_float - lowx_float; |
||
1728 | percent = (1-lowy_float)*x_percent; |
||
1729 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
1730 | for (k = 0, temp_index = temp; k < components; |
||
1731 | k++, temp_index += element_size) { |
||
1732 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1733 | } |
||
1734 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1735 | temp += ysize; |
||
1736 | for (k = 0, temp_index = temp; k < components; |
||
1737 | k++, temp_index += element_size) { |
||
1738 | totals[k] += (GLbyte)(*(temp_index)) * x_percent; |
||
1739 | } |
||
1740 | } |
||
1741 | percent = x_percent * highy_float; |
||
1742 | temp += ysize; |
||
1743 | for (k = 0, temp_index = temp; k < components; |
||
1744 | k++, temp_index += element_size) { |
||
1745 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1746 | } |
||
1747 | } else if (highx_int > lowx_int) { |
||
1748 | y_percent = highy_float - lowy_float; |
||
1749 | percent = (1-lowx_float)*y_percent; |
||
1750 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
1751 | for (k = 0, temp_index = temp; k < components; |
||
1752 | k++, temp_index += element_size) { |
||
1753 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1754 | } |
||
1755 | for (l = lowx_int+1; l < highx_int; l++) { |
||
1756 | temp += group_size; |
||
1757 | for (k = 0, temp_index = temp; k < components; |
||
1758 | k++, temp_index += element_size) { |
||
1759 | totals[k] += (GLbyte)(*(temp_index)) * y_percent; |
||
1760 | } |
||
1761 | } |
||
1762 | temp += group_size; |
||
1763 | percent = y_percent * highx_float; |
||
1764 | for (k = 0, temp_index = temp; k < components; |
||
1765 | k++, temp_index += element_size) { |
||
1766 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1767 | } |
||
1768 | } else { |
||
1769 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
1770 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
1771 | for (k = 0, temp_index = temp; k < components; |
||
1772 | k++, temp_index += element_size) { |
||
1773 | totals[k] += (GLbyte)(*(temp_index)) * percent; |
||
1774 | } |
||
1775 | } |
||
1776 | |||
1777 | |||
1778 | |||
1779 | /* this is for the pixels in the body */ |
||
1780 | temp0 = (const char *)datain + xindex + group_size + |
||
1781 | (lowy_int+1)*ysize; |
||
1782 | for (m = lowy_int+1; m < highy_int; m++) { |
||
1783 | temp = temp0; |
||
1784 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1785 | for (k = 0, temp_index = temp; k < components; |
||
1786 | k++, temp_index += element_size) { |
||
1787 | totals[k] += (GLbyte)(*(temp_index)); |
||
1788 | } |
||
1789 | temp += group_size; |
||
1790 | } |
||
1791 | temp0 += ysize; |
||
1792 | } |
||
1793 | |||
1794 | outindex = (j + (i * widthout)) * components; |
||
1795 | for (k = 0; k < components; k++) { |
||
1796 | dataout[outindex + k] = totals[k]/area; |
||
1797 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
1798 | } |
||
1799 | lowx_int = highx_int; |
||
1800 | lowx_float = highx_float; |
||
1801 | highx_int += convx_int; |
||
1802 | highx_float += convx_float; |
||
1803 | if(highx_float > 1) { |
||
1804 | highx_float -= 1.0; |
||
1805 | highx_int++; |
||
1806 | } |
||
1807 | } |
||
1808 | lowy_int = highy_int; |
||
1809 | lowy_float = highy_float; |
||
1810 | highy_int += convy_int; |
||
1811 | highy_float += convy_float; |
||
1812 | if(highy_float > 1) { |
||
1813 | highy_float -= 1.0; |
||
1814 | highy_int++; |
||
1815 | } |
||
1816 | } |
||
1817 | } |
||
1818 | |||
1819 | static void scale_internal_ushort(GLint components, GLint widthin, |
||
1820 | GLint heightin, const GLushort *datain, |
||
1821 | GLint widthout, GLint heightout, |
||
1822 | GLushort *dataout, GLint element_size, |
||
1823 | GLint ysize, GLint group_size, |
||
1824 | GLint myswap_bytes) |
||
1825 | { |
||
1826 | float convx; |
||
1827 | float convy; |
||
1828 | float percent; |
||
1829 | /* Max components in a format is 4, so... */ |
||
1830 | float totals[4]; |
||
1831 | float area; |
||
1832 | int i,j,k,xindex; |
||
1833 | |||
1834 | const char *temp, *temp0; |
||
1835 | const char *temp_index; |
||
1836 | int outindex; |
||
1837 | |||
1838 | int lowx_int, highx_int, lowy_int, highy_int; |
||
1839 | float x_percent, y_percent; |
||
1840 | float lowx_float, highx_float, lowy_float, highy_float; |
||
1841 | float convy_float, convx_float; |
||
1842 | int convy_int, convx_int; |
||
1843 | int l, m; |
||
1844 | const char *left, *right; |
||
1845 | |||
1846 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
1847 | halveImage_ushort(components, widthin, heightin, |
||
1848 | (const GLushort *)datain, (GLushort *)dataout, |
||
1849 | element_size, ysize, group_size, myswap_bytes); |
||
1850 | return; |
||
1851 | } |
||
1852 | convy = (float) heightin/heightout; |
||
1853 | convx = (float) widthin/widthout; |
||
1854 | convy_int = floor(convy); |
||
1855 | convy_float = convy - convy_int; |
||
1856 | convx_int = floor(convx); |
||
1857 | convx_float = convx - convx_int; |
||
1858 | |||
1859 | area = convx * convy; |
||
1860 | |||
1861 | lowy_int = 0; |
||
1862 | lowy_float = 0; |
||
1863 | highy_int = convy_int; |
||
1864 | highy_float = convy_float; |
||
1865 | |||
1866 | for (i = 0; i < heightout; i++) { |
||
1867 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
1868 | if (highy_int >= heightin) |
||
1869 | highy_int = heightin - 1; |
||
1870 | lowx_int = 0; |
||
1871 | lowx_float = 0; |
||
1872 | highx_int = convx_int; |
||
1873 | highx_float = convx_float; |
||
1874 | |||
1875 | for (j = 0; j < widthout; j++) { |
||
1876 | /* |
||
1877 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
1878 | ** to (highx, highy) on input data into this pixel on output |
||
1879 | ** data. |
||
1880 | */ |
||
1881 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
1882 | |||
1883 | /* calculate the value for pixels in the 1st row */ |
||
1884 | xindex = lowx_int*group_size; |
||
1885 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
1886 | |||
1887 | y_percent = 1-lowy_float; |
||
1888 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
1889 | percent = y_percent * (1-lowx_float); |
||
1890 | for (k = 0, temp_index = temp; k < components; |
||
1891 | k++, temp_index += element_size) { |
||
1892 | if (myswap_bytes) { |
||
1893 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
1894 | } else { |
||
1895 | totals[k] += *(const GLushort*)temp_index * percent; |
||
1896 | } |
||
1897 | } |
||
1898 | left = temp; |
||
1899 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1900 | temp += group_size; |
||
1901 | for (k = 0, temp_index = temp; k < components; |
||
1902 | k++, temp_index += element_size) { |
||
1903 | if (myswap_bytes) { |
||
1904 | totals[k] += |
||
1905 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
1906 | } else { |
||
1907 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
1908 | } |
||
1909 | } |
||
1910 | } |
||
1911 | temp += group_size; |
||
1912 | right = temp; |
||
1913 | percent = y_percent * highx_float; |
||
1914 | for (k = 0, temp_index = temp; k < components; |
||
1915 | k++, temp_index += element_size) { |
||
1916 | if (myswap_bytes) { |
||
1917 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
1918 | } else { |
||
1919 | totals[k] += *(const GLushort*)temp_index * percent; |
||
1920 | } |
||
1921 | } |
||
1922 | |||
1923 | /* calculate the value for pixels in the last row */ |
||
1924 | y_percent = highy_float; |
||
1925 | percent = y_percent * (1-lowx_float); |
||
1926 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
1927 | for (k = 0, temp_index = temp; k < components; |
||
1928 | k++, temp_index += element_size) { |
||
1929 | if (myswap_bytes) { |
||
1930 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
1931 | } else { |
||
1932 | totals[k] += *(const GLushort*)temp_index * percent; |
||
1933 | } |
||
1934 | } |
||
1935 | for(l = lowx_int+1; l < highx_int; l++) { |
||
1936 | temp += group_size; |
||
1937 | for (k = 0, temp_index = temp; k < components; |
||
1938 | k++, temp_index += element_size) { |
||
1939 | if (myswap_bytes) { |
||
1940 | totals[k] += |
||
1941 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
1942 | } else { |
||
1943 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
1944 | } |
||
1945 | } |
||
1946 | } |
||
1947 | temp += group_size; |
||
1948 | percent = y_percent * highx_float; |
||
1949 | for (k = 0, temp_index = temp; k < components; |
||
1950 | k++, temp_index += element_size) { |
||
1951 | if (myswap_bytes) { |
||
1952 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
1953 | } else { |
||
1954 | totals[k] += *(const GLushort*)temp_index * percent; |
||
1955 | } |
||
1956 | } |
||
1957 | |||
1958 | /* calculate the value for pixels in the 1st and last column */ |
||
1959 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1960 | left += ysize; |
||
1961 | right += ysize; |
||
1962 | for (k = 0; k < components; |
||
1963 | k++, left += element_size, right += element_size) { |
||
1964 | if (myswap_bytes) { |
||
1965 | totals[k] += |
||
1966 | __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + |
||
1967 | __GLU_SWAP_2_BYTES(right) * highx_float; |
||
1968 | } else { |
||
1969 | totals[k] += *(const GLushort*)left * (1-lowx_float) |
||
1970 | + *(const GLushort*)right * highx_float; |
||
1971 | } |
||
1972 | } |
||
1973 | } |
||
1974 | } else if (highy_int > lowy_int) { |
||
1975 | x_percent = highx_float - lowx_float; |
||
1976 | percent = (1-lowy_float)*x_percent; |
||
1977 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
1978 | for (k = 0, temp_index = temp; k < components; |
||
1979 | k++, temp_index += element_size) { |
||
1980 | if (myswap_bytes) { |
||
1981 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
1982 | } else { |
||
1983 | totals[k] += *(const GLushort*)temp_index * percent; |
||
1984 | } |
||
1985 | } |
||
1986 | for(m = lowy_int+1; m < highy_int; m++) { |
||
1987 | temp += ysize; |
||
1988 | for (k = 0, temp_index = temp; k < components; |
||
1989 | k++, temp_index += element_size) { |
||
1990 | if (myswap_bytes) { |
||
1991 | totals[k] += |
||
1992 | __GLU_SWAP_2_BYTES(temp_index) * x_percent; |
||
1993 | } else { |
||
1994 | totals[k] += *(const GLushort*)temp_index * x_percent; |
||
1995 | } |
||
1996 | } |
||
1997 | } |
||
1998 | percent = x_percent * highy_float; |
||
1999 | temp += ysize; |
||
2000 | for (k = 0, temp_index = temp; k < components; |
||
2001 | k++, temp_index += element_size) { |
||
2002 | if (myswap_bytes) { |
||
2003 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
2004 | } else { |
||
2005 | totals[k] += *(const GLushort*)temp_index * percent; |
||
2006 | } |
||
2007 | } |
||
2008 | } else if (highx_int > lowx_int) { |
||
2009 | y_percent = highy_float - lowy_float; |
||
2010 | percent = (1-lowx_float)*y_percent; |
||
2011 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2012 | for (k = 0, temp_index = temp; k < components; |
||
2013 | k++, temp_index += element_size) { |
||
2014 | if (myswap_bytes) { |
||
2015 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
2016 | } else { |
||
2017 | totals[k] += *(const GLushort*)temp_index * percent; |
||
2018 | } |
||
2019 | } |
||
2020 | for (l = lowx_int+1; l < highx_int; l++) { |
||
2021 | temp += group_size; |
||
2022 | for (k = 0, temp_index = temp; k < components; |
||
2023 | k++, temp_index += element_size) { |
||
2024 | if (myswap_bytes) { |
||
2025 | totals[k] += |
||
2026 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
2027 | } else { |
||
2028 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
2029 | } |
||
2030 | } |
||
2031 | } |
||
2032 | temp += group_size; |
||
2033 | percent = y_percent * highx_float; |
||
2034 | for (k = 0, temp_index = temp; k < components; |
||
2035 | k++, temp_index += element_size) { |
||
2036 | if (myswap_bytes) { |
||
2037 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
2038 | } else { |
||
2039 | totals[k] += *(const GLushort*)temp_index * percent; |
||
2040 | } |
||
2041 | } |
||
2042 | } else { |
||
2043 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
2044 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2045 | for (k = 0, temp_index = temp; k < components; |
||
2046 | k++, temp_index += element_size) { |
||
2047 | if (myswap_bytes) { |
||
2048 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
2049 | } else { |
||
2050 | totals[k] += *(const GLushort*)temp_index * percent; |
||
2051 | } |
||
2052 | } |
||
2053 | } |
||
2054 | |||
2055 | /* this is for the pixels in the body */ |
||
2056 | temp0 = (const char *)datain + xindex + group_size + |
||
2057 | (lowy_int+1)*ysize; |
||
2058 | for (m = lowy_int+1; m < highy_int; m++) { |
||
2059 | temp = temp0; |
||
2060 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2061 | for (k = 0, temp_index = temp; k < components; |
||
2062 | k++, temp_index += element_size) { |
||
2063 | if (myswap_bytes) { |
||
2064 | totals[k] += __GLU_SWAP_2_BYTES(temp_index); |
||
2065 | } else { |
||
2066 | totals[k] += *(const GLushort*)temp_index; |
||
2067 | } |
||
2068 | } |
||
2069 | temp += group_size; |
||
2070 | } |
||
2071 | temp0 += ysize; |
||
2072 | } |
||
2073 | |||
2074 | outindex = (j + (i * widthout)) * components; |
||
2075 | for (k = 0; k < components; k++) { |
||
2076 | dataout[outindex + k] = totals[k]/area; |
||
2077 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
2078 | } |
||
2079 | lowx_int = highx_int; |
||
2080 | lowx_float = highx_float; |
||
2081 | highx_int += convx_int; |
||
2082 | highx_float += convx_float; |
||
2083 | if(highx_float > 1) { |
||
2084 | highx_float -= 1.0; |
||
2085 | highx_int++; |
||
2086 | } |
||
2087 | } |
||
2088 | lowy_int = highy_int; |
||
2089 | lowy_float = highy_float; |
||
2090 | highy_int += convy_int; |
||
2091 | highy_float += convy_float; |
||
2092 | if(highy_float > 1) { |
||
2093 | highy_float -= 1.0; |
||
2094 | highy_int++; |
||
2095 | } |
||
2096 | } |
||
2097 | } |
||
2098 | |||
2099 | static void scale_internal_short(GLint components, GLint widthin, |
||
2100 | GLint heightin, const GLshort *datain, |
||
2101 | GLint widthout, GLint heightout, |
||
2102 | GLshort *dataout, GLint element_size, |
||
2103 | GLint ysize, GLint group_size, |
||
2104 | GLint myswap_bytes) |
||
2105 | { |
||
2106 | float convx; |
||
2107 | float convy; |
||
2108 | float percent; |
||
2109 | /* Max components in a format is 4, so... */ |
||
2110 | float totals[4]; |
||
2111 | float area; |
||
2112 | int i,j,k,xindex; |
||
2113 | |||
2114 | const char *temp, *temp0; |
||
2115 | const char *temp_index; |
||
2116 | int outindex; |
||
2117 | |||
2118 | int lowx_int, highx_int, lowy_int, highy_int; |
||
2119 | float x_percent, y_percent; |
||
2120 | float lowx_float, highx_float, lowy_float, highy_float; |
||
2121 | float convy_float, convx_float; |
||
2122 | int convy_int, convx_int; |
||
2123 | int l, m; |
||
2124 | const char *left, *right; |
||
2125 | |||
2126 | GLushort swapbuf; /* unsigned buffer */ |
||
2127 | |||
2128 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
2129 | halveImage_short(components, widthin, heightin, |
||
2130 | (const GLshort *)datain, (GLshort *)dataout, |
||
2131 | element_size, ysize, group_size, myswap_bytes); |
||
2132 | return; |
||
2133 | } |
||
2134 | convy = (float) heightin/heightout; |
||
2135 | convx = (float) widthin/widthout; |
||
2136 | convy_int = floor(convy); |
||
2137 | convy_float = convy - convy_int; |
||
2138 | convx_int = floor(convx); |
||
2139 | convx_float = convx - convx_int; |
||
2140 | |||
2141 | area = convx * convy; |
||
2142 | |||
2143 | lowy_int = 0; |
||
2144 | lowy_float = 0; |
||
2145 | highy_int = convy_int; |
||
2146 | highy_float = convy_float; |
||
2147 | |||
2148 | for (i = 0; i < heightout; i++) { |
||
2149 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
2150 | if (highy_int >= heightin) |
||
2151 | highy_int = heightin - 1; |
||
2152 | lowx_int = 0; |
||
2153 | lowx_float = 0; |
||
2154 | highx_int = convx_int; |
||
2155 | highx_float = convx_float; |
||
2156 | |||
2157 | for (j = 0; j < widthout; j++) { |
||
2158 | /* |
||
2159 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
2160 | ** to (highx, highy) on input data into this pixel on output |
||
2161 | ** data. |
||
2162 | */ |
||
2163 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
2164 | |||
2165 | /* calculate the value for pixels in the 1st row */ |
||
2166 | xindex = lowx_int*group_size; |
||
2167 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
2168 | |||
2169 | y_percent = 1-lowy_float; |
||
2170 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2171 | percent = y_percent * (1-lowx_float); |
||
2172 | for (k = 0, temp_index = temp; k < components; |
||
2173 | k++, temp_index += element_size) { |
||
2174 | if (myswap_bytes) { |
||
2175 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2176 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2177 | } else { |
||
2178 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2179 | } |
||
2180 | } |
||
2181 | left = temp; |
||
2182 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2183 | temp += group_size; |
||
2184 | for (k = 0, temp_index = temp; k < components; |
||
2185 | k++, temp_index += element_size) { |
||
2186 | if (myswap_bytes) { |
||
2187 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2188 | totals[k] += *(const GLshort*)&swapbuf * y_percent; |
||
2189 | } else { |
||
2190 | totals[k] += *(const GLshort*)temp_index * y_percent; |
||
2191 | } |
||
2192 | } |
||
2193 | } |
||
2194 | temp += group_size; |
||
2195 | right = temp; |
||
2196 | percent = y_percent * highx_float; |
||
2197 | for (k = 0, temp_index = temp; k < components; |
||
2198 | k++, temp_index += element_size) { |
||
2199 | if (myswap_bytes) { |
||
2200 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2201 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2202 | } else { |
||
2203 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2204 | } |
||
2205 | } |
||
2206 | |||
2207 | /* calculate the value for pixels in the last row */ |
||
2208 | y_percent = highy_float; |
||
2209 | percent = y_percent * (1-lowx_float); |
||
2210 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
2211 | for (k = 0, temp_index = temp; k < components; |
||
2212 | k++, temp_index += element_size) { |
||
2213 | if (myswap_bytes) { |
||
2214 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2215 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2216 | } else { |
||
2217 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2218 | } |
||
2219 | } |
||
2220 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2221 | temp += group_size; |
||
2222 | for (k = 0, temp_index = temp; k < components; |
||
2223 | k++, temp_index += element_size) { |
||
2224 | if (myswap_bytes) { |
||
2225 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2226 | totals[k] += *(const GLshort*)&swapbuf * y_percent; |
||
2227 | } else { |
||
2228 | totals[k] += *(const GLshort*)temp_index * y_percent; |
||
2229 | } |
||
2230 | } |
||
2231 | } |
||
2232 | temp += group_size; |
||
2233 | percent = y_percent * highx_float; |
||
2234 | for (k = 0, temp_index = temp; k < components; |
||
2235 | k++, temp_index += element_size) { |
||
2236 | if (myswap_bytes) { |
||
2237 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2238 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2239 | } else { |
||
2240 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2241 | } |
||
2242 | } |
||
2243 | |||
2244 | /* calculate the value for pixels in the 1st and last column */ |
||
2245 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2246 | left += ysize; |
||
2247 | right += ysize; |
||
2248 | for (k = 0; k < components; |
||
2249 | k++, left += element_size, right += element_size) { |
||
2250 | if (myswap_bytes) { |
||
2251 | swapbuf = __GLU_SWAP_2_BYTES(left); |
||
2252 | totals[k] += *(const GLshort*)&swapbuf * (1-lowx_float); |
||
2253 | swapbuf = __GLU_SWAP_2_BYTES(right); |
||
2254 | totals[k] += *(const GLshort*)&swapbuf * highx_float; |
||
2255 | } else { |
||
2256 | totals[k] += *(const GLshort*)left * (1-lowx_float) |
||
2257 | + *(const GLshort*)right * highx_float; |
||
2258 | } |
||
2259 | } |
||
2260 | } |
||
2261 | } else if (highy_int > lowy_int) { |
||
2262 | x_percent = highx_float - lowx_float; |
||
2263 | percent = (1-lowy_float)*x_percent; |
||
2264 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2265 | for (k = 0, temp_index = temp; k < components; |
||
2266 | k++, temp_index += element_size) { |
||
2267 | if (myswap_bytes) { |
||
2268 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2269 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2270 | } else { |
||
2271 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2272 | } |
||
2273 | } |
||
2274 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2275 | temp += ysize; |
||
2276 | for (k = 0, temp_index = temp; k < components; |
||
2277 | k++, temp_index += element_size) { |
||
2278 | if (myswap_bytes) { |
||
2279 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2280 | totals[k] += *(const GLshort*)&swapbuf * x_percent; |
||
2281 | } else { |
||
2282 | totals[k] += *(const GLshort*)temp_index * x_percent; |
||
2283 | } |
||
2284 | } |
||
2285 | } |
||
2286 | percent = x_percent * highy_float; |
||
2287 | temp += ysize; |
||
2288 | for (k = 0, temp_index = temp; k < components; |
||
2289 | k++, temp_index += element_size) { |
||
2290 | if (myswap_bytes) { |
||
2291 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2292 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2293 | } else { |
||
2294 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2295 | } |
||
2296 | } |
||
2297 | } else if (highx_int > lowx_int) { |
||
2298 | y_percent = highy_float - lowy_float; |
||
2299 | percent = (1-lowx_float)*y_percent; |
||
2300 | |||
2301 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2302 | for (k = 0, temp_index = temp; k < components; |
||
2303 | k++, temp_index += element_size) { |
||
2304 | if (myswap_bytes) { |
||
2305 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2306 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2307 | } else { |
||
2308 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2309 | } |
||
2310 | } |
||
2311 | for (l = lowx_int+1; l < highx_int; l++) { |
||
2312 | temp += group_size; |
||
2313 | for (k = 0, temp_index = temp; k < components; |
||
2314 | k++, temp_index += element_size) { |
||
2315 | if (myswap_bytes) { |
||
2316 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2317 | totals[k] += *(const GLshort*)&swapbuf * y_percent; |
||
2318 | } else { |
||
2319 | totals[k] += *(const GLshort*)temp_index * y_percent; |
||
2320 | } |
||
2321 | } |
||
2322 | } |
||
2323 | temp += group_size; |
||
2324 | percent = y_percent * highx_float; |
||
2325 | for (k = 0, temp_index = temp; k < components; |
||
2326 | k++, temp_index += element_size) { |
||
2327 | if (myswap_bytes) { |
||
2328 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2329 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2330 | } else { |
||
2331 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2332 | } |
||
2333 | } |
||
2334 | } else { |
||
2335 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
2336 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2337 | for (k = 0, temp_index = temp; k < components; |
||
2338 | k++, temp_index += element_size) { |
||
2339 | if (myswap_bytes) { |
||
2340 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2341 | totals[k] += *(const GLshort*)&swapbuf * percent; |
||
2342 | } else { |
||
2343 | totals[k] += *(const GLshort*)temp_index * percent; |
||
2344 | } |
||
2345 | } |
||
2346 | } |
||
2347 | |||
2348 | /* this is for the pixels in the body */ |
||
2349 | temp0 = (const char *)datain + xindex + group_size + |
||
2350 | (lowy_int+1)*ysize; |
||
2351 | for (m = lowy_int+1; m < highy_int; m++) { |
||
2352 | temp = temp0; |
||
2353 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2354 | for (k = 0, temp_index = temp; k < components; |
||
2355 | k++, temp_index += element_size) { |
||
2356 | if (myswap_bytes) { |
||
2357 | swapbuf = __GLU_SWAP_2_BYTES(temp_index); |
||
2358 | totals[k] += *(const GLshort*)&swapbuf; |
||
2359 | } else { |
||
2360 | totals[k] += *(const GLshort*)temp_index; |
||
2361 | } |
||
2362 | } |
||
2363 | temp += group_size; |
||
2364 | } |
||
2365 | temp0 += ysize; |
||
2366 | } |
||
2367 | |||
2368 | outindex = (j + (i * widthout)) * components; |
||
2369 | for (k = 0; k < components; k++) { |
||
2370 | dataout[outindex + k] = totals[k]/area; |
||
2371 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
2372 | } |
||
2373 | lowx_int = highx_int; |
||
2374 | lowx_float = highx_float; |
||
2375 | highx_int += convx_int; |
||
2376 | highx_float += convx_float; |
||
2377 | if(highx_float > 1) { |
||
2378 | highx_float -= 1.0; |
||
2379 | highx_int++; |
||
2380 | } |
||
2381 | } |
||
2382 | lowy_int = highy_int; |
||
2383 | lowy_float = highy_float; |
||
2384 | highy_int += convy_int; |
||
2385 | highy_float += convy_float; |
||
2386 | if(highy_float > 1) { |
||
2387 | highy_float -= 1.0; |
||
2388 | highy_int++; |
||
2389 | } |
||
2390 | } |
||
2391 | } |
||
2392 | |||
2393 | static void scale_internal_uint(GLint components, GLint widthin, |
||
2394 | GLint heightin, const GLuint *datain, |
||
2395 | GLint widthout, GLint heightout, |
||
2396 | GLuint *dataout, GLint element_size, |
||
2397 | GLint ysize, GLint group_size, |
||
2398 | GLint myswap_bytes) |
||
2399 | { |
||
2400 | float convx; |
||
2401 | float convy; |
||
2402 | float percent; |
||
2403 | /* Max components in a format is 4, so... */ |
||
2404 | float totals[4]; |
||
2405 | float area; |
||
2406 | int i,j,k,xindex; |
||
2407 | |||
2408 | const char *temp, *temp0; |
||
2409 | const char *temp_index; |
||
2410 | int outindex; |
||
2411 | |||
2412 | int lowx_int, highx_int, lowy_int, highy_int; |
||
2413 | float x_percent, y_percent; |
||
2414 | float lowx_float, highx_float, lowy_float, highy_float; |
||
2415 | float convy_float, convx_float; |
||
2416 | int convy_int, convx_int; |
||
2417 | int l, m; |
||
2418 | const char *left, *right; |
||
2419 | |||
2420 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
2421 | halveImage_uint(components, widthin, heightin, |
||
2422 | (const GLuint *)datain, (GLuint *)dataout, |
||
2423 | element_size, ysize, group_size, myswap_bytes); |
||
2424 | return; |
||
2425 | } |
||
2426 | convy = (float) heightin/heightout; |
||
2427 | convx = (float) widthin/widthout; |
||
2428 | convy_int = floor(convy); |
||
2429 | convy_float = convy - convy_int; |
||
2430 | convx_int = floor(convx); |
||
2431 | convx_float = convx - convx_int; |
||
2432 | |||
2433 | area = convx * convy; |
||
2434 | |||
2435 | lowy_int = 0; |
||
2436 | lowy_float = 0; |
||
2437 | highy_int = convy_int; |
||
2438 | highy_float = convy_float; |
||
2439 | |||
2440 | for (i = 0; i < heightout; i++) { |
||
2441 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
2442 | if (highy_int >= heightin) |
||
2443 | highy_int = heightin - 1; |
||
2444 | lowx_int = 0; |
||
2445 | lowx_float = 0; |
||
2446 | highx_int = convx_int; |
||
2447 | highx_float = convx_float; |
||
2448 | |||
2449 | for (j = 0; j < widthout; j++) { |
||
2450 | /* |
||
2451 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
2452 | ** to (highx, highy) on input data into this pixel on output |
||
2453 | ** data. |
||
2454 | */ |
||
2455 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
2456 | |||
2457 | /* calculate the value for pixels in the 1st row */ |
||
2458 | xindex = lowx_int*group_size; |
||
2459 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
2460 | |||
2461 | y_percent = 1-lowy_float; |
||
2462 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2463 | percent = y_percent * (1-lowx_float); |
||
2464 | for (k = 0, temp_index = temp; k < components; |
||
2465 | k++, temp_index += element_size) { |
||
2466 | if (myswap_bytes) { |
||
2467 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2468 | } else { |
||
2469 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2470 | } |
||
2471 | } |
||
2472 | left = temp; |
||
2473 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2474 | temp += group_size; |
||
2475 | for (k = 0, temp_index = temp; k < components; |
||
2476 | k++, temp_index += element_size) { |
||
2477 | if (myswap_bytes) { |
||
2478 | totals[k] += |
||
2479 | __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
||
2480 | } else { |
||
2481 | totals[k] += *(const GLuint*)temp_index * y_percent; |
||
2482 | } |
||
2483 | } |
||
2484 | } |
||
2485 | temp += group_size; |
||
2486 | right = temp; |
||
2487 | percent = y_percent * highx_float; |
||
2488 | for (k = 0, temp_index = temp; k < components; |
||
2489 | k++, temp_index += element_size) { |
||
2490 | if (myswap_bytes) { |
||
2491 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2492 | } else { |
||
2493 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2494 | } |
||
2495 | } |
||
2496 | |||
2497 | /* calculate the value for pixels in the last row */ |
||
2498 | y_percent = highy_float; |
||
2499 | percent = y_percent * (1-lowx_float); |
||
2500 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
2501 | for (k = 0, temp_index = temp; k < components; |
||
2502 | k++, temp_index += element_size) { |
||
2503 | if (myswap_bytes) { |
||
2504 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2505 | } else { |
||
2506 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2507 | } |
||
2508 | } |
||
2509 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2510 | temp += group_size; |
||
2511 | for (k = 0, temp_index = temp; k < components; |
||
2512 | k++, temp_index += element_size) { |
||
2513 | if (myswap_bytes) { |
||
2514 | totals[k] += |
||
2515 | __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
||
2516 | } else { |
||
2517 | totals[k] += *(const GLuint*)temp_index * y_percent; |
||
2518 | } |
||
2519 | } |
||
2520 | } |
||
2521 | temp += group_size; |
||
2522 | percent = y_percent * highx_float; |
||
2523 | for (k = 0, temp_index = temp; k < components; |
||
2524 | k++, temp_index += element_size) { |
||
2525 | if (myswap_bytes) { |
||
2526 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2527 | } else { |
||
2528 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2529 | } |
||
2530 | } |
||
2531 | |||
2532 | /* calculate the value for pixels in the 1st and last column */ |
||
2533 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2534 | left += ysize; |
||
2535 | right += ysize; |
||
2536 | for (k = 0; k < components; |
||
2537 | k++, left += element_size, right += element_size) { |
||
2538 | if (myswap_bytes) { |
||
2539 | totals[k] += |
||
2540 | __GLU_SWAP_4_BYTES(left) * (1-lowx_float) |
||
2541 | + __GLU_SWAP_4_BYTES(right) * highx_float; |
||
2542 | } else { |
||
2543 | totals[k] += *(const GLuint*)left * (1-lowx_float) |
||
2544 | + *(const GLuint*)right * highx_float; |
||
2545 | } |
||
2546 | } |
||
2547 | } |
||
2548 | } else if (highy_int > lowy_int) { |
||
2549 | x_percent = highx_float - lowx_float; |
||
2550 | percent = (1-lowy_float)*x_percent; |
||
2551 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2552 | for (k = 0, temp_index = temp; k < components; |
||
2553 | k++, temp_index += element_size) { |
||
2554 | if (myswap_bytes) { |
||
2555 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2556 | } else { |
||
2557 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2558 | } |
||
2559 | } |
||
2560 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2561 | temp += ysize; |
||
2562 | for (k = 0, temp_index = temp; k < components; |
||
2563 | k++, temp_index += element_size) { |
||
2564 | if (myswap_bytes) { |
||
2565 | totals[k] += |
||
2566 | __GLU_SWAP_4_BYTES(temp_index) * x_percent; |
||
2567 | } else { |
||
2568 | totals[k] += *(const GLuint*)temp_index * x_percent; |
||
2569 | } |
||
2570 | } |
||
2571 | } |
||
2572 | percent = x_percent * highy_float; |
||
2573 | temp += ysize; |
||
2574 | for (k = 0, temp_index = temp; k < components; |
||
2575 | k++, temp_index += element_size) { |
||
2576 | if (myswap_bytes) { |
||
2577 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2578 | } else { |
||
2579 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2580 | } |
||
2581 | } |
||
2582 | } else if (highx_int > lowx_int) { |
||
2583 | y_percent = highy_float - lowy_float; |
||
2584 | percent = (1-lowx_float)*y_percent; |
||
2585 | |||
2586 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2587 | for (k = 0, temp_index = temp; k < components; |
||
2588 | k++, temp_index += element_size) { |
||
2589 | if (myswap_bytes) { |
||
2590 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2591 | } else { |
||
2592 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2593 | } |
||
2594 | } |
||
2595 | for (l = lowx_int+1; l < highx_int; l++) { |
||
2596 | temp += group_size; |
||
2597 | for (k = 0, temp_index = temp; k < components; |
||
2598 | k++, temp_index += element_size) { |
||
2599 | if (myswap_bytes) { |
||
2600 | totals[k] += |
||
2601 | __GLU_SWAP_4_BYTES(temp_index) * y_percent; |
||
2602 | } else { |
||
2603 | totals[k] += *(const GLuint*)temp_index * y_percent; |
||
2604 | } |
||
2605 | } |
||
2606 | } |
||
2607 | temp += group_size; |
||
2608 | percent = y_percent * highx_float; |
||
2609 | for (k = 0, temp_index = temp; k < components; |
||
2610 | k++, temp_index += element_size) { |
||
2611 | if (myswap_bytes) { |
||
2612 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2613 | } else { |
||
2614 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2615 | } |
||
2616 | } |
||
2617 | } else { |
||
2618 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
2619 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2620 | for (k = 0, temp_index = temp; k < components; |
||
2621 | k++, temp_index += element_size) { |
||
2622 | if (myswap_bytes) { |
||
2623 | totals[k] += __GLU_SWAP_4_BYTES(temp_index) * percent; |
||
2624 | } else { |
||
2625 | totals[k] += *(const GLuint*)temp_index * percent; |
||
2626 | } |
||
2627 | } |
||
2628 | } |
||
2629 | |||
2630 | /* this is for the pixels in the body */ |
||
2631 | temp0 = (const char *)datain + xindex + group_size + |
||
2632 | (lowy_int+1)*ysize; |
||
2633 | for (m = lowy_int+1; m < highy_int; m++) { |
||
2634 | temp = temp0; |
||
2635 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2636 | for (k = 0, temp_index = temp; k < components; |
||
2637 | k++, temp_index += element_size) { |
||
2638 | if (myswap_bytes) { |
||
2639 | totals[k] += __GLU_SWAP_4_BYTES(temp_index); |
||
2640 | } else { |
||
2641 | totals[k] += *(const GLuint*)temp_index; |
||
2642 | } |
||
2643 | } |
||
2644 | temp += group_size; |
||
2645 | } |
||
2646 | temp0 += ysize; |
||
2647 | } |
||
2648 | |||
2649 | outindex = (j + (i * widthout)) * components; |
||
2650 | for (k = 0; k < components; k++) { |
||
2651 | /* clamp at UINT_MAX */ |
||
2652 | float value= totals[k]/area; |
||
2653 | if (value >= (float) UINT_MAX) { /* need '=' */ |
||
2654 | dataout[outindex + k] = UINT_MAX; |
||
2655 | } |
||
2656 | else dataout[outindex + k] = value; |
||
2657 | } |
||
2658 | lowx_int = highx_int; |
||
2659 | lowx_float = highx_float; |
||
2660 | highx_int += convx_int; |
||
2661 | highx_float += convx_float; |
||
2662 | if(highx_float > 1) { |
||
2663 | highx_float -= 1.0; |
||
2664 | highx_int++; |
||
2665 | } |
||
2666 | } |
||
2667 | lowy_int = highy_int; |
||
2668 | lowy_float = highy_float; |
||
2669 | highy_int += convy_int; |
||
2670 | highy_float += convy_float; |
||
2671 | if(highy_float > 1) { |
||
2672 | highy_float -= 1.0; |
||
2673 | highy_int++; |
||
2674 | } |
||
2675 | } |
||
2676 | } |
||
2677 | |||
2678 | |||
2679 | |||
2680 | static void scale_internal_int(GLint components, GLint widthin, |
||
2681 | GLint heightin, const GLint *datain, |
||
2682 | GLint widthout, GLint heightout, |
||
2683 | GLint *dataout, GLint element_size, |
||
2684 | GLint ysize, GLint group_size, |
||
2685 | GLint myswap_bytes) |
||
2686 | { |
||
2687 | float convx; |
||
2688 | float convy; |
||
2689 | float percent; |
||
2690 | /* Max components in a format is 4, so... */ |
||
2691 | float totals[4]; |
||
2692 | float area; |
||
2693 | int i,j,k,xindex; |
||
2694 | |||
2695 | const char *temp, *temp0; |
||
2696 | const char *temp_index; |
||
2697 | int outindex; |
||
2698 | |||
2699 | int lowx_int, highx_int, lowy_int, highy_int; |
||
2700 | float x_percent, y_percent; |
||
2701 | float lowx_float, highx_float, lowy_float, highy_float; |
||
2702 | float convy_float, convx_float; |
||
2703 | int convy_int, convx_int; |
||
2704 | int l, m; |
||
2705 | const char *left, *right; |
||
2706 | |||
2707 | GLuint swapbuf; /* unsigned buffer */ |
||
2708 | |||
2709 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
2710 | halveImage_int(components, widthin, heightin, |
||
2711 | (const GLint *)datain, (GLint *)dataout, |
||
2712 | element_size, ysize, group_size, myswap_bytes); |
||
2713 | return; |
||
2714 | } |
||
2715 | convy = (float) heightin/heightout; |
||
2716 | convx = (float) widthin/widthout; |
||
2717 | convy_int = floor(convy); |
||
2718 | convy_float = convy - convy_int; |
||
2719 | convx_int = floor(convx); |
||
2720 | convx_float = convx - convx_int; |
||
2721 | |||
2722 | area = convx * convy; |
||
2723 | |||
2724 | lowy_int = 0; |
||
2725 | lowy_float = 0; |
||
2726 | highy_int = convy_int; |
||
2727 | highy_float = convy_float; |
||
2728 | |||
2729 | for (i = 0; i < heightout; i++) { |
||
2730 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
2731 | if (highy_int >= heightin) |
||
2732 | highy_int = heightin - 1; |
||
2733 | lowx_int = 0; |
||
2734 | lowx_float = 0; |
||
2735 | highx_int = convx_int; |
||
2736 | highx_float = convx_float; |
||
2737 | |||
2738 | for (j = 0; j < widthout; j++) { |
||
2739 | /* |
||
2740 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
2741 | ** to (highx, highy) on input data into this pixel on output |
||
2742 | ** data. |
||
2743 | */ |
||
2744 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
2745 | |||
2746 | /* calculate the value for pixels in the 1st row */ |
||
2747 | xindex = lowx_int*group_size; |
||
2748 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
2749 | |||
2750 | y_percent = 1-lowy_float; |
||
2751 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2752 | percent = y_percent * (1-lowx_float); |
||
2753 | for (k = 0, temp_index = temp; k < components; |
||
2754 | k++, temp_index += element_size) { |
||
2755 | if (myswap_bytes) { |
||
2756 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2757 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2758 | } else { |
||
2759 | totals[k] += *(const GLint*)temp_index * percent; |
||
2760 | } |
||
2761 | } |
||
2762 | left = temp; |
||
2763 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2764 | temp += group_size; |
||
2765 | for (k = 0, temp_index = temp; k < components; |
||
2766 | k++, temp_index += element_size) { |
||
2767 | if (myswap_bytes) { |
||
2768 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2769 | totals[k] += *(const GLint*)&swapbuf * y_percent; |
||
2770 | } else { |
||
2771 | totals[k] += *(const GLint*)temp_index * y_percent; |
||
2772 | } |
||
2773 | } |
||
2774 | } |
||
2775 | temp += group_size; |
||
2776 | right = temp; |
||
2777 | percent = y_percent * highx_float; |
||
2778 | for (k = 0, temp_index = temp; k < components; |
||
2779 | k++, temp_index += element_size) { |
||
2780 | if (myswap_bytes) { |
||
2781 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2782 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2783 | } else { |
||
2784 | totals[k] += *(const GLint*)temp_index * percent; |
||
2785 | } |
||
2786 | } |
||
2787 | |||
2788 | /* calculate the value for pixels in the last row */ |
||
2789 | y_percent = highy_float; |
||
2790 | percent = y_percent * (1-lowx_float); |
||
2791 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
2792 | for (k = 0, temp_index = temp; k < components; |
||
2793 | k++, temp_index += element_size) { |
||
2794 | if (myswap_bytes) { |
||
2795 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2796 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2797 | } else { |
||
2798 | totals[k] += *(const GLint*)temp_index * percent; |
||
2799 | } |
||
2800 | } |
||
2801 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2802 | temp += group_size; |
||
2803 | for (k = 0, temp_index = temp; k < components; |
||
2804 | k++, temp_index += element_size) { |
||
2805 | if (myswap_bytes) { |
||
2806 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2807 | totals[k] += *(const GLint*)&swapbuf * y_percent; |
||
2808 | } else { |
||
2809 | totals[k] += *(const GLint*)temp_index * y_percent; |
||
2810 | } |
||
2811 | } |
||
2812 | } |
||
2813 | temp += group_size; |
||
2814 | percent = y_percent * highx_float; |
||
2815 | for (k = 0, temp_index = temp; k < components; |
||
2816 | k++, temp_index += element_size) { |
||
2817 | if (myswap_bytes) { |
||
2818 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2819 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2820 | } else { |
||
2821 | totals[k] += *(const GLint*)temp_index * percent; |
||
2822 | } |
||
2823 | } |
||
2824 | |||
2825 | /* calculate the value for pixels in the 1st and last column */ |
||
2826 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2827 | left += ysize; |
||
2828 | right += ysize; |
||
2829 | for (k = 0; k < components; |
||
2830 | k++, left += element_size, right += element_size) { |
||
2831 | if (myswap_bytes) { |
||
2832 | swapbuf = __GLU_SWAP_4_BYTES(left); |
||
2833 | totals[k] += *(const GLint*)&swapbuf * (1-lowx_float); |
||
2834 | swapbuf = __GLU_SWAP_4_BYTES(right); |
||
2835 | totals[k] += *(const GLint*)&swapbuf * highx_float; |
||
2836 | } else { |
||
2837 | totals[k] += *(const GLint*)left * (1-lowx_float) |
||
2838 | + *(const GLint*)right * highx_float; |
||
2839 | } |
||
2840 | } |
||
2841 | } |
||
2842 | } else if (highy_int > lowy_int) { |
||
2843 | x_percent = highx_float - lowx_float; |
||
2844 | percent = (1-lowy_float)*x_percent; |
||
2845 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2846 | for (k = 0, temp_index = temp; k < components; |
||
2847 | k++, temp_index += element_size) { |
||
2848 | if (myswap_bytes) { |
||
2849 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2850 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2851 | } else { |
||
2852 | totals[k] += *(const GLint*)temp_index * percent; |
||
2853 | } |
||
2854 | } |
||
2855 | for(m = lowy_int+1; m < highy_int; m++) { |
||
2856 | temp += ysize; |
||
2857 | for (k = 0, temp_index = temp; k < components; |
||
2858 | k++, temp_index += element_size) { |
||
2859 | if (myswap_bytes) { |
||
2860 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2861 | totals[k] += *(const GLint*)&swapbuf * x_percent; |
||
2862 | } else { |
||
2863 | totals[k] += *(const GLint*)temp_index * x_percent; |
||
2864 | } |
||
2865 | } |
||
2866 | } |
||
2867 | percent = x_percent * highy_float; |
||
2868 | temp += ysize; |
||
2869 | for (k = 0, temp_index = temp; k < components; |
||
2870 | k++, temp_index += element_size) { |
||
2871 | if (myswap_bytes) { |
||
2872 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2873 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2874 | } else { |
||
2875 | totals[k] += *(const GLint*)temp_index * percent; |
||
2876 | } |
||
2877 | } |
||
2878 | } else if (highx_int > lowx_int) { |
||
2879 | y_percent = highy_float - lowy_float; |
||
2880 | percent = (1-lowx_float)*y_percent; |
||
2881 | |||
2882 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
2883 | for (k = 0, temp_index = temp; k < components; |
||
2884 | k++, temp_index += element_size) { |
||
2885 | if (myswap_bytes) { |
||
2886 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2887 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2888 | } else { |
||
2889 | totals[k] += *(const GLint*)temp_index * percent; |
||
2890 | } |
||
2891 | } |
||
2892 | for (l = lowx_int+1; l < highx_int; l++) { |
||
2893 | temp += group_size; |
||
2894 | for (k = 0, temp_index = temp; k < components; |
||
2895 | k++, temp_index += element_size) { |
||
2896 | if (myswap_bytes) { |
||
2897 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2898 | totals[k] += *(const GLint*)&swapbuf * y_percent; |
||
2899 | } else { |
||
2900 | totals[k] += *(const GLint*)temp_index * y_percent; |
||
2901 | } |
||
2902 | } |
||
2903 | } |
||
2904 | temp += group_size; |
||
2905 | percent = y_percent * highx_float; |
||
2906 | for (k = 0, temp_index = temp; k < components; |
||
2907 | k++, temp_index += element_size) { |
||
2908 | if (myswap_bytes) { |
||
2909 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2910 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2911 | } else { |
||
2912 | totals[k] += *(const GLint*)temp_index * percent; |
||
2913 | } |
||
2914 | } |
||
2915 | } else { |
||
2916 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
2917 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
2918 | for (k = 0, temp_index = temp; k < components; |
||
2919 | k++, temp_index += element_size) { |
||
2920 | if (myswap_bytes) { |
||
2921 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2922 | totals[k] += *(const GLint*)&swapbuf * percent; |
||
2923 | } else { |
||
2924 | totals[k] += *(const GLint*)temp_index * percent; |
||
2925 | } |
||
2926 | } |
||
2927 | } |
||
2928 | |||
2929 | /* this is for the pixels in the body */ |
||
2930 | temp0 = (const char *)datain + xindex + group_size + |
||
2931 | (lowy_int+1)*ysize; |
||
2932 | for (m = lowy_int+1; m < highy_int; m++) { |
||
2933 | temp = temp0; |
||
2934 | for(l = lowx_int+1; l < highx_int; l++) { |
||
2935 | for (k = 0, temp_index = temp; k < components; |
||
2936 | k++, temp_index += element_size) { |
||
2937 | if (myswap_bytes) { |
||
2938 | swapbuf = __GLU_SWAP_4_BYTES(temp_index); |
||
2939 | totals[k] += *(const GLint*)&swapbuf; |
||
2940 | } else { |
||
2941 | totals[k] += *(const GLint*)temp_index; |
||
2942 | } |
||
2943 | } |
||
2944 | temp += group_size; |
||
2945 | } |
||
2946 | temp0 += ysize; |
||
2947 | } |
||
2948 | |||
2949 | outindex = (j + (i * widthout)) * components; |
||
2950 | for (k = 0; k < components; k++) { |
||
2951 | dataout[outindex + k] = totals[k]/area; |
||
2952 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
2953 | } |
||
2954 | lowx_int = highx_int; |
||
2955 | lowx_float = highx_float; |
||
2956 | highx_int += convx_int; |
||
2957 | highx_float += convx_float; |
||
2958 | if(highx_float > 1) { |
||
2959 | highx_float -= 1.0; |
||
2960 | highx_int++; |
||
2961 | } |
||
2962 | } |
||
2963 | lowy_int = highy_int; |
||
2964 | lowy_float = highy_float; |
||
2965 | highy_int += convy_int; |
||
2966 | highy_float += convy_float; |
||
2967 | if(highy_float > 1) { |
||
2968 | highy_float -= 1.0; |
||
2969 | highy_int++; |
||
2970 | } |
||
2971 | } |
||
2972 | } |
||
2973 | |||
2974 | |||
2975 | |||
2976 | static void scale_internal_float(GLint components, GLint widthin, |
||
2977 | GLint heightin, const GLfloat *datain, |
||
2978 | GLint widthout, GLint heightout, |
||
2979 | GLfloat *dataout, GLint element_size, |
||
2980 | GLint ysize, GLint group_size, |
||
2981 | GLint myswap_bytes) |
||
2982 | { |
||
2983 | float convx; |
||
2984 | float convy; |
||
2985 | float percent; |
||
2986 | /* Max components in a format is 4, so... */ |
||
2987 | float totals[4]; |
||
2988 | float area; |
||
2989 | int i,j,k,xindex; |
||
2990 | |||
2991 | const char *temp, *temp0; |
||
2992 | const char *temp_index; |
||
2993 | int outindex; |
||
2994 | |||
2995 | int lowx_int, highx_int, lowy_int, highy_int; |
||
2996 | float x_percent, y_percent; |
||
2997 | float lowx_float, highx_float, lowy_float, highy_float; |
||
2998 | float convy_float, convx_float; |
||
2999 | int convy_int, convx_int; |
||
3000 | int l, m; |
||
3001 | const char *left, *right; |
||
3002 | |||
3003 | union { GLuint b; GLfloat f; } swapbuf; |
||
3004 | |||
3005 | if (widthin == widthout*2 && heightin == heightout*2) { |
||
3006 | halveImage_float(components, widthin, heightin, |
||
3007 | (const GLfloat *)datain, (GLfloat *)dataout, |
||
3008 | element_size, ysize, group_size, myswap_bytes); |
||
3009 | return; |
||
3010 | } |
||
3011 | convy = (float) heightin/heightout; |
||
3012 | convx = (float) widthin/widthout; |
||
3013 | convy_int = floor(convy); |
||
3014 | convy_float = convy - convy_int; |
||
3015 | convx_int = floor(convx); |
||
3016 | convx_float = convx - convx_int; |
||
3017 | |||
3018 | area = convx * convy; |
||
3019 | |||
3020 | lowy_int = 0; |
||
3021 | lowy_float = 0; |
||
3022 | highy_int = convy_int; |
||
3023 | highy_float = convy_float; |
||
3024 | |||
3025 | for (i = 0; i < heightout; i++) { |
||
3026 | /* Clamp here to be sure we don't read beyond input buffer. */ |
||
3027 | if (highy_int >= heightin) |
||
3028 | highy_int = heightin - 1; |
||
3029 | lowx_int = 0; |
||
3030 | lowx_float = 0; |
||
3031 | highx_int = convx_int; |
||
3032 | highx_float = convx_float; |
||
3033 | |||
3034 | for (j = 0; j < widthout; j++) { |
||
3035 | /* |
||
3036 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
3037 | ** to (highx, highy) on input data into this pixel on output |
||
3038 | ** data. |
||
3039 | */ |
||
3040 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
3041 | |||
3042 | /* calculate the value for pixels in the 1st row */ |
||
3043 | xindex = lowx_int*group_size; |
||
3044 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
3045 | |||
3046 | y_percent = 1-lowy_float; |
||
3047 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
3048 | percent = y_percent * (1-lowx_float); |
||
3049 | for (k = 0, temp_index = temp; k < components; |
||
3050 | k++, temp_index += element_size) { |
||
3051 | if (myswap_bytes) { |
||
3052 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3053 | totals[k] += swapbuf.f * percent; |
||
3054 | } else { |
||
3055 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3056 | } |
||
3057 | } |
||
3058 | left = temp; |
||
3059 | for(l = lowx_int+1; l < highx_int; l++) { |
||
3060 | temp += group_size; |
||
3061 | for (k = 0, temp_index = temp; k < components; |
||
3062 | k++, temp_index += element_size) { |
||
3063 | if (myswap_bytes) { |
||
3064 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3065 | totals[k] += swapbuf.f * y_percent; |
||
3066 | } else { |
||
3067 | totals[k] += *(const GLfloat*)temp_index * y_percent; |
||
3068 | } |
||
3069 | } |
||
3070 | } |
||
3071 | temp += group_size; |
||
3072 | right = temp; |
||
3073 | percent = y_percent * highx_float; |
||
3074 | for (k = 0, temp_index = temp; k < components; |
||
3075 | k++, temp_index += element_size) { |
||
3076 | if (myswap_bytes) { |
||
3077 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3078 | totals[k] += swapbuf.f * percent; |
||
3079 | } else { |
||
3080 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3081 | } |
||
3082 | } |
||
3083 | |||
3084 | /* calculate the value for pixels in the last row */ |
||
3085 | y_percent = highy_float; |
||
3086 | percent = y_percent * (1-lowx_float); |
||
3087 | temp = (const char *)datain + xindex + highy_int * ysize; |
||
3088 | for (k = 0, temp_index = temp; k < components; |
||
3089 | k++, temp_index += element_size) { |
||
3090 | if (myswap_bytes) { |
||
3091 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3092 | totals[k] += swapbuf.f * percent; |
||
3093 | } else { |
||
3094 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3095 | } |
||
3096 | } |
||
3097 | for(l = lowx_int+1; l < highx_int; l++) { |
||
3098 | temp += group_size; |
||
3099 | for (k = 0, temp_index = temp; k < components; |
||
3100 | k++, temp_index += element_size) { |
||
3101 | if (myswap_bytes) { |
||
3102 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3103 | totals[k] += swapbuf.f * y_percent; |
||
3104 | } else { |
||
3105 | totals[k] += *(const GLfloat*)temp_index * y_percent; |
||
3106 | } |
||
3107 | } |
||
3108 | } |
||
3109 | temp += group_size; |
||
3110 | percent = y_percent * highx_float; |
||
3111 | for (k = 0, temp_index = temp; k < components; |
||
3112 | k++, temp_index += element_size) { |
||
3113 | if (myswap_bytes) { |
||
3114 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3115 | totals[k] += swapbuf.f * percent; |
||
3116 | } else { |
||
3117 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3118 | } |
||
3119 | } |
||
3120 | |||
3121 | /* calculate the value for pixels in the 1st and last column */ |
||
3122 | for(m = lowy_int+1; m < highy_int; m++) { |
||
3123 | left += ysize; |
||
3124 | right += ysize; |
||
3125 | for (k = 0; k < components; |
||
3126 | k++, left += element_size, right += element_size) { |
||
3127 | if (myswap_bytes) { |
||
3128 | swapbuf.b = __GLU_SWAP_4_BYTES(left); |
||
3129 | totals[k] += swapbuf.f * (1-lowx_float); |
||
3130 | swapbuf.b = __GLU_SWAP_4_BYTES(right); |
||
3131 | totals[k] += swapbuf.f * highx_float; |
||
3132 | } else { |
||
3133 | totals[k] += *(const GLfloat*)left * (1-lowx_float) |
||
3134 | + *(const GLfloat*)right * highx_float; |
||
3135 | } |
||
3136 | } |
||
3137 | } |
||
3138 | } else if (highy_int > lowy_int) { |
||
3139 | x_percent = highx_float - lowx_float; |
||
3140 | percent = (1-lowy_float)*x_percent; |
||
3141 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
3142 | for (k = 0, temp_index = temp; k < components; |
||
3143 | k++, temp_index += element_size) { |
||
3144 | if (myswap_bytes) { |
||
3145 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3146 | totals[k] += swapbuf.f * percent; |
||
3147 | } else { |
||
3148 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3149 | } |
||
3150 | } |
||
3151 | for(m = lowy_int+1; m < highy_int; m++) { |
||
3152 | temp += ysize; |
||
3153 | for (k = 0, temp_index = temp; k < components; |
||
3154 | k++, temp_index += element_size) { |
||
3155 | if (myswap_bytes) { |
||
3156 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3157 | totals[k] += swapbuf.f * x_percent; |
||
3158 | } else { |
||
3159 | totals[k] += *(const GLfloat*)temp_index * x_percent; |
||
3160 | } |
||
3161 | } |
||
3162 | } |
||
3163 | percent = x_percent * highy_float; |
||
3164 | temp += ysize; |
||
3165 | for (k = 0, temp_index = temp; k < components; |
||
3166 | k++, temp_index += element_size) { |
||
3167 | if (myswap_bytes) { |
||
3168 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3169 | totals[k] += swapbuf.f * percent; |
||
3170 | } else { |
||
3171 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3172 | } |
||
3173 | } |
||
3174 | } else if (highx_int > lowx_int) { |
||
3175 | y_percent = highy_float - lowy_float; |
||
3176 | percent = (1-lowx_float)*y_percent; |
||
3177 | |||
3178 | temp = (const char *)datain + xindex + lowy_int*ysize; |
||
3179 | for (k = 0, temp_index = temp; k < components; |
||
3180 | k++, temp_index += element_size) { |
||
3181 | if (myswap_bytes) { |
||
3182 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3183 | totals[k] += swapbuf.f * percent; |
||
3184 | } else { |
||
3185 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3186 | } |
||
3187 | } |
||
3188 | for (l = lowx_int+1; l < highx_int; l++) { |
||
3189 | temp += group_size; |
||
3190 | for (k = 0, temp_index = temp; k < components; |
||
3191 | k++, temp_index += element_size) { |
||
3192 | if (myswap_bytes) { |
||
3193 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3194 | totals[k] += swapbuf.f * y_percent; |
||
3195 | } else { |
||
3196 | totals[k] += *(const GLfloat*)temp_index * y_percent; |
||
3197 | } |
||
3198 | } |
||
3199 | } |
||
3200 | temp += group_size; |
||
3201 | percent = y_percent * highx_float; |
||
3202 | for (k = 0, temp_index = temp; k < components; |
||
3203 | k++, temp_index += element_size) { |
||
3204 | if (myswap_bytes) { |
||
3205 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3206 | totals[k] += swapbuf.f * percent; |
||
3207 | } else { |
||
3208 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3209 | } |
||
3210 | } |
||
3211 | } else { |
||
3212 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
3213 | temp = (const char *)datain + xindex + lowy_int * ysize; |
||
3214 | for (k = 0, temp_index = temp; k < components; |
||
3215 | k++, temp_index += element_size) { |
||
3216 | if (myswap_bytes) { |
||
3217 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3218 | totals[k] += swapbuf.f * percent; |
||
3219 | } else { |
||
3220 | totals[k] += *(const GLfloat*)temp_index * percent; |
||
3221 | } |
||
3222 | } |
||
3223 | } |
||
3224 | |||
3225 | /* this is for the pixels in the body */ |
||
3226 | temp0 = (const char *)datain + xindex + group_size + |
||
3227 | (lowy_int+1)*ysize; |
||
3228 | for (m = lowy_int+1; m < highy_int; m++) { |
||
3229 | temp = temp0; |
||
3230 | for(l = lowx_int+1; l < highx_int; l++) { |
||
3231 | for (k = 0, temp_index = temp; k < components; |
||
3232 | k++, temp_index += element_size) { |
||
3233 | if (myswap_bytes) { |
||
3234 | swapbuf.b = __GLU_SWAP_4_BYTES(temp_index); |
||
3235 | totals[k] += swapbuf.f; |
||
3236 | } else { |
||
3237 | totals[k] += *(const GLfloat*)temp_index; |
||
3238 | } |
||
3239 | } |
||
3240 | temp += group_size; |
||
3241 | } |
||
3242 | temp0 += ysize; |
||
3243 | } |
||
3244 | |||
3245 | outindex = (j + (i * widthout)) * components; |
||
3246 | for (k = 0; k < components; k++) { |
||
3247 | dataout[outindex + k] = totals[k]/area; |
||
3248 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
3249 | } |
||
3250 | lowx_int = highx_int; |
||
3251 | lowx_float = highx_float; |
||
3252 | highx_int += convx_int; |
||
3253 | highx_float += convx_float; |
||
3254 | if(highx_float > 1) { |
||
3255 | highx_float -= 1.0; |
||
3256 | highx_int++; |
||
3257 | } |
||
3258 | } |
||
3259 | lowy_int = highy_int; |
||
3260 | lowy_float = highy_float; |
||
3261 | highy_int += convy_int; |
||
3262 | highy_float += convy_float; |
||
3263 | if(highy_float > 1) { |
||
3264 | highy_float -= 1.0; |
||
3265 | highy_int++; |
||
3266 | } |
||
3267 | } |
||
3268 | } |
||
3269 | |||
3270 | static int checkMipmapArgs(GLenum internalFormat, GLenum format, GLenum type) |
||
3271 | { |
||
3272 | if (!legalFormat(format) || !legalType(type)) { |
||
3273 | return GLU_INVALID_ENUM; |
||
3274 | } |
||
3275 | if (format == GL_STENCIL_INDEX) { |
||
3276 | return GLU_INVALID_ENUM; |
||
3277 | } |
||
3278 | |||
3279 | if (!isLegalFormatForPackedPixelType(format, type)) { |
||
3280 | return GLU_INVALID_OPERATION; |
||
3281 | } |
||
3282 | |||
3283 | return 0; |
||
3284 | } /* checkMipmapArgs() */ |
||
3285 | |||
3286 | static GLboolean legalFormat(GLenum format) |
||
3287 | { |
||
3288 | switch(format) { |
||
3289 | case GL_COLOR_INDEX: |
||
3290 | case GL_STENCIL_INDEX: |
||
3291 | case GL_DEPTH_COMPONENT: |
||
3292 | case GL_RED: |
||
3293 | case GL_GREEN: |
||
3294 | case GL_BLUE: |
||
3295 | case GL_ALPHA: |
||
3296 | case GL_RGB: |
||
3297 | case GL_RGBA: |
||
3298 | case GL_LUMINANCE: |
||
3299 | case GL_LUMINANCE_ALPHA: |
||
3300 | case GL_BGR: |
||
3301 | case GL_BGRA: |
||
3302 | return GL_TRUE; |
||
3303 | default: |
||
3304 | return GL_FALSE; |
||
3305 | } |
||
3306 | } |
||
3307 | |||
3308 | |||
3309 | static GLboolean legalType(GLenum type) |
||
3310 | { |
||
3311 | switch(type) { |
||
3312 | case GL_BITMAP: |
||
3313 | case GL_BYTE: |
||
3314 | case GL_UNSIGNED_BYTE: |
||
3315 | case GL_SHORT: |
||
3316 | case GL_UNSIGNED_SHORT: |
||
3317 | case GL_INT: |
||
3318 | case GL_UNSIGNED_INT: |
||
3319 | case GL_FLOAT: |
||
3320 | case GL_UNSIGNED_BYTE_3_3_2: |
||
3321 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
3322 | case GL_UNSIGNED_SHORT_5_6_5: |
||
3323 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
3324 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
3325 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
3326 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
3327 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
3328 | case GL_UNSIGNED_INT_8_8_8_8: |
||
3329 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
3330 | case GL_UNSIGNED_INT_10_10_10_2: |
||
3331 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
3332 | return GL_TRUE; |
||
3333 | default: |
||
3334 | return GL_FALSE; |
||
3335 | } |
||
3336 | } |
||
3337 | |||
3338 | /* */ |
||
3339 | static GLboolean isTypePackedPixel(GLenum type) |
||
3340 | { |
||
3341 | assert(legalType(type)); |
||
3342 | |||
3343 | if (type == GL_UNSIGNED_BYTE_3_3_2 || |
||
3344 | type == GL_UNSIGNED_BYTE_2_3_3_REV || |
||
3345 | type == GL_UNSIGNED_SHORT_5_6_5 || |
||
3346 | type == GL_UNSIGNED_SHORT_5_6_5_REV || |
||
3347 | type == GL_UNSIGNED_SHORT_4_4_4_4 || |
||
3348 | type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
||
3349 | type == GL_UNSIGNED_SHORT_5_5_5_1 || |
||
3350 | type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
||
3351 | type == GL_UNSIGNED_INT_8_8_8_8 || |
||
3352 | type == GL_UNSIGNED_INT_8_8_8_8_REV || |
||
3353 | type == GL_UNSIGNED_INT_10_10_10_2 || |
||
3354 | type == GL_UNSIGNED_INT_2_10_10_10_REV) { |
||
3355 | return 1; |
||
3356 | } |
||
3357 | else return 0; |
||
3358 | } /* isTypePackedPixel() */ |
||
3359 | |||
3360 | /* Determines if the packed pixel type is compatible with the format */ |
||
3361 | static GLboolean isLegalFormatForPackedPixelType(GLenum format, GLenum type) |
||
3362 | { |
||
3363 | /* if not a packed pixel type then return true */ |
||
3364 | if (!isTypePackedPixel(type)) { |
||
3365 | return GL_TRUE; |
||
3366 | } |
||
3367 | |||
3368 | /* 3_3_2/2_3_3_REV & 5_6_5/5_6_5_REV are only compatible with RGB */ |
||
3369 | if ((type == GL_UNSIGNED_BYTE_3_3_2 || type == GL_UNSIGNED_BYTE_2_3_3_REV|| |
||
3370 | type == GL_UNSIGNED_SHORT_5_6_5|| type == GL_UNSIGNED_SHORT_5_6_5_REV) |
||
3371 | && format != GL_RGB) |
||
3372 | return GL_FALSE; |
||
3373 | |||
3374 | /* 4_4_4_4/4_4_4_4_REV & 5_5_5_1/1_5_5_5_REV & 8_8_8_8/8_8_8_8_REV & |
||
3375 | * 10_10_10_2/2_10_10_10_REV are only compatible with RGBA, BGRA & ABGR_EXT. |
||
3376 | */ |
||
3377 | if ((type == GL_UNSIGNED_SHORT_4_4_4_4 || |
||
3378 | type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
||
3379 | type == GL_UNSIGNED_SHORT_5_5_5_1 || |
||
3380 | type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
||
3381 | type == GL_UNSIGNED_INT_8_8_8_8 || |
||
3382 | type == GL_UNSIGNED_INT_8_8_8_8_REV || |
||
3383 | type == GL_UNSIGNED_INT_10_10_10_2 || |
||
3384 | type == GL_UNSIGNED_INT_2_10_10_10_REV) && |
||
3385 | (format != GL_RGBA && |
||
3386 | format != GL_BGRA)) { |
||
3387 | return GL_FALSE; |
||
3388 | } |
||
3389 | |||
3390 | return GL_TRUE; |
||
3391 | } /* isLegalFormatForPackedPixelType() */ |
||
3392 | |||
3393 | static GLboolean isLegalLevels(GLint userLevel,GLint baseLevel,GLint maxLevel, |
||
3394 | GLint totalLevels) |
||
3395 | { |
||
3396 | if (baseLevel < 0 || baseLevel < userLevel || maxLevel < baseLevel || |
||
3397 | totalLevels < maxLevel) |
||
3398 | return GL_FALSE; |
||
3399 | else return GL_TRUE; |
||
3400 | } /* isLegalLevels() */ |
||
3401 | |||
3402 | /* Given user requested texture size, determine if it fits. If it |
||
3403 | * doesn't then halve both sides and make the determination again |
||
3404 | * until it does fit (for IR only). |
||
3405 | * Note that proxy textures are not implemented in RE* even though |
||
3406 | * they advertise the texture extension. |
||
3407 | * Note that proxy textures are implemented but not according to spec in |
||
3408 | * IMPACT*. |
||
3409 | */ |
||
3410 | static void closestFit(GLenum target, GLint width, GLint height, |
||
3411 | GLint internalFormat, GLenum format, GLenum type, |
||
3412 | GLint *newWidth, GLint *newHeight) |
||
3413 | { |
||
3414 | /* Use proxy textures if OpenGL version is >= 1.1 */ |
||
3415 | if ( (strtod((const char *)glGetString(GL_VERSION),NULL) >= 1.1) |
||
3416 | ) { |
||
3417 | GLint widthPowerOf2= nearestPower(width); |
||
3418 | GLint heightPowerOf2= nearestPower(height); |
||
3419 | GLint proxyWidth; |
||
3420 | |||
3421 | do { |
||
3422 | /* compute level 1 width & height, clamping each at 1 */ |
||
3423 | GLint widthAtLevelOne= (widthPowerOf2 > 1) ? |
||
3424 | widthPowerOf2 >> 1 : |
||
3425 | widthPowerOf2; |
||
3426 | GLint heightAtLevelOne= (heightPowerOf2 > 1) ? |
||
3427 | heightPowerOf2 >> 1 : |
||
3428 | heightPowerOf2; |
||
3429 | GLenum proxyTarget; |
||
3430 | assert(widthAtLevelOne > 0); assert(heightAtLevelOne > 0); |
||
3431 | |||
3432 | /* does width x height at level 1 & all their mipmaps fit? */ |
||
3433 | if (target == GL_TEXTURE_2D || target == GL_PROXY_TEXTURE_2D) { |
||
3434 | proxyTarget = GL_PROXY_TEXTURE_2D; |
||
3435 | glTexImage2D(proxyTarget, 1, /* must be non-zero */ |
||
3436 | internalFormat, |
||
3437 | widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); |
||
3438 | } else |
||
3439 | #if defined(GL_ARB_texture_cube_map) |
||
3440 | if ((target == GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB) || |
||
3441 | (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB) || |
||
3442 | (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB) || |
||
3443 | (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB) || |
||
3444 | (target == GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB) || |
||
3445 | (target == GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) { |
||
3446 | proxyTarget = GL_PROXY_TEXTURE_CUBE_MAP_ARB; |
||
3447 | glTexImage2D(proxyTarget, 1, /* must be non-zero */ |
||
3448 | internalFormat, |
||
3449 | widthAtLevelOne,heightAtLevelOne,0,format,type,NULL); |
||
3450 | } else |
||
3451 | #endif /* GL_ARB_texture_cube_map */ |
||
3452 | { |
||
3453 | assert(target == GL_TEXTURE_1D || target == GL_PROXY_TEXTURE_1D); |
||
3454 | proxyTarget = GL_PROXY_TEXTURE_1D; |
||
3455 | glTexImage1D(proxyTarget, 1, /* must be non-zero */ |
||
3456 | internalFormat,widthAtLevelOne,0,format,type,NULL); |
||
3457 | } |
||
3458 | glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); |
||
3459 | /* does it fit??? */ |
||
3460 | if (proxyWidth == 0) { /* nope, so try again with these sizes */ |
||
3461 | if (widthPowerOf2 == 1 && heightPowerOf2 == 1) { |
||
3462 | /* An 1x1 texture couldn't fit for some reason, so |
||
3463 | * break out. This should never happen. But things |
||
3464 | * happen. The disadvantage with this if-statement is |
||
3465 | * that we will never be aware of when this happens |
||
3466 | * since it will silently branch out. |
||
3467 | */ |
||
3468 | goto noProxyTextures; |
||
3469 | } |
||
3470 | widthPowerOf2= widthAtLevelOne; |
||
3471 | heightPowerOf2= heightAtLevelOne; |
||
3472 | } |
||
3473 | /* else it does fit */ |
||
3474 | } while (proxyWidth == 0); |
||
3475 | /* loop must terminate! */ |
||
3476 | |||
3477 | /* return the width & height at level 0 that fits */ |
||
3478 | *newWidth= widthPowerOf2; |
||
3479 | *newHeight= heightPowerOf2; |
||
3480 | /*printf("Proxy Textures\n");*/ |
||
3481 | } /* if gluCheckExtension() */ |
||
3482 | else { /* no texture extension, so do this instead */ |
||
3483 | GLint maxsize; |
||
3484 | |||
3485 | noProxyTextures: |
||
3486 | |||
3487 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); |
||
3488 | /* clamp user's texture sizes to maximum sizes, if necessary */ |
||
3489 | *newWidth = nearestPower(width); |
||
3490 | if (*newWidth > maxsize) *newWidth = maxsize; |
||
3491 | *newHeight = nearestPower(height); |
||
3492 | if (*newHeight > maxsize) *newHeight = maxsize; |
||
3493 | /*printf("NO proxy textures\n");*/ |
||
3494 | } |
||
3495 | } /* closestFit() */ |
||
3496 | |||
3497 | GLint GLAPIENTRY |
||
3498 | gluScaleImage(GLenum format, GLsizei widthin, GLsizei heightin, |
||
3499 | GLenum typein, const void *datain, |
||
3500 | GLsizei widthout, GLsizei heightout, GLenum typeout, |
||
3501 | void *dataout) |
||
3502 | { |
||
3503 | int components; |
||
3504 | GLushort *beforeImage; |
||
3505 | GLushort *afterImage; |
||
3506 | PixelStorageModes psm; |
||
3507 | |||
3508 | if (widthin == 0 || heightin == 0 || widthout == 0 || heightout == 0) { |
||
3509 | return 0; |
||
3510 | } |
||
3511 | if (widthin < 0 || heightin < 0 || widthout < 0 || heightout < 0) { |
||
3512 | return GLU_INVALID_VALUE; |
||
3513 | } |
||
3514 | if (!legalFormat(format) || !legalType(typein) || !legalType(typeout)) { |
||
3515 | return GLU_INVALID_ENUM; |
||
3516 | } |
||
3517 | if (!isLegalFormatForPackedPixelType(format, typein)) { |
||
3518 | return GLU_INVALID_OPERATION; |
||
3519 | } |
||
3520 | if (!isLegalFormatForPackedPixelType(format, typeout)) { |
||
3521 | return GLU_INVALID_OPERATION; |
||
3522 | } |
||
3523 | beforeImage = |
||
3524 | malloc(image_size(widthin, heightin, format, GL_UNSIGNED_SHORT)); |
||
3525 | afterImage = |
||
3526 | malloc(image_size(widthout, heightout, format, GL_UNSIGNED_SHORT)); |
||
3527 | if (beforeImage == NULL || afterImage == NULL) { |
||
3528 | free(beforeImage); |
||
3529 | free(afterImage); |
||
3530 | return GLU_OUT_OF_MEMORY; |
||
3531 | } |
||
3532 | |||
3533 | retrieveStoreModes(&psm); |
||
3534 | fill_image(&psm,widthin, heightin, format, typein, is_index(format), |
||
3535 | datain, beforeImage); |
||
3536 | components = elements_per_group(format, 0); |
||
3537 | scale_internal(components, widthin, heightin, beforeImage, |
||
3538 | widthout, heightout, afterImage); |
||
3539 | empty_image(&psm,widthout, heightout, format, typeout, |
||
3540 | is_index(format), afterImage, dataout); |
||
3541 | free((GLbyte *) beforeImage); |
||
3542 | free((GLbyte *) afterImage); |
||
3543 | |||
3544 | return 0; |
||
3545 | } |
||
3546 | |||
3547 | int gluBuild1DMipmapLevelsCore(GLenum target, GLint internalFormat, |
||
3548 | GLsizei width, |
||
3549 | GLsizei widthPowerOf2, |
||
3550 | GLenum format, GLenum type, |
||
3551 | GLint userLevel, GLint baseLevel,GLint maxLevel, |
||
3552 | const void *data) |
||
3553 | { |
||
3554 | GLint newwidth; |
||
3555 | GLint level, levels; |
||
3556 | GLushort *newImage; |
||
3557 | GLint newImage_width; |
||
3558 | GLushort *otherImage; |
||
3559 | GLushort *imageTemp; |
||
3560 | GLint memreq; |
||
3561 | GLint cmpts; |
||
3562 | PixelStorageModes psm; |
||
3563 | |||
3564 | assert(checkMipmapArgs(internalFormat,format,type) == 0); |
||
3565 | assert(width >= 1); |
||
3566 | |||
3567 | otherImage = NULL; |
||
3568 | |||
3569 | newwidth= widthPowerOf2; |
||
3570 | levels = computeLog(newwidth); |
||
3571 | |||
3572 | levels+= userLevel; |
||
3573 | |||
3574 | retrieveStoreModes(&psm); |
||
3575 | newImage = (GLushort *) |
||
3576 | malloc(image_size(width, 1, format, GL_UNSIGNED_SHORT)); |
||
3577 | newImage_width = width; |
||
3578 | if (newImage == NULL) { |
||
3579 | return GLU_OUT_OF_MEMORY; |
||
3580 | } |
||
3581 | fill_image(&psm,width, 1, format, type, is_index(format), |
||
3582 | data, newImage); |
||
3583 | cmpts = elements_per_group(format,type); |
||
3584 | glPixelStorei(GL_UNPACK_ALIGNMENT, 2); |
||
3585 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
||
3586 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
||
3587 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
3588 | /* |
||
3589 | ** If swap_bytes was set, swapping occurred in fill_image. |
||
3590 | */ |
||
3591 | glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
||
3592 | |||
3593 | for (level = userLevel; level <= levels; level++) { |
||
3594 | if (newImage_width == newwidth) { |
||
3595 | /* Use newImage for this level */ |
||
3596 | if (baseLevel <= level && level <= maxLevel) { |
||
3597 | glTexImage1D(target, level, internalFormat, newImage_width, |
||
3598 | 0, format, GL_UNSIGNED_SHORT, (void *) newImage); |
||
3599 | } |
||
3600 | } else { |
||
3601 | if (otherImage == NULL) { |
||
3602 | memreq = image_size(newwidth, 1, format, GL_UNSIGNED_SHORT); |
||
3603 | otherImage = (GLushort *) malloc(memreq); |
||
3604 | if (otherImage == NULL) { |
||
3605 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3606 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3607 | glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); |
||
3608 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3609 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3610 | free(newImage); |
||
3611 | return GLU_OUT_OF_MEMORY; |
||
3612 | } |
||
3613 | } |
||
3614 | scale_internal(cmpts, newImage_width, 1, newImage, |
||
3615 | newwidth, 1, otherImage); |
||
3616 | /* Swap newImage and otherImage */ |
||
3617 | imageTemp = otherImage; |
||
3618 | otherImage = newImage; |
||
3619 | newImage = imageTemp; |
||
3620 | |||
3621 | newImage_width = newwidth; |
||
3622 | if (baseLevel <= level && level <= maxLevel) { |
||
3623 | glTexImage1D(target, level, internalFormat, newImage_width, |
||
3624 | 0, format, GL_UNSIGNED_SHORT, (void *) newImage); |
||
3625 | } |
||
3626 | } |
||
3627 | if (newwidth > 1) newwidth /= 2; |
||
3628 | } |
||
3629 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3630 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3631 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
3632 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3633 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3634 | |||
3635 | free((GLbyte *) newImage); |
||
3636 | if (otherImage) { |
||
3637 | free((GLbyte *) otherImage); |
||
3638 | } |
||
3639 | return 0; |
||
3640 | } |
||
3641 | |||
3642 | GLint GLAPIENTRY |
||
3643 | gluBuild1DMipmapLevels(GLenum target, GLint internalFormat, |
||
3644 | GLsizei width, |
||
3645 | GLenum format, GLenum type, |
||
3646 | GLint userLevel, GLint baseLevel, GLint maxLevel, |
||
3647 | const void *data) |
||
3648 | { |
||
3649 | int levels; |
||
3650 | |||
3651 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
3652 | if (rc != 0) return rc; |
||
3653 | |||
3654 | if (width < 1) { |
||
3655 | return GLU_INVALID_VALUE; |
||
3656 | } |
||
3657 | |||
3658 | levels = computeLog(width); |
||
3659 | |||
3660 | levels+= userLevel; |
||
3661 | if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
||
3662 | return GLU_INVALID_VALUE; |
||
3663 | |||
3664 | return gluBuild1DMipmapLevelsCore(target, internalFormat, |
||
3665 | width, |
||
3666 | width,format, type, |
||
3667 | userLevel, baseLevel, maxLevel, |
||
3668 | data); |
||
3669 | } /* gluBuild1DMipmapLevels() */ |
||
3670 | |||
3671 | GLint GLAPIENTRY |
||
3672 | gluBuild1DMipmaps(GLenum target, GLint internalFormat, GLsizei width, |
||
3673 | GLenum format, GLenum type, |
||
3674 | const void *data) |
||
3675 | { |
||
3676 | GLint widthPowerOf2; |
||
3677 | int levels; |
||
3678 | GLint dummy; |
||
3679 | |||
3680 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
3681 | if (rc != 0) return rc; |
||
3682 | |||
3683 | if (width < 1) { |
||
3684 | return GLU_INVALID_VALUE; |
||
3685 | } |
||
3686 | |||
3687 | closestFit(target,width,1,internalFormat,format,type,&widthPowerOf2,&dummy); |
||
3688 | levels = computeLog(widthPowerOf2); |
||
3689 | |||
3690 | return gluBuild1DMipmapLevelsCore(target,internalFormat, |
||
3691 | width, |
||
3692 | widthPowerOf2, |
||
3693 | format,type,0,0,levels,data); |
||
3694 | } |
||
3695 | |||
3696 | static int bitmapBuild2DMipmaps(GLenum target, GLint internalFormat, |
||
3697 | GLint width, GLint height, GLenum format, |
||
3698 | GLenum type, const void *data) |
||
3699 | { |
||
3700 | GLint newwidth, newheight; |
||
3701 | GLint level, levels; |
||
3702 | GLushort *newImage; |
||
3703 | GLint newImage_width; |
||
3704 | GLint newImage_height; |
||
3705 | GLushort *otherImage; |
||
3706 | GLushort *imageTemp; |
||
3707 | GLint memreq; |
||
3708 | GLint cmpts; |
||
3709 | PixelStorageModes psm; |
||
3710 | |||
3711 | retrieveStoreModes(&psm); |
||
3712 | |||
3713 | #if 0 |
||
3714 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); |
||
3715 | newwidth = nearestPower(width); |
||
3716 | if (newwidth > maxsize) newwidth = maxsize; |
||
3717 | newheight = nearestPower(height); |
||
3718 | if (newheight > maxsize) newheight = maxsize; |
||
3719 | #else |
||
3720 | closestFit(target,width,height,internalFormat,format,type, |
||
3721 | &newwidth,&newheight); |
||
3722 | #endif |
||
3723 | levels = computeLog(newwidth); |
||
3724 | level = computeLog(newheight); |
||
3725 | if (level > levels) levels=level; |
||
3726 | |||
3727 | otherImage = NULL; |
||
3728 | newImage = (GLushort *) |
||
3729 | malloc(image_size(width, height, format, GL_UNSIGNED_SHORT)); |
||
3730 | newImage_width = width; |
||
3731 | newImage_height = height; |
||
3732 | if (newImage == NULL) { |
||
3733 | return GLU_OUT_OF_MEMORY; |
||
3734 | } |
||
3735 | |||
3736 | fill_image(&psm,width, height, format, type, is_index(format), |
||
3737 | data, newImage); |
||
3738 | |||
3739 | cmpts = elements_per_group(format,type); |
||
3740 | glPixelStorei(GL_UNPACK_ALIGNMENT, 2); |
||
3741 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
||
3742 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
||
3743 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
3744 | /* |
||
3745 | ** If swap_bytes was set, swapping occurred in fill_image. |
||
3746 | */ |
||
3747 | glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
||
3748 | |||
3749 | for (level = 0; level <= levels; level++) { |
||
3750 | if (newImage_width == newwidth && newImage_height == newheight) { /* Use newImage for this level */ |
||
3751 | glTexImage2D(target, level, internalFormat, newImage_width, |
||
3752 | newImage_height, 0, format, GL_UNSIGNED_SHORT, |
||
3753 | (void *) newImage); |
||
3754 | } else { |
||
3755 | if (otherImage == NULL) { |
||
3756 | memreq = |
||
3757 | image_size(newwidth, newheight, format, GL_UNSIGNED_SHORT); |
||
3758 | otherImage = (GLushort *) malloc(memreq); |
||
3759 | if (otherImage == NULL) { |
||
3760 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3761 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3762 | glPixelStorei(GL_UNPACK_SKIP_PIXELS,psm.unpack_skip_pixels); |
||
3763 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3764 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3765 | free(newImage); |
||
3766 | return GLU_OUT_OF_MEMORY; |
||
3767 | } |
||
3768 | } |
||
3769 | scale_internal(cmpts, newImage_width, newImage_height, newImage, |
||
3770 | newwidth, newheight, otherImage); |
||
3771 | /* Swap newImage and otherImage */ |
||
3772 | imageTemp = otherImage; |
||
3773 | otherImage = newImage; |
||
3774 | newImage = imageTemp; |
||
3775 | |||
3776 | newImage_width = newwidth; |
||
3777 | newImage_height = newheight; |
||
3778 | glTexImage2D(target, level, internalFormat, newImage_width, |
||
3779 | newImage_height, 0, format, GL_UNSIGNED_SHORT, |
||
3780 | (void *) newImage); |
||
3781 | } |
||
3782 | if (newwidth > 1) newwidth /= 2; |
||
3783 | if (newheight > 1) newheight /= 2; |
||
3784 | } |
||
3785 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3786 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3787 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
3788 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3789 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3790 | |||
3791 | free((GLbyte *) newImage); |
||
3792 | if (otherImage) { |
||
3793 | free((GLbyte *) otherImage); |
||
3794 | } |
||
3795 | return 0; |
||
3796 | } |
||
3797 | |||
3798 | /* To make swapping images less error prone */ |
||
3799 | #define __GLU_INIT_SWAP_IMAGE void *tmpImage |
||
3800 | #define __GLU_SWAP_IMAGE(a,b) tmpImage = a; a = b; b = tmpImage; |
||
3801 | |||
3802 | static int gluBuild2DMipmapLevelsCore(GLenum target, GLint internalFormat, |
||
3803 | GLsizei width, GLsizei height, |
||
3804 | GLsizei widthPowerOf2, |
||
3805 | GLsizei heightPowerOf2, |
||
3806 | GLenum format, GLenum type, |
||
3807 | GLint userLevel, |
||
3808 | GLint baseLevel,GLint maxLevel, |
||
3809 | const void *data) |
||
3810 | { |
||
3811 | GLint newwidth, newheight; |
||
3812 | GLint level, levels; |
||
3813 | const void *usersImage; /* passed from user. Don't touch! */ |
||
3814 | void *srcImage, *dstImage; /* scratch area to build mipmapped images */ |
||
3815 | __GLU_INIT_SWAP_IMAGE; |
||
3816 | GLint memreq; |
||
3817 | GLint cmpts; |
||
3818 | |||
3819 | GLint myswap_bytes, groups_per_line, element_size, group_size; |
||
3820 | GLint rowsize, padding; |
||
3821 | PixelStorageModes psm; |
||
3822 | |||
3823 | assert(checkMipmapArgs(internalFormat,format,type) == 0); |
||
3824 | assert(width >= 1 && height >= 1); |
||
3825 | |||
3826 | if(type == GL_BITMAP) { |
||
3827 | return bitmapBuild2DMipmaps(target, internalFormat, width, height, |
||
3828 | format, type, data); |
||
3829 | } |
||
3830 | |||
3831 | srcImage = dstImage = NULL; |
||
3832 | |||
3833 | newwidth= widthPowerOf2; |
||
3834 | newheight= heightPowerOf2; |
||
3835 | levels = computeLog(newwidth); |
||
3836 | level = computeLog(newheight); |
||
3837 | if (level > levels) levels=level; |
||
3838 | |||
3839 | levels+= userLevel; |
||
3840 | |||
3841 | retrieveStoreModes(&psm); |
||
3842 | myswap_bytes = psm.unpack_swap_bytes; |
||
3843 | cmpts = elements_per_group(format,type); |
||
3844 | if (psm.unpack_row_length > 0) { |
||
3845 | groups_per_line = psm.unpack_row_length; |
||
3846 | } else { |
||
3847 | groups_per_line = width; |
||
3848 | } |
||
3849 | |||
3850 | element_size = bytes_per_element(type); |
||
3851 | group_size = element_size * cmpts; |
||
3852 | if (element_size == 1) myswap_bytes = 0; |
||
3853 | |||
3854 | rowsize = groups_per_line * group_size; |
||
3855 | padding = (rowsize % psm.unpack_alignment); |
||
3856 | if (padding) { |
||
3857 | rowsize += psm.unpack_alignment - padding; |
||
3858 | } |
||
3859 | usersImage = (const GLubyte *) data + psm.unpack_skip_rows * rowsize + |
||
3860 | psm.unpack_skip_pixels * group_size; |
||
3861 | |||
3862 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
||
3863 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
||
3864 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
3865 | |||
3866 | level = userLevel; |
||
3867 | |||
3868 | /* already power-of-two square */ |
||
3869 | if (width == newwidth && height == newheight) { |
||
3870 | /* Use usersImage for level userLevel */ |
||
3871 | if (baseLevel <= level && level <= maxLevel) { |
||
3872 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3873 | glTexImage2D(target, level, internalFormat, width, |
||
3874 | height, 0, format, type, |
||
3875 | usersImage); |
||
3876 | } |
||
3877 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
3878 | if(levels == 0) { /* we're done. clean up and return */ |
||
3879 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3880 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3881 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
3882 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3883 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3884 | return 0; |
||
3885 | } |
||
3886 | { |
||
3887 | int nextWidth= newwidth/2; |
||
3888 | int nextHeight= newheight/2; |
||
3889 | |||
3890 | /* clamp to 1 */ |
||
3891 | if (nextWidth < 1) nextWidth= 1; |
||
3892 | if (nextHeight < 1) nextHeight= 1; |
||
3893 | memreq = image_size(nextWidth, nextHeight, format, type); |
||
3894 | } |
||
3895 | |||
3896 | switch(type) { |
||
3897 | case GL_UNSIGNED_BYTE: |
||
3898 | dstImage = (GLubyte *)malloc(memreq); |
||
3899 | break; |
||
3900 | case GL_BYTE: |
||
3901 | dstImage = (GLbyte *)malloc(memreq); |
||
3902 | break; |
||
3903 | case GL_UNSIGNED_SHORT: |
||
3904 | dstImage = (GLushort *)malloc(memreq); |
||
3905 | break; |
||
3906 | case GL_SHORT: |
||
3907 | dstImage = (GLshort *)malloc(memreq); |
||
3908 | break; |
||
3909 | case GL_UNSIGNED_INT: |
||
3910 | dstImage = (GLuint *)malloc(memreq); |
||
3911 | break; |
||
3912 | case GL_INT: |
||
3913 | dstImage = (GLint *)malloc(memreq); |
||
3914 | break; |
||
3915 | case GL_FLOAT: |
||
3916 | dstImage = (GLfloat *)malloc(memreq); |
||
3917 | break; |
||
3918 | case GL_UNSIGNED_BYTE_3_3_2: |
||
3919 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
3920 | dstImage = (GLubyte *)malloc(memreq); |
||
3921 | break; |
||
3922 | case GL_UNSIGNED_SHORT_5_6_5: |
||
3923 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
3924 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
3925 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
3926 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
3927 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
3928 | dstImage = (GLushort *)malloc(memreq); |
||
3929 | break; |
||
3930 | case GL_UNSIGNED_INT_8_8_8_8: |
||
3931 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
3932 | case GL_UNSIGNED_INT_10_10_10_2: |
||
3933 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
3934 | dstImage = (GLuint *)malloc(memreq); |
||
3935 | break; |
||
3936 | default: |
||
3937 | return GLU_INVALID_ENUM; |
||
3938 | } |
||
3939 | if (dstImage == NULL) { |
||
3940 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
3941 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
3942 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
3943 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
3944 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
3945 | return GLU_OUT_OF_MEMORY; |
||
3946 | } |
||
3947 | else |
||
3948 | switch(type) { |
||
3949 | case GL_UNSIGNED_BYTE: |
||
3950 | halveImage_ubyte(cmpts, width, height, |
||
3951 | (const GLubyte *)usersImage, (GLubyte *)dstImage, |
||
3952 | element_size, rowsize, group_size); |
||
3953 | break; |
||
3954 | case GL_BYTE: |
||
3955 | halveImage_byte(cmpts, width, height, |
||
3956 | (const GLbyte *)usersImage, (GLbyte *)dstImage, |
||
3957 | element_size, rowsize, group_size); |
||
3958 | break; |
||
3959 | case GL_UNSIGNED_SHORT: |
||
3960 | halveImage_ushort(cmpts, width, height, |
||
3961 | (const GLushort *)usersImage, (GLushort *)dstImage, |
||
3962 | element_size, rowsize, group_size, myswap_bytes); |
||
3963 | break; |
||
3964 | case GL_SHORT: |
||
3965 | halveImage_short(cmpts, width, height, |
||
3966 | (const GLshort *)usersImage, (GLshort *)dstImage, |
||
3967 | element_size, rowsize, group_size, myswap_bytes); |
||
3968 | break; |
||
3969 | case GL_UNSIGNED_INT: |
||
3970 | halveImage_uint(cmpts, width, height, |
||
3971 | (const GLuint *)usersImage, (GLuint *)dstImage, |
||
3972 | element_size, rowsize, group_size, myswap_bytes); |
||
3973 | break; |
||
3974 | case GL_INT: |
||
3975 | halveImage_int(cmpts, width, height, |
||
3976 | (const GLint *)usersImage, (GLint *)dstImage, |
||
3977 | element_size, rowsize, group_size, myswap_bytes); |
||
3978 | break; |
||
3979 | case GL_FLOAT: |
||
3980 | halveImage_float(cmpts, width, height, |
||
3981 | (const GLfloat *)usersImage, (GLfloat *)dstImage, |
||
3982 | element_size, rowsize, group_size, myswap_bytes); |
||
3983 | break; |
||
3984 | case GL_UNSIGNED_BYTE_3_3_2: |
||
3985 | assert(format == GL_RGB); |
||
3986 | halveImagePackedPixel(3,extract332,shove332, |
||
3987 | width,height,usersImage,dstImage, |
||
3988 | element_size,rowsize,myswap_bytes); |
||
3989 | break; |
||
3990 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
3991 | assert(format == GL_RGB); |
||
3992 | halveImagePackedPixel(3,extract233rev,shove233rev, |
||
3993 | width,height,usersImage,dstImage, |
||
3994 | element_size,rowsize,myswap_bytes); |
||
3995 | break; |
||
3996 | case GL_UNSIGNED_SHORT_5_6_5: |
||
3997 | halveImagePackedPixel(3,extract565,shove565, |
||
3998 | width,height,usersImage,dstImage, |
||
3999 | element_size,rowsize,myswap_bytes); |
||
4000 | break; |
||
4001 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4002 | halveImagePackedPixel(3,extract565rev,shove565rev, |
||
4003 | width,height,usersImage,dstImage, |
||
4004 | element_size,rowsize,myswap_bytes); |
||
4005 | break; |
||
4006 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4007 | halveImagePackedPixel(4,extract4444,shove4444, |
||
4008 | width,height,usersImage,dstImage, |
||
4009 | element_size,rowsize,myswap_bytes); |
||
4010 | break; |
||
4011 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4012 | halveImagePackedPixel(4,extract4444rev,shove4444rev, |
||
4013 | width,height,usersImage,dstImage, |
||
4014 | element_size,rowsize,myswap_bytes); |
||
4015 | break; |
||
4016 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4017 | halveImagePackedPixel(4,extract5551,shove5551, |
||
4018 | width,height,usersImage,dstImage, |
||
4019 | element_size,rowsize,myswap_bytes); |
||
4020 | break; |
||
4021 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4022 | halveImagePackedPixel(4,extract1555rev,shove1555rev, |
||
4023 | width,height,usersImage,dstImage, |
||
4024 | element_size,rowsize,myswap_bytes); |
||
4025 | break; |
||
4026 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4027 | halveImagePackedPixel(4,extract8888,shove8888, |
||
4028 | width,height,usersImage,dstImage, |
||
4029 | element_size,rowsize,myswap_bytes); |
||
4030 | break; |
||
4031 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4032 | halveImagePackedPixel(4,extract8888rev,shove8888rev, |
||
4033 | width,height,usersImage,dstImage, |
||
4034 | element_size,rowsize,myswap_bytes); |
||
4035 | break; |
||
4036 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4037 | halveImagePackedPixel(4,extract1010102,shove1010102, |
||
4038 | width,height,usersImage,dstImage, |
||
4039 | element_size,rowsize,myswap_bytes); |
||
4040 | break; |
||
4041 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4042 | halveImagePackedPixel(4,extract2101010rev,shove2101010rev, |
||
4043 | width,height,usersImage,dstImage, |
||
4044 | element_size,rowsize,myswap_bytes); |
||
4045 | break; |
||
4046 | default: |
||
4047 | assert(0); |
||
4048 | break; |
||
4049 | } |
||
4050 | newwidth = width/2; |
||
4051 | newheight = height/2; |
||
4052 | /* clamp to 1 */ |
||
4053 | if (newwidth < 1) newwidth= 1; |
||
4054 | if (newheight < 1) newheight= 1; |
||
4055 | |||
4056 | myswap_bytes = 0; |
||
4057 | rowsize = newwidth * group_size; |
||
4058 | memreq = image_size(newwidth, newheight, format, type); |
||
4059 | /* Swap srcImage and dstImage */ |
||
4060 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
4061 | switch(type) { |
||
4062 | case GL_UNSIGNED_BYTE: |
||
4063 | dstImage = (GLubyte *)malloc(memreq); |
||
4064 | break; |
||
4065 | case GL_BYTE: |
||
4066 | dstImage = (GLbyte *)malloc(memreq); |
||
4067 | break; |
||
4068 | case GL_UNSIGNED_SHORT: |
||
4069 | dstImage = (GLushort *)malloc(memreq); |
||
4070 | break; |
||
4071 | case GL_SHORT: |
||
4072 | dstImage = (GLshort *)malloc(memreq); |
||
4073 | break; |
||
4074 | case GL_UNSIGNED_INT: |
||
4075 | dstImage = (GLuint *)malloc(memreq); |
||
4076 | break; |
||
4077 | case GL_INT: |
||
4078 | dstImage = (GLint *)malloc(memreq); |
||
4079 | break; |
||
4080 | case GL_FLOAT: |
||
4081 | dstImage = (GLfloat *)malloc(memreq); |
||
4082 | break; |
||
4083 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4084 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4085 | dstImage = (GLubyte *)malloc(memreq); |
||
4086 | break; |
||
4087 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4088 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4089 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4090 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4091 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4092 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4093 | dstImage = (GLushort *)malloc(memreq); |
||
4094 | break; |
||
4095 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4096 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4097 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4098 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4099 | dstImage = (GLuint *)malloc(memreq); |
||
4100 | break; |
||
4101 | default: |
||
4102 | return GLU_INVALID_ENUM; |
||
4103 | } |
||
4104 | if (dstImage == NULL) { |
||
4105 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
4106 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
4107 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
4108 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
4109 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
4110 | free(srcImage); |
||
4111 | return GLU_OUT_OF_MEMORY; |
||
4112 | } |
||
4113 | /* level userLevel+1 is in srcImage; level userLevel already saved */ |
||
4114 | level = userLevel+1; |
||
4115 | } else { /* user's image is *not* nice power-of-2 sized square */ |
||
4116 | memreq = image_size(newwidth, newheight, format, type); |
||
4117 | switch(type) { |
||
4118 | case GL_UNSIGNED_BYTE: |
||
4119 | dstImage = (GLubyte *)malloc(memreq); |
||
4120 | break; |
||
4121 | case GL_BYTE: |
||
4122 | dstImage = (GLbyte *)malloc(memreq); |
||
4123 | break; |
||
4124 | case GL_UNSIGNED_SHORT: |
||
4125 | dstImage = (GLushort *)malloc(memreq); |
||
4126 | break; |
||
4127 | case GL_SHORT: |
||
4128 | dstImage = (GLshort *)malloc(memreq); |
||
4129 | break; |
||
4130 | case GL_UNSIGNED_INT: |
||
4131 | dstImage = (GLuint *)malloc(memreq); |
||
4132 | break; |
||
4133 | case GL_INT: |
||
4134 | dstImage = (GLint *)malloc(memreq); |
||
4135 | break; |
||
4136 | case GL_FLOAT: |
||
4137 | dstImage = (GLfloat *)malloc(memreq); |
||
4138 | break; |
||
4139 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4140 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4141 | dstImage = (GLubyte *)malloc(memreq); |
||
4142 | break; |
||
4143 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4144 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4145 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4146 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4147 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4148 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4149 | dstImage = (GLushort *)malloc(memreq); |
||
4150 | break; |
||
4151 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4152 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4153 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4154 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4155 | dstImage = (GLuint *)malloc(memreq); |
||
4156 | break; |
||
4157 | default: |
||
4158 | return GLU_INVALID_ENUM; |
||
4159 | } |
||
4160 | |||
4161 | if (dstImage == NULL) { |
||
4162 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
4163 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
4164 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
4165 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
4166 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
4167 | return GLU_OUT_OF_MEMORY; |
||
4168 | } |
||
4169 | |||
4170 | switch(type) { |
||
4171 | case GL_UNSIGNED_BYTE: |
||
4172 | scale_internal_ubyte(cmpts, width, height, |
||
4173 | (const GLubyte *)usersImage, newwidth, newheight, |
||
4174 | (GLubyte *)dstImage, element_size, |
||
4175 | rowsize, group_size); |
||
4176 | break; |
||
4177 | case GL_BYTE: |
||
4178 | scale_internal_byte(cmpts, width, height, |
||
4179 | (const GLbyte *)usersImage, newwidth, newheight, |
||
4180 | (GLbyte *)dstImage, element_size, |
||
4181 | rowsize, group_size); |
||
4182 | break; |
||
4183 | case GL_UNSIGNED_SHORT: |
||
4184 | scale_internal_ushort(cmpts, width, height, |
||
4185 | (const GLushort *)usersImage, newwidth, newheight, |
||
4186 | (GLushort *)dstImage, element_size, |
||
4187 | rowsize, group_size, myswap_bytes); |
||
4188 | break; |
||
4189 | case GL_SHORT: |
||
4190 | scale_internal_short(cmpts, width, height, |
||
4191 | (const GLshort *)usersImage, newwidth, newheight, |
||
4192 | (GLshort *)dstImage, element_size, |
||
4193 | rowsize, group_size, myswap_bytes); |
||
4194 | break; |
||
4195 | case GL_UNSIGNED_INT: |
||
4196 | scale_internal_uint(cmpts, width, height, |
||
4197 | (const GLuint *)usersImage, newwidth, newheight, |
||
4198 | (GLuint *)dstImage, element_size, |
||
4199 | rowsize, group_size, myswap_bytes); |
||
4200 | break; |
||
4201 | case GL_INT: |
||
4202 | scale_internal_int(cmpts, width, height, |
||
4203 | (const GLint *)usersImage, newwidth, newheight, |
||
4204 | (GLint *)dstImage, element_size, |
||
4205 | rowsize, group_size, myswap_bytes); |
||
4206 | break; |
||
4207 | case GL_FLOAT: |
||
4208 | scale_internal_float(cmpts, width, height, |
||
4209 | (const GLfloat *)usersImage, newwidth, newheight, |
||
4210 | (GLfloat *)dstImage, element_size, |
||
4211 | rowsize, group_size, myswap_bytes); |
||
4212 | break; |
||
4213 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4214 | scaleInternalPackedPixel(3,extract332,shove332, |
||
4215 | width, height,usersImage, |
||
4216 | newwidth,newheight,(void *)dstImage, |
||
4217 | element_size,rowsize,myswap_bytes); |
||
4218 | break; |
||
4219 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4220 | scaleInternalPackedPixel(3,extract233rev,shove233rev, |
||
4221 | width, height,usersImage, |
||
4222 | newwidth,newheight,(void *)dstImage, |
||
4223 | element_size,rowsize,myswap_bytes); |
||
4224 | break; |
||
4225 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4226 | scaleInternalPackedPixel(3,extract565,shove565, |
||
4227 | width, height,usersImage, |
||
4228 | newwidth,newheight,(void *)dstImage, |
||
4229 | element_size,rowsize,myswap_bytes); |
||
4230 | break; |
||
4231 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4232 | scaleInternalPackedPixel(3,extract565rev,shove565rev, |
||
4233 | width, height,usersImage, |
||
4234 | newwidth,newheight,(void *)dstImage, |
||
4235 | element_size,rowsize,myswap_bytes); |
||
4236 | break; |
||
4237 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4238 | scaleInternalPackedPixel(4,extract4444,shove4444, |
||
4239 | width, height,usersImage, |
||
4240 | newwidth,newheight,(void *)dstImage, |
||
4241 | element_size,rowsize,myswap_bytes); |
||
4242 | break; |
||
4243 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4244 | scaleInternalPackedPixel(4,extract4444rev,shove4444rev, |
||
4245 | width, height,usersImage, |
||
4246 | newwidth,newheight,(void *)dstImage, |
||
4247 | element_size,rowsize,myswap_bytes); |
||
4248 | break; |
||
4249 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4250 | scaleInternalPackedPixel(4,extract5551,shove5551, |
||
4251 | width, height,usersImage, |
||
4252 | newwidth,newheight,(void *)dstImage, |
||
4253 | element_size,rowsize,myswap_bytes); |
||
4254 | break; |
||
4255 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4256 | scaleInternalPackedPixel(4,extract1555rev,shove1555rev, |
||
4257 | width, height,usersImage, |
||
4258 | newwidth,newheight,(void *)dstImage, |
||
4259 | element_size,rowsize,myswap_bytes); |
||
4260 | break; |
||
4261 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4262 | scaleInternalPackedPixel(4,extract8888,shove8888, |
||
4263 | width, height,usersImage, |
||
4264 | newwidth,newheight,(void *)dstImage, |
||
4265 | element_size,rowsize,myswap_bytes); |
||
4266 | break; |
||
4267 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4268 | scaleInternalPackedPixel(4,extract8888rev,shove8888rev, |
||
4269 | width, height,usersImage, |
||
4270 | newwidth,newheight,(void *)dstImage, |
||
4271 | element_size,rowsize,myswap_bytes); |
||
4272 | break; |
||
4273 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4274 | scaleInternalPackedPixel(4,extract1010102,shove1010102, |
||
4275 | width, height,usersImage, |
||
4276 | newwidth,newheight,(void *)dstImage, |
||
4277 | element_size,rowsize,myswap_bytes); |
||
4278 | break; |
||
4279 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4280 | scaleInternalPackedPixel(4,extract2101010rev,shove2101010rev, |
||
4281 | width, height,usersImage, |
||
4282 | newwidth,newheight,(void *)dstImage, |
||
4283 | element_size,rowsize,myswap_bytes); |
||
4284 | break; |
||
4285 | default: |
||
4286 | assert(0); |
||
4287 | break; |
||
4288 | } |
||
4289 | myswap_bytes = 0; |
||
4290 | rowsize = newwidth * group_size; |
||
4291 | /* Swap dstImage and srcImage */ |
||
4292 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
4293 | |||
4294 | if(levels != 0) { /* use as little memory as possible */ |
||
4295 | { |
||
4296 | int nextWidth= newwidth/2; |
||
4297 | int nextHeight= newheight/2; |
||
4298 | if (nextWidth < 1) nextWidth= 1; |
||
4299 | if (nextHeight < 1) nextHeight= 1; |
||
4300 | |||
4301 | memreq = image_size(nextWidth, nextHeight, format, type); |
||
4302 | } |
||
4303 | |||
4304 | switch(type) { |
||
4305 | case GL_UNSIGNED_BYTE: |
||
4306 | dstImage = (GLubyte *)malloc(memreq); |
||
4307 | break; |
||
4308 | case GL_BYTE: |
||
4309 | dstImage = (GLbyte *)malloc(memreq); |
||
4310 | break; |
||
4311 | case GL_UNSIGNED_SHORT: |
||
4312 | dstImage = (GLushort *)malloc(memreq); |
||
4313 | break; |
||
4314 | case GL_SHORT: |
||
4315 | dstImage = (GLshort *)malloc(memreq); |
||
4316 | break; |
||
4317 | case GL_UNSIGNED_INT: |
||
4318 | dstImage = (GLuint *)malloc(memreq); |
||
4319 | break; |
||
4320 | case GL_INT: |
||
4321 | dstImage = (GLint *)malloc(memreq); |
||
4322 | break; |
||
4323 | case GL_FLOAT: |
||
4324 | dstImage = (GLfloat *)malloc(memreq); |
||
4325 | break; |
||
4326 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4327 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4328 | dstImage = (GLubyte *)malloc(memreq); |
||
4329 | break; |
||
4330 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4331 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4332 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4333 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4334 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4335 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4336 | dstImage = (GLushort *)malloc(memreq); |
||
4337 | break; |
||
4338 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4339 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4340 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4341 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4342 | dstImage = (GLuint *)malloc(memreq); |
||
4343 | break; |
||
4344 | default: |
||
4345 | return GLU_INVALID_ENUM; |
||
4346 | } |
||
4347 | if (dstImage == NULL) { |
||
4348 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
4349 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
4350 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
4351 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
4352 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
4353 | free(srcImage); |
||
4354 | return GLU_OUT_OF_MEMORY; |
||
4355 | } |
||
4356 | } |
||
4357 | /* level userLevel is in srcImage; nothing saved yet */ |
||
4358 | level = userLevel; |
||
4359 | } |
||
4360 | |||
4361 | glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
||
4362 | if (baseLevel <= level && level <= maxLevel) { |
||
4363 | glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
||
4364 | format, type, (void *)srcImage); |
||
4365 | } |
||
4366 | |||
4367 | level++; /* update current level for the loop */ |
||
4368 | for (; level <= levels; level++) { |
||
4369 | switch(type) { |
||
4370 | case GL_UNSIGNED_BYTE: |
||
4371 | halveImage_ubyte(cmpts, newwidth, newheight, |
||
4372 | (GLubyte *)srcImage, (GLubyte *)dstImage, element_size, |
||
4373 | rowsize, group_size); |
||
4374 | break; |
||
4375 | case GL_BYTE: |
||
4376 | halveImage_byte(cmpts, newwidth, newheight, |
||
4377 | (GLbyte *)srcImage, (GLbyte *)dstImage, element_size, |
||
4378 | rowsize, group_size); |
||
4379 | break; |
||
4380 | case GL_UNSIGNED_SHORT: |
||
4381 | halveImage_ushort(cmpts, newwidth, newheight, |
||
4382 | (GLushort *)srcImage, (GLushort *)dstImage, element_size, |
||
4383 | rowsize, group_size, myswap_bytes); |
||
4384 | break; |
||
4385 | case GL_SHORT: |
||
4386 | halveImage_short(cmpts, newwidth, newheight, |
||
4387 | (GLshort *)srcImage, (GLshort *)dstImage, element_size, |
||
4388 | rowsize, group_size, myswap_bytes); |
||
4389 | break; |
||
4390 | case GL_UNSIGNED_INT: |
||
4391 | halveImage_uint(cmpts, newwidth, newheight, |
||
4392 | (GLuint *)srcImage, (GLuint *)dstImage, element_size, |
||
4393 | rowsize, group_size, myswap_bytes); |
||
4394 | break; |
||
4395 | case GL_INT: |
||
4396 | halveImage_int(cmpts, newwidth, newheight, |
||
4397 | (GLint *)srcImage, (GLint *)dstImage, element_size, |
||
4398 | rowsize, group_size, myswap_bytes); |
||
4399 | break; |
||
4400 | case GL_FLOAT: |
||
4401 | halveImage_float(cmpts, newwidth, newheight, |
||
4402 | (GLfloat *)srcImage, (GLfloat *)dstImage, element_size, |
||
4403 | rowsize, group_size, myswap_bytes); |
||
4404 | break; |
||
4405 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4406 | halveImagePackedPixel(3,extract332,shove332, |
||
4407 | newwidth,newheight, |
||
4408 | srcImage,dstImage,element_size,rowsize, |
||
4409 | myswap_bytes); |
||
4410 | break; |
||
4411 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4412 | halveImagePackedPixel(3,extract233rev,shove233rev, |
||
4413 | newwidth,newheight, |
||
4414 | srcImage,dstImage,element_size,rowsize, |
||
4415 | myswap_bytes); |
||
4416 | break; |
||
4417 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4418 | halveImagePackedPixel(3,extract565,shove565, |
||
4419 | newwidth,newheight, |
||
4420 | srcImage,dstImage,element_size,rowsize, |
||
4421 | myswap_bytes); |
||
4422 | break; |
||
4423 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4424 | halveImagePackedPixel(3,extract565rev,shove565rev, |
||
4425 | newwidth,newheight, |
||
4426 | srcImage,dstImage,element_size,rowsize, |
||
4427 | myswap_bytes); |
||
4428 | break; |
||
4429 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4430 | halveImagePackedPixel(4,extract4444,shove4444, |
||
4431 | newwidth,newheight, |
||
4432 | srcImage,dstImage,element_size,rowsize, |
||
4433 | myswap_bytes); |
||
4434 | break; |
||
4435 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4436 | halveImagePackedPixel(4,extract4444rev,shove4444rev, |
||
4437 | newwidth,newheight, |
||
4438 | srcImage,dstImage,element_size,rowsize, |
||
4439 | myswap_bytes); |
||
4440 | break; |
||
4441 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4442 | halveImagePackedPixel(4,extract5551,shove5551, |
||
4443 | newwidth,newheight, |
||
4444 | srcImage,dstImage,element_size,rowsize, |
||
4445 | myswap_bytes); |
||
4446 | break; |
||
4447 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4448 | halveImagePackedPixel(4,extract1555rev,shove1555rev, |
||
4449 | newwidth,newheight, |
||
4450 | srcImage,dstImage,element_size,rowsize, |
||
4451 | myswap_bytes); |
||
4452 | break; |
||
4453 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4454 | halveImagePackedPixel(4,extract8888,shove8888, |
||
4455 | newwidth,newheight, |
||
4456 | srcImage,dstImage,element_size,rowsize, |
||
4457 | myswap_bytes); |
||
4458 | break; |
||
4459 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4460 | halveImagePackedPixel(4,extract8888rev,shove8888rev, |
||
4461 | newwidth,newheight, |
||
4462 | srcImage,dstImage,element_size,rowsize, |
||
4463 | myswap_bytes); |
||
4464 | break; |
||
4465 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4466 | halveImagePackedPixel(4,extract1010102,shove1010102, |
||
4467 | newwidth,newheight, |
||
4468 | srcImage,dstImage,element_size,rowsize, |
||
4469 | myswap_bytes); |
||
4470 | break; |
||
4471 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4472 | halveImagePackedPixel(4,extract2101010rev,shove2101010rev, |
||
4473 | newwidth,newheight, |
||
4474 | srcImage,dstImage,element_size,rowsize, |
||
4475 | myswap_bytes); |
||
4476 | break; |
||
4477 | default: |
||
4478 | assert(0); |
||
4479 | break; |
||
4480 | } |
||
4481 | |||
4482 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
4483 | |||
4484 | if (newwidth > 1) { newwidth /= 2; rowsize /= 2;} |
||
4485 | if (newheight > 1) newheight /= 2; |
||
4486 | { |
||
4487 | /* compute amount to pad per row, if any */ |
||
4488 | int rowPad= rowsize % psm.unpack_alignment; |
||
4489 | |||
4490 | /* should row be padded? */ |
||
4491 | if (rowPad == 0) { /* nope, row should not be padded */ |
||
4492 | /* call tex image with srcImage untouched since it's not padded */ |
||
4493 | if (baseLevel <= level && level <= maxLevel) { |
||
4494 | glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
||
4495 | format, type, (void *) srcImage); |
||
4496 | } |
||
4497 | } |
||
4498 | else { /* yes, row should be padded */ |
||
4499 | /* compute length of new row in bytes, including padding */ |
||
4500 | int newRowLength= rowsize + psm.unpack_alignment - rowPad; |
||
4501 | int ii; unsigned char *dstTrav, *srcTrav; /* indices for copying */ |
||
4502 | |||
4503 | /* allocate new image for mipmap of size newRowLength x newheight */ |
||
4504 | void *newMipmapImage= malloc((size_t) (newRowLength*newheight)); |
||
4505 | if (newMipmapImage == NULL) { |
||
4506 | /* out of memory so return */ |
||
4507 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
4508 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
4509 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
4510 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
4511 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
4512 | return GLU_OUT_OF_MEMORY; |
||
4513 | } |
||
4514 | |||
4515 | /* copy image from srcImage into newMipmapImage by rows */ |
||
4516 | for (ii= 0, |
||
4517 | dstTrav= (unsigned char *) newMipmapImage, |
||
4518 | srcTrav= (unsigned char *) srcImage; |
||
4519 | ii< newheight; |
||
4520 | ii++, |
||
4521 | dstTrav+= newRowLength, /* make sure the correct distance... */ |
||
4522 | srcTrav+= rowsize) { /* ...is skipped */ |
||
4523 | memcpy(dstTrav,srcTrav,rowsize); |
||
4524 | /* note that the pad bytes are not visited and will contain |
||
4525 | * garbage, which is ok. |
||
4526 | */ |
||
4527 | } |
||
4528 | |||
4529 | /* ...and use this new image for mipmapping instead */ |
||
4530 | if (baseLevel <= level && level <= maxLevel) { |
||
4531 | glTexImage2D(target, level, internalFormat, newwidth, newheight, 0, |
||
4532 | format, type, newMipmapImage); |
||
4533 | } |
||
4534 | free(newMipmapImage); /* don't forget to free it! */ |
||
4535 | } /* else */ |
||
4536 | } |
||
4537 | } /* for level */ |
||
4538 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
4539 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
4540 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
4541 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
4542 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
4543 | |||
4544 | free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ |
||
4545 | if (dstImage) { /* if it's non-rectangular and only 1 level */ |
||
4546 | free(dstImage); |
||
4547 | } |
||
4548 | return 0; |
||
4549 | } /* gluBuild2DMipmapLevelsCore() */ |
||
4550 | |||
4551 | GLint GLAPIENTRY |
||
4552 | gluBuild2DMipmapLevels(GLenum target, GLint internalFormat, |
||
4553 | GLsizei width, GLsizei height, |
||
4554 | GLenum format, GLenum type, |
||
4555 | GLint userLevel, GLint baseLevel, GLint maxLevel, |
||
4556 | const void *data) |
||
4557 | { |
||
4558 | int level, levels; |
||
4559 | |||
4560 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
4561 | if (rc != 0) return rc; |
||
4562 | |||
4563 | if (width < 1 || height < 1) { |
||
4564 | return GLU_INVALID_VALUE; |
||
4565 | } |
||
4566 | |||
4567 | levels = computeLog(width); |
||
4568 | level = computeLog(height); |
||
4569 | if (level > levels) levels=level; |
||
4570 | |||
4571 | levels+= userLevel; |
||
4572 | if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
||
4573 | return GLU_INVALID_VALUE; |
||
4574 | |||
4575 | return gluBuild2DMipmapLevelsCore(target, internalFormat, |
||
4576 | width, height, |
||
4577 | width, height, |
||
4578 | format, type, |
||
4579 | userLevel, baseLevel, maxLevel, |
||
4580 | data); |
||
4581 | } /* gluBuild2DMipmapLevels() */ |
||
4582 | |||
4583 | GLint GLAPIENTRY |
||
4584 | gluBuild2DMipmaps(GLenum target, GLint internalFormat, |
||
4585 | GLsizei width, GLsizei height, |
||
4586 | GLenum format, GLenum type, |
||
4587 | const void *data) |
||
4588 | { |
||
4589 | GLint widthPowerOf2, heightPowerOf2; |
||
4590 | int level, levels; |
||
4591 | |||
4592 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
4593 | if (rc != 0) return rc; |
||
4594 | |||
4595 | if (width < 1 || height < 1) { |
||
4596 | return GLU_INVALID_VALUE; |
||
4597 | } |
||
4598 | |||
4599 | closestFit(target,width,height,internalFormat,format,type, |
||
4600 | &widthPowerOf2,&heightPowerOf2); |
||
4601 | |||
4602 | levels = computeLog(widthPowerOf2); |
||
4603 | level = computeLog(heightPowerOf2); |
||
4604 | if (level > levels) levels=level; |
||
4605 | |||
4606 | return gluBuild2DMipmapLevelsCore(target,internalFormat, |
||
4607 | width, height, |
||
4608 | widthPowerOf2,heightPowerOf2, |
||
4609 | format,type, |
||
4610 | 0,0,levels,data); |
||
4611 | } /* gluBuild2DMipmaps() */ |
||
4612 | |||
4613 | #if 0 |
||
4614 | /* |
||
4615 | ** This routine is for the limited case in which |
||
4616 | ** type == GL_UNSIGNED_BYTE && format != index && |
||
4617 | ** unpack_alignment = 1 && unpack_swap_bytes == false |
||
4618 | ** |
||
4619 | ** so all of the work data can be kept as ubytes instead of shorts. |
||
4620 | */ |
||
4621 | static int fastBuild2DMipmaps(const PixelStorageModes *psm, |
||
4622 | GLenum target, GLint components, GLint width, |
||
4623 | GLint height, GLenum format, |
||
4624 | GLenum type, void *data) |
||
4625 | { |
||
4626 | GLint newwidth, newheight; |
||
4627 | GLint level, levels; |
||
4628 | GLubyte *newImage; |
||
4629 | GLint newImage_width; |
||
4630 | GLint newImage_height; |
||
4631 | GLubyte *otherImage; |
||
4632 | GLubyte *imageTemp; |
||
4633 | GLint memreq; |
||
4634 | GLint cmpts; |
||
4635 | |||
4636 | |||
4637 | #if 0 |
||
4638 | glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize); |
||
4639 | newwidth = nearestPower(width); |
||
4640 | if (newwidth > maxsize) newwidth = maxsize; |
||
4641 | newheight = nearestPower(height); |
||
4642 | if (newheight > maxsize) newheight = maxsize; |
||
4643 | #else |
||
4644 | closestFit(target,width,height,components,format,type, |
||
4645 | &newwidth,&newheight); |
||
4646 | #endif |
||
4647 | levels = computeLog(newwidth); |
||
4648 | level = computeLog(newheight); |
||
4649 | if (level > levels) levels=level; |
||
4650 | |||
4651 | cmpts = elements_per_group(format,type); |
||
4652 | |||
4653 | otherImage = NULL; |
||
4654 | /** |
||
4655 | ** No need to copy the user data if its in the packed correctly. |
||
4656 | ** Make sure that later routines don't change that data. |
||
4657 | */ |
||
4658 | if (psm->unpack_skip_rows == 0 && psm->unpack_skip_pixels == 0) { |
||
4659 | newImage = (GLubyte *)data; |
||
4660 | newImage_width = width; |
||
4661 | newImage_height = height; |
||
4662 | } else { |
||
4663 | GLint rowsize; |
||
4664 | GLint groups_per_line; |
||
4665 | GLint elements_per_line; |
||
4666 | const GLubyte *start; |
||
4667 | const GLubyte *iter; |
||
4668 | GLubyte *iter2; |
||
4669 | GLint i, j; |
||
4670 | |||
4671 | newImage = (GLubyte *) |
||
4672 | malloc(image_size(width, height, format, GL_UNSIGNED_BYTE)); |
||
4673 | newImage_width = width; |
||
4674 | newImage_height = height; |
||
4675 | if (newImage == NULL) { |
||
4676 | return GLU_OUT_OF_MEMORY; |
||
4677 | } |
||
4678 | |||
4679 | /* |
||
4680 | ** Abbreviated version of fill_image for this restricted case. |
||
4681 | */ |
||
4682 | if (psm->unpack_row_length > 0) { |
||
4683 | groups_per_line = psm->unpack_row_length; |
||
4684 | } else { |
||
4685 | groups_per_line = width; |
||
4686 | } |
||
4687 | rowsize = groups_per_line * cmpts; |
||
4688 | elements_per_line = width * cmpts; |
||
4689 | start = (const GLubyte *) data + psm->unpack_skip_rows * rowsize + |
||
4690 | psm->unpack_skip_pixels * cmpts; |
||
4691 | iter2 = newImage; |
||
4692 | |||
4693 | for (i = 0; i < height; i++) { |
||
4694 | iter = start; |
||
4695 | for (j = 0; j < elements_per_line; j++) { |
||
4696 | *iter2 = *iter; |
||
4697 | iter++; |
||
4698 | iter2++; |
||
4699 | } |
||
4700 | start += rowsize; |
||
4701 | } |
||
4702 | } |
||
4703 | |||
4704 | |||
4705 | glPixelStorei(GL_UNPACK_ALIGNMENT, 1); |
||
4706 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
||
4707 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
||
4708 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
4709 | glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
||
4710 | |||
4711 | for (level = 0; level <= levels; level++) { |
||
4712 | if (newImage_width == newwidth && newImage_height == newheight) { |
||
4713 | /* Use newImage for this level */ |
||
4714 | glTexImage2D(target, level, components, newImage_width, |
||
4715 | newImage_height, 0, format, GL_UNSIGNED_BYTE, |
||
4716 | (void *) newImage); |
||
4717 | } else { |
||
4718 | if (otherImage == NULL) { |
||
4719 | memreq = |
||
4720 | image_size(newwidth, newheight, format, GL_UNSIGNED_BYTE); |
||
4721 | otherImage = (GLubyte *) malloc(memreq); |
||
4722 | if (otherImage == NULL) { |
||
4723 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); |
||
4724 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); |
||
4725 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); |
||
4726 | glPixelStorei(GL_UNPACK_ROW_LENGTH,psm->unpack_row_length); |
||
4727 | glPixelStorei(GL_UNPACK_SWAP_BYTES,psm->unpack_swap_bytes); |
||
4728 | return GLU_OUT_OF_MEMORY; |
||
4729 | } |
||
4730 | } |
||
4731 | /* |
||
4732 | scale_internal_ubyte(cmpts, newImage_width, newImage_height, |
||
4733 | newImage, newwidth, newheight, otherImage); |
||
4734 | */ |
||
4735 | /* Swap newImage and otherImage */ |
||
4736 | imageTemp = otherImage; |
||
4737 | otherImage = newImage; |
||
4738 | newImage = imageTemp; |
||
4739 | |||
4740 | newImage_width = newwidth; |
||
4741 | newImage_height = newheight; |
||
4742 | glTexImage2D(target, level, components, newImage_width, |
||
4743 | newImage_height, 0, format, GL_UNSIGNED_BYTE, |
||
4744 | (void *) newImage); |
||
4745 | } |
||
4746 | if (newwidth > 1) newwidth /= 2; |
||
4747 | if (newheight > 1) newheight /= 2; |
||
4748 | } |
||
4749 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm->unpack_alignment); |
||
4750 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm->unpack_skip_rows); |
||
4751 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm->unpack_skip_pixels); |
||
4752 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm->unpack_row_length); |
||
4753 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm->unpack_swap_bytes); |
||
4754 | |||
4755 | if (newImage != (const GLubyte *)data) { |
||
4756 | free((GLbyte *) newImage); |
||
4757 | } |
||
4758 | if (otherImage && otherImage != (const GLubyte *)data) { |
||
4759 | free((GLbyte *) otherImage); |
||
4760 | } |
||
4761 | return 0; |
||
4762 | } |
||
4763 | #endif |
||
4764 | |||
4765 | /* |
||
4766 | * Utility Routines |
||
4767 | */ |
||
4768 | static GLint elements_per_group(GLenum format, GLenum type) |
||
4769 | { |
||
4770 | /* |
||
4771 | * Return the number of elements per group of a specified format |
||
4772 | */ |
||
4773 | |||
4774 | /* If the type is packedpixels then answer is 1 (ignore format) */ |
||
4775 | if (type == GL_UNSIGNED_BYTE_3_3_2 || |
||
4776 | type == GL_UNSIGNED_BYTE_2_3_3_REV || |
||
4777 | type == GL_UNSIGNED_SHORT_5_6_5 || |
||
4778 | type == GL_UNSIGNED_SHORT_5_6_5_REV || |
||
4779 | type == GL_UNSIGNED_SHORT_4_4_4_4 || |
||
4780 | type == GL_UNSIGNED_SHORT_4_4_4_4_REV || |
||
4781 | type == GL_UNSIGNED_SHORT_5_5_5_1 || |
||
4782 | type == GL_UNSIGNED_SHORT_1_5_5_5_REV || |
||
4783 | type == GL_UNSIGNED_INT_8_8_8_8 || |
||
4784 | type == GL_UNSIGNED_INT_8_8_8_8_REV || |
||
4785 | type == GL_UNSIGNED_INT_10_10_10_2 || |
||
4786 | type == GL_UNSIGNED_INT_2_10_10_10_REV) { |
||
4787 | return 1; |
||
4788 | } |
||
4789 | |||
4790 | /* Types are not packed pixels, so get elements per group */ |
||
4791 | switch(format) { |
||
4792 | case GL_RGB: |
||
4793 | case GL_BGR: |
||
4794 | return 3; |
||
4795 | case GL_LUMINANCE_ALPHA: |
||
4796 | return 2; |
||
4797 | case GL_RGBA: |
||
4798 | case GL_BGRA: |
||
4799 | return 4; |
||
4800 | default: |
||
4801 | return 1; |
||
4802 | } |
||
4803 | } |
||
4804 | |||
4805 | static GLfloat bytes_per_element(GLenum type) |
||
4806 | { |
||
4807 | /* |
||
4808 | * Return the number of bytes per element, based on the element type |
||
4809 | */ |
||
4810 | switch(type) { |
||
4811 | case GL_BITMAP: |
||
4812 | return 1.0 / 8.0; |
||
4813 | case GL_UNSIGNED_SHORT: |
||
4814 | return(sizeof(GLushort)); |
||
4815 | case GL_SHORT: |
||
4816 | return(sizeof(GLshort)); |
||
4817 | case GL_UNSIGNED_BYTE: |
||
4818 | return(sizeof(GLubyte)); |
||
4819 | case GL_BYTE: |
||
4820 | return(sizeof(GLbyte)); |
||
4821 | case GL_INT: |
||
4822 | return(sizeof(GLint)); |
||
4823 | case GL_UNSIGNED_INT: |
||
4824 | return(sizeof(GLuint)); |
||
4825 | case GL_FLOAT: |
||
4826 | return(sizeof(GLfloat)); |
||
4827 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4828 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4829 | return(sizeof(GLubyte)); |
||
4830 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4831 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
4832 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
4833 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
4834 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
4835 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
4836 | return(sizeof(GLushort)); |
||
4837 | case GL_UNSIGNED_INT_8_8_8_8: |
||
4838 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
4839 | case GL_UNSIGNED_INT_10_10_10_2: |
||
4840 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
4841 | return(sizeof(GLuint)); |
||
4842 | default: |
||
4843 | return 4; |
||
4844 | } |
||
4845 | } |
||
4846 | |||
4847 | static GLint is_index(GLenum format) |
||
4848 | { |
||
4849 | return format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX; |
||
4850 | } |
||
4851 | |||
4852 | /* |
||
4853 | ** Compute memory required for internal packed array of data of given type |
||
4854 | ** and format. |
||
4855 | */ |
||
4856 | static GLint image_size(GLint width, GLint height, GLenum format, GLenum type) |
||
4857 | { |
||
4858 | int bytes_per_row; |
||
4859 | int components; |
||
4860 | |||
4861 | assert(width > 0); |
||
4862 | assert(height > 0); |
||
4863 | components = elements_per_group(format,type); |
||
4864 | if (type == GL_BITMAP) { |
||
4865 | bytes_per_row = (width + 7) / 8; |
||
4866 | } else { |
||
4867 | bytes_per_row = bytes_per_element(type) * width; |
||
4868 | } |
||
4869 | return bytes_per_row * height * components; |
||
4870 | } |
||
4871 | |||
4872 | /* |
||
4873 | ** Extract array from user's data applying all pixel store modes. |
||
4874 | ** The internal format used is an array of unsigned shorts. |
||
4875 | */ |
||
4876 | static void fill_image(const PixelStorageModes *psm, |
||
4877 | GLint width, GLint height, GLenum format, |
||
4878 | GLenum type, GLboolean index_format, |
||
4879 | const void *userdata, GLushort *newimage) |
||
4880 | { |
||
4881 | GLint components; |
||
4882 | GLint element_size; |
||
4883 | GLint rowsize; |
||
4884 | GLint padding; |
||
4885 | GLint groups_per_line; |
||
4886 | GLint group_size; |
||
4887 | GLint elements_per_line; |
||
4888 | const GLubyte *start; |
||
4889 | const GLubyte *iter; |
||
4890 | GLushort *iter2; |
||
4891 | GLint i, j, k; |
||
4892 | GLint myswap_bytes; |
||
4893 | |||
4894 | myswap_bytes = psm->unpack_swap_bytes; |
||
4895 | components = elements_per_group(format,type); |
||
4896 | if (psm->unpack_row_length > 0) { |
||
4897 | groups_per_line = psm->unpack_row_length; |
||
4898 | } else { |
||
4899 | groups_per_line = width; |
||
4900 | } |
||
4901 | |||
4902 | /* All formats except GL_BITMAP fall out trivially */ |
||
4903 | if (type == GL_BITMAP) { |
||
4904 | GLint bit_offset; |
||
4905 | GLint current_bit; |
||
4906 | |||
4907 | rowsize = (groups_per_line * components + 7) / 8; |
||
4908 | padding = (rowsize % psm->unpack_alignment); |
||
4909 | if (padding) { |
||
4910 | rowsize += psm->unpack_alignment - padding; |
||
4911 | } |
||
4912 | start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + |
||
4913 | (psm->unpack_skip_pixels * components / 8); |
||
4914 | elements_per_line = width * components; |
||
4915 | iter2 = newimage; |
||
4916 | for (i = 0; i < height; i++) { |
||
4917 | iter = start; |
||
4918 | bit_offset = (psm->unpack_skip_pixels * components) % 8; |
||
4919 | for (j = 0; j < elements_per_line; j++) { |
||
4920 | /* Retrieve bit */ |
||
4921 | if (psm->unpack_lsb_first) { |
||
4922 | current_bit = iter[0] & (1 << bit_offset); |
||
4923 | } else { |
||
4924 | current_bit = iter[0] & (1 << (7 - bit_offset)); |
||
4925 | } |
||
4926 | if (current_bit) { |
||
4927 | if (index_format) { |
||
4928 | *iter2 = 1; |
||
4929 | } else { |
||
4930 | *iter2 = 65535; |
||
4931 | } |
||
4932 | } else { |
||
4933 | *iter2 = 0; |
||
4934 | } |
||
4935 | bit_offset++; |
||
4936 | if (bit_offset == 8) { |
||
4937 | bit_offset = 0; |
||
4938 | iter++; |
||
4939 | } |
||
4940 | iter2++; |
||
4941 | } |
||
4942 | start += rowsize; |
||
4943 | } |
||
4944 | } else { |
||
4945 | element_size = bytes_per_element(type); |
||
4946 | group_size = element_size * components; |
||
4947 | if (element_size == 1) myswap_bytes = 0; |
||
4948 | |||
4949 | rowsize = groups_per_line * group_size; |
||
4950 | padding = (rowsize % psm->unpack_alignment); |
||
4951 | if (padding) { |
||
4952 | rowsize += psm->unpack_alignment - padding; |
||
4953 | } |
||
4954 | start = (const GLubyte *) userdata + psm->unpack_skip_rows * rowsize + |
||
4955 | psm->unpack_skip_pixels * group_size; |
||
4956 | elements_per_line = width * components; |
||
4957 | |||
4958 | iter2 = newimage; |
||
4959 | for (i = 0; i < height; i++) { |
||
4960 | iter = start; |
||
4961 | for (j = 0; j < elements_per_line; j++) { |
||
4962 | Type_Widget widget; |
||
4963 | float extractComponents[4]; |
||
4964 | |||
4965 | switch(type) { |
||
4966 | case GL_UNSIGNED_BYTE_3_3_2: |
||
4967 | extract332(0,iter,extractComponents); |
||
4968 | for (k = 0; k < 3; k++) { |
||
4969 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
4970 | } |
||
4971 | break; |
||
4972 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
4973 | extract233rev(0,iter,extractComponents); |
||
4974 | for (k = 0; k < 3; k++) { |
||
4975 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
4976 | } |
||
4977 | break; |
||
4978 | case GL_UNSIGNED_BYTE: |
||
4979 | if (index_format) { |
||
4980 | *iter2++ = *iter; |
||
4981 | } else { |
||
4982 | *iter2++ = (*iter) * 257; |
||
4983 | } |
||
4984 | break; |
||
4985 | case GL_BYTE: |
||
4986 | if (index_format) { |
||
4987 | *iter2++ = *((const GLbyte *) iter); |
||
4988 | } else { |
||
4989 | /* rough approx */ |
||
4990 | *iter2++ = (*((const GLbyte *) iter)) * 516; |
||
4991 | } |
||
4992 | break; |
||
4993 | case GL_UNSIGNED_SHORT_5_6_5: |
||
4994 | extract565(myswap_bytes,iter,extractComponents); |
||
4995 | for (k = 0; k < 3; k++) { |
||
4996 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
4997 | } |
||
4998 | break; |
||
4999 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
5000 | extract565rev(myswap_bytes,iter,extractComponents); |
||
5001 | for (k = 0; k < 3; k++) { |
||
5002 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5003 | } |
||
5004 | break; |
||
5005 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
5006 | extract4444(myswap_bytes,iter,extractComponents); |
||
5007 | for (k = 0; k < 4; k++) { |
||
5008 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5009 | } |
||
5010 | break; |
||
5011 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
5012 | extract4444rev(myswap_bytes,iter,extractComponents); |
||
5013 | for (k = 0; k < 4; k++) { |
||
5014 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5015 | } |
||
5016 | break; |
||
5017 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
5018 | extract5551(myswap_bytes,iter,extractComponents); |
||
5019 | for (k = 0; k < 4; k++) { |
||
5020 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5021 | } |
||
5022 | break; |
||
5023 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
5024 | extract1555rev(myswap_bytes,iter,extractComponents); |
||
5025 | for (k = 0; k < 4; k++) { |
||
5026 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5027 | } |
||
5028 | break; |
||
5029 | case GL_UNSIGNED_SHORT: |
||
5030 | case GL_SHORT: |
||
5031 | if (myswap_bytes) { |
||
5032 | widget.ub[0] = iter[1]; |
||
5033 | widget.ub[1] = iter[0]; |
||
5034 | } else { |
||
5035 | widget.ub[0] = iter[0]; |
||
5036 | widget.ub[1] = iter[1]; |
||
5037 | } |
||
5038 | if (type == GL_SHORT) { |
||
5039 | if (index_format) { |
||
5040 | *iter2++ = widget.s[0]; |
||
5041 | } else { |
||
5042 | /* rough approx */ |
||
5043 | *iter2++ = widget.s[0]*2; |
||
5044 | } |
||
5045 | } else { |
||
5046 | *iter2++ = widget.us[0]; |
||
5047 | } |
||
5048 | break; |
||
5049 | case GL_UNSIGNED_INT_8_8_8_8: |
||
5050 | extract8888(myswap_bytes,iter,extractComponents); |
||
5051 | for (k = 0; k < 4; k++) { |
||
5052 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5053 | } |
||
5054 | break; |
||
5055 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
5056 | extract8888rev(myswap_bytes,iter,extractComponents); |
||
5057 | for (k = 0; k < 4; k++) { |
||
5058 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5059 | } |
||
5060 | break; |
||
5061 | case GL_UNSIGNED_INT_10_10_10_2: |
||
5062 | extract1010102(myswap_bytes,iter,extractComponents); |
||
5063 | for (k = 0; k < 4; k++) { |
||
5064 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5065 | } |
||
5066 | break; |
||
5067 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
5068 | extract2101010rev(myswap_bytes,iter,extractComponents); |
||
5069 | for (k = 0; k < 4; k++) { |
||
5070 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
5071 | } |
||
5072 | break; |
||
5073 | case GL_INT: |
||
5074 | case GL_UNSIGNED_INT: |
||
5075 | case GL_FLOAT: |
||
5076 | if (myswap_bytes) { |
||
5077 | widget.ub[0] = iter[3]; |
||
5078 | widget.ub[1] = iter[2]; |
||
5079 | widget.ub[2] = iter[1]; |
||
5080 | widget.ub[3] = iter[0]; |
||
5081 | } else { |
||
5082 | widget.ub[0] = iter[0]; |
||
5083 | widget.ub[1] = iter[1]; |
||
5084 | widget.ub[2] = iter[2]; |
||
5085 | widget.ub[3] = iter[3]; |
||
5086 | } |
||
5087 | if (type == GL_FLOAT) { |
||
5088 | if (index_format) { |
||
5089 | *iter2++ = widget.f; |
||
5090 | } else { |
||
5091 | *iter2++ = 65535 * widget.f; |
||
5092 | } |
||
5093 | } else if (type == GL_UNSIGNED_INT) { |
||
5094 | if (index_format) { |
||
5095 | *iter2++ = widget.ui; |
||
5096 | } else { |
||
5097 | *iter2++ = widget.ui >> 16; |
||
5098 | } |
||
5099 | } else { |
||
5100 | if (index_format) { |
||
5101 | *iter2++ = widget.i; |
||
5102 | } else { |
||
5103 | *iter2++ = widget.i >> 15; |
||
5104 | } |
||
5105 | } |
||
5106 | break; |
||
5107 | } |
||
5108 | iter += element_size; |
||
5109 | } /* for j */ |
||
5110 | start += rowsize; |
||
5111 | #if 1 |
||
5112 | /* want 'iter' pointing at start, not within, row for assertion |
||
5113 | * purposes |
||
5114 | */ |
||
5115 | iter= start; |
||
5116 | #endif |
||
5117 | } /* for i */ |
||
5118 | |||
5119 | /* iterators should be one byte past end */ |
||
5120 | if (!isTypePackedPixel(type)) { |
||
5121 | assert(iter2 == &newimage[width*height*components]); |
||
5122 | } |
||
5123 | else { |
||
5124 | assert(iter2 == &newimage[width*height* |
||
5125 | elements_per_group(format,0)]); |
||
5126 | } |
||
5127 | assert( iter == &((const GLubyte *)userdata)[rowsize*height + |
||
5128 | psm->unpack_skip_rows * rowsize + |
||
5129 | psm->unpack_skip_pixels * group_size] ); |
||
5130 | |||
5131 | } /* else */ |
||
5132 | } /* fill_image() */ |
||
5133 | |||
5134 | /* |
||
5135 | ** Insert array into user's data applying all pixel store modes. |
||
5136 | ** The internal format is an array of unsigned shorts. |
||
5137 | ** empty_image() because it is the opposite of fill_image(). |
||
5138 | */ |
||
5139 | static void empty_image(const PixelStorageModes *psm, |
||
5140 | GLint width, GLint height, GLenum format, |
||
5141 | GLenum type, GLboolean index_format, |
||
5142 | const GLushort *oldimage, void *userdata) |
||
5143 | { |
||
5144 | GLint components; |
||
5145 | GLint element_size; |
||
5146 | GLint rowsize; |
||
5147 | GLint padding; |
||
5148 | GLint groups_per_line; |
||
5149 | GLint group_size; |
||
5150 | GLint elements_per_line; |
||
5151 | GLubyte *start; |
||
5152 | GLubyte *iter; |
||
5153 | const GLushort *iter2; |
||
5154 | GLint i, j, k; |
||
5155 | GLint myswap_bytes; |
||
5156 | |||
5157 | myswap_bytes = psm->pack_swap_bytes; |
||
5158 | components = elements_per_group(format,type); |
||
5159 | if (psm->pack_row_length > 0) { |
||
5160 | groups_per_line = psm->pack_row_length; |
||
5161 | } else { |
||
5162 | groups_per_line = width; |
||
5163 | } |
||
5164 | |||
5165 | /* All formats except GL_BITMAP fall out trivially */ |
||
5166 | if (type == GL_BITMAP) { |
||
5167 | GLint bit_offset; |
||
5168 | GLint current_bit; |
||
5169 | |||
5170 | rowsize = (groups_per_line * components + 7) / 8; |
||
5171 | padding = (rowsize % psm->pack_alignment); |
||
5172 | if (padding) { |
||
5173 | rowsize += psm->pack_alignment - padding; |
||
5174 | } |
||
5175 | start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + |
||
5176 | (psm->pack_skip_pixels * components / 8); |
||
5177 | elements_per_line = width * components; |
||
5178 | iter2 = oldimage; |
||
5179 | for (i = 0; i < height; i++) { |
||
5180 | iter = start; |
||
5181 | bit_offset = (psm->pack_skip_pixels * components) % 8; |
||
5182 | for (j = 0; j < elements_per_line; j++) { |
||
5183 | if (index_format) { |
||
5184 | current_bit = iter2[0] & 1; |
||
5185 | } else { |
||
5186 | if (iter2[0] > 32767) { |
||
5187 | current_bit = 1; |
||
5188 | } else { |
||
5189 | current_bit = 0; |
||
5190 | } |
||
5191 | } |
||
5192 | |||
5193 | if (current_bit) { |
||
5194 | if (psm->pack_lsb_first) { |
||
5195 | *iter |= (1 << bit_offset); |
||
5196 | } else { |
||
5197 | *iter |= (1 << (7 - bit_offset)); |
||
5198 | } |
||
5199 | } else { |
||
5200 | if (psm->pack_lsb_first) { |
||
5201 | *iter &= ~(1 << bit_offset); |
||
5202 | } else { |
||
5203 | *iter &= ~(1 << (7 - bit_offset)); |
||
5204 | } |
||
5205 | } |
||
5206 | |||
5207 | bit_offset++; |
||
5208 | if (bit_offset == 8) { |
||
5209 | bit_offset = 0; |
||
5210 | iter++; |
||
5211 | } |
||
5212 | iter2++; |
||
5213 | } |
||
5214 | start += rowsize; |
||
5215 | } |
||
5216 | } else { |
||
5217 | float shoveComponents[4]; |
||
5218 | |||
5219 | element_size = bytes_per_element(type); |
||
5220 | group_size = element_size * components; |
||
5221 | if (element_size == 1) myswap_bytes = 0; |
||
5222 | |||
5223 | rowsize = groups_per_line * group_size; |
||
5224 | padding = (rowsize % psm->pack_alignment); |
||
5225 | if (padding) { |
||
5226 | rowsize += psm->pack_alignment - padding; |
||
5227 | } |
||
5228 | start = (GLubyte *) userdata + psm->pack_skip_rows * rowsize + |
||
5229 | psm->pack_skip_pixels * group_size; |
||
5230 | elements_per_line = width * components; |
||
5231 | |||
5232 | iter2 = oldimage; |
||
5233 | for (i = 0; i < height; i++) { |
||
5234 | iter = start; |
||
5235 | for (j = 0; j < elements_per_line; j++) { |
||
5236 | Type_Widget widget; |
||
5237 | |||
5238 | switch(type) { |
||
5239 | case GL_UNSIGNED_BYTE_3_3_2: |
||
5240 | for (k = 0; k < 3; k++) { |
||
5241 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5242 | } |
||
5243 | shove332(shoveComponents,0,(void *)iter); |
||
5244 | break; |
||
5245 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
5246 | for (k = 0; k < 3; k++) { |
||
5247 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5248 | } |
||
5249 | shove233rev(shoveComponents,0,(void *)iter); |
||
5250 | break; |
||
5251 | case GL_UNSIGNED_BYTE: |
||
5252 | if (index_format) { |
||
5253 | *iter = *iter2++; |
||
5254 | } else { |
||
5255 | *iter = *iter2++ >> 8; |
||
5256 | } |
||
5257 | break; |
||
5258 | case GL_BYTE: |
||
5259 | if (index_format) { |
||
5260 | *((GLbyte *) iter) = *iter2++; |
||
5261 | } else { |
||
5262 | *((GLbyte *) iter) = *iter2++ >> 9; |
||
5263 | } |
||
5264 | break; |
||
5265 | case GL_UNSIGNED_SHORT_5_6_5: |
||
5266 | for (k = 0; k < 3; k++) { |
||
5267 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5268 | } |
||
5269 | shove565(shoveComponents,0,(void *)&widget.us[0]); |
||
5270 | if (myswap_bytes) { |
||
5271 | iter[0] = widget.ub[1]; |
||
5272 | iter[1] = widget.ub[0]; |
||
5273 | } |
||
5274 | else { |
||
5275 | *(GLushort *)iter = widget.us[0]; |
||
5276 | } |
||
5277 | break; |
||
5278 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
5279 | for (k = 0; k < 3; k++) { |
||
5280 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5281 | } |
||
5282 | shove565rev(shoveComponents,0,(void *)&widget.us[0]); |
||
5283 | if (myswap_bytes) { |
||
5284 | iter[0] = widget.ub[1]; |
||
5285 | iter[1] = widget.ub[0]; |
||
5286 | } |
||
5287 | else { |
||
5288 | *(GLushort *)iter = widget.us[0]; |
||
5289 | } |
||
5290 | break; |
||
5291 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
5292 | for (k = 0; k < 4; k++) { |
||
5293 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5294 | } |
||
5295 | shove4444(shoveComponents,0,(void *)&widget.us[0]); |
||
5296 | if (myswap_bytes) { |
||
5297 | iter[0] = widget.ub[1]; |
||
5298 | iter[1] = widget.ub[0]; |
||
5299 | } else { |
||
5300 | *(GLushort *)iter = widget.us[0]; |
||
5301 | } |
||
5302 | break; |
||
5303 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
5304 | for (k = 0; k < 4; k++) { |
||
5305 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5306 | } |
||
5307 | shove4444rev(shoveComponents,0,(void *)&widget.us[0]); |
||
5308 | if (myswap_bytes) { |
||
5309 | iter[0] = widget.ub[1]; |
||
5310 | iter[1] = widget.ub[0]; |
||
5311 | } else { |
||
5312 | *(GLushort *)iter = widget.us[0]; |
||
5313 | } |
||
5314 | break; |
||
5315 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
5316 | for (k = 0; k < 4; k++) { |
||
5317 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5318 | } |
||
5319 | shove5551(shoveComponents,0,(void *)&widget.us[0]); |
||
5320 | if (myswap_bytes) { |
||
5321 | iter[0] = widget.ub[1]; |
||
5322 | iter[1] = widget.ub[0]; |
||
5323 | } else { |
||
5324 | *(GLushort *)iter = widget.us[0]; |
||
5325 | } |
||
5326 | break; |
||
5327 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
5328 | for (k = 0; k < 4; k++) { |
||
5329 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5330 | } |
||
5331 | shove1555rev(shoveComponents,0,(void *)&widget.us[0]); |
||
5332 | if (myswap_bytes) { |
||
5333 | iter[0] = widget.ub[1]; |
||
5334 | iter[1] = widget.ub[0]; |
||
5335 | } else { |
||
5336 | *(GLushort *)iter = widget.us[0]; |
||
5337 | } |
||
5338 | break; |
||
5339 | case GL_UNSIGNED_SHORT: |
||
5340 | case GL_SHORT: |
||
5341 | if (type == GL_SHORT) { |
||
5342 | if (index_format) { |
||
5343 | widget.s[0] = *iter2++; |
||
5344 | } else { |
||
5345 | widget.s[0] = *iter2++ >> 1; |
||
5346 | } |
||
5347 | } else { |
||
5348 | widget.us[0] = *iter2++; |
||
5349 | } |
||
5350 | if (myswap_bytes) { |
||
5351 | iter[0] = widget.ub[1]; |
||
5352 | iter[1] = widget.ub[0]; |
||
5353 | } else { |
||
5354 | iter[0] = widget.ub[0]; |
||
5355 | iter[1] = widget.ub[1]; |
||
5356 | } |
||
5357 | break; |
||
5358 | case GL_UNSIGNED_INT_8_8_8_8: |
||
5359 | for (k = 0; k < 4; k++) { |
||
5360 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5361 | } |
||
5362 | shove8888(shoveComponents,0,(void *)&widget.ui); |
||
5363 | if (myswap_bytes) { |
||
5364 | iter[3] = widget.ub[0]; |
||
5365 | iter[2] = widget.ub[1]; |
||
5366 | iter[1] = widget.ub[2]; |
||
5367 | iter[0] = widget.ub[3]; |
||
5368 | } else { |
||
5369 | *(GLuint *)iter= widget.ui; |
||
5370 | } |
||
5371 | |||
5372 | break; |
||
5373 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
5374 | for (k = 0; k < 4; k++) { |
||
5375 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5376 | } |
||
5377 | shove8888rev(shoveComponents,0,(void *)&widget.ui); |
||
5378 | if (myswap_bytes) { |
||
5379 | iter[3] = widget.ub[0]; |
||
5380 | iter[2] = widget.ub[1]; |
||
5381 | iter[1] = widget.ub[2]; |
||
5382 | iter[0] = widget.ub[3]; |
||
5383 | } else { |
||
5384 | *(GLuint *)iter= widget.ui; |
||
5385 | } |
||
5386 | break; |
||
5387 | case GL_UNSIGNED_INT_10_10_10_2: |
||
5388 | for (k = 0; k < 4; k++) { |
||
5389 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5390 | } |
||
5391 | shove1010102(shoveComponents,0,(void *)&widget.ui); |
||
5392 | if (myswap_bytes) { |
||
5393 | iter[3] = widget.ub[0]; |
||
5394 | iter[2] = widget.ub[1]; |
||
5395 | iter[1] = widget.ub[2]; |
||
5396 | iter[0] = widget.ub[3]; |
||
5397 | } else { |
||
5398 | *(GLuint *)iter= widget.ui; |
||
5399 | } |
||
5400 | break; |
||
5401 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
5402 | for (k = 0; k < 4; k++) { |
||
5403 | shoveComponents[k]= *iter2++ / 65535.0; |
||
5404 | } |
||
5405 | shove2101010rev(shoveComponents,0,(void *)&widget.ui); |
||
5406 | if (myswap_bytes) { |
||
5407 | iter[3] = widget.ub[0]; |
||
5408 | iter[2] = widget.ub[1]; |
||
5409 | iter[1] = widget.ub[2]; |
||
5410 | iter[0] = widget.ub[3]; |
||
5411 | } else { |
||
5412 | *(GLuint *)iter= widget.ui; |
||
5413 | } |
||
5414 | break; |
||
5415 | case GL_INT: |
||
5416 | case GL_UNSIGNED_INT: |
||
5417 | case GL_FLOAT: |
||
5418 | if (type == GL_FLOAT) { |
||
5419 | if (index_format) { |
||
5420 | widget.f = *iter2++; |
||
5421 | } else { |
||
5422 | widget.f = *iter2++ / (float) 65535.0; |
||
5423 | } |
||
5424 | } else if (type == GL_UNSIGNED_INT) { |
||
5425 | if (index_format) { |
||
5426 | widget.ui = *iter2++; |
||
5427 | } else { |
||
5428 | widget.ui = (unsigned int) *iter2++ * 65537; |
||
5429 | } |
||
5430 | } else { |
||
5431 | if (index_format) { |
||
5432 | widget.i = *iter2++; |
||
5433 | } else { |
||
5434 | widget.i = ((unsigned int) *iter2++ * 65537)/2; |
||
5435 | } |
||
5436 | } |
||
5437 | if (myswap_bytes) { |
||
5438 | iter[3] = widget.ub[0]; |
||
5439 | iter[2] = widget.ub[1]; |
||
5440 | iter[1] = widget.ub[2]; |
||
5441 | iter[0] = widget.ub[3]; |
||
5442 | } else { |
||
5443 | iter[0] = widget.ub[0]; |
||
5444 | iter[1] = widget.ub[1]; |
||
5445 | iter[2] = widget.ub[2]; |
||
5446 | iter[3] = widget.ub[3]; |
||
5447 | } |
||
5448 | break; |
||
5449 | } |
||
5450 | iter += element_size; |
||
5451 | } /* for j */ |
||
5452 | start += rowsize; |
||
5453 | #if 1 |
||
5454 | /* want 'iter' pointing at start, not within, row for assertion |
||
5455 | * purposes |
||
5456 | */ |
||
5457 | iter= start; |
||
5458 | #endif |
||
5459 | } /* for i */ |
||
5460 | |||
5461 | /* iterators should be one byte past end */ |
||
5462 | if (!isTypePackedPixel(type)) { |
||
5463 | assert(iter2 == &oldimage[width*height*components]); |
||
5464 | } |
||
5465 | else { |
||
5466 | assert(iter2 == &oldimage[width*height* |
||
5467 | elements_per_group(format,0)]); |
||
5468 | } |
||
5469 | assert( iter == &((GLubyte *)userdata)[rowsize*height + |
||
5470 | psm->pack_skip_rows * rowsize + |
||
5471 | psm->pack_skip_pixels * group_size] ); |
||
5472 | |||
5473 | } /* else */ |
||
5474 | } /* empty_image() */ |
||
5475 | |||
5476 | /*-------------------------------------------------------------------------- |
||
5477 | * Decimation of packed pixel types |
||
5478 | *-------------------------------------------------------------------------- |
||
5479 | */ |
||
5480 | static void extract332(int isSwap, |
||
5481 | const void *packedPixel, GLfloat extractComponents[]) |
||
5482 | { |
||
5483 | GLubyte ubyte= *(const GLubyte *)packedPixel; |
||
5484 | |||
5485 | isSwap= isSwap; /* turn off warnings */ |
||
5486 | |||
5487 | /* 11100000 == 0xe0 */ |
||
5488 | /* 00011100 == 0x1c */ |
||
5489 | /* 00000011 == 0x03 */ |
||
5490 | |||
5491 | extractComponents[0]= (float)((ubyte & 0xe0) >> 5) / 7.0; |
||
5492 | extractComponents[1]= (float)((ubyte & 0x1c) >> 2) / 7.0; /* 7 = 2^3-1 */ |
||
5493 | extractComponents[2]= (float)((ubyte & 0x03) ) / 3.0; /* 3 = 2^2-1 */ |
||
5494 | } /* extract332() */ |
||
5495 | |||
5496 | static void shove332(const GLfloat shoveComponents[], |
||
5497 | int index, void *packedPixel) |
||
5498 | { |
||
5499 | /* 11100000 == 0xe0 */ |
||
5500 | /* 00011100 == 0x1c */ |
||
5501 | /* 00000011 == 0x03 */ |
||
5502 | |||
5503 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5504 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5505 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5506 | |||
5507 | /* due to limited precision, need to round before shoving */ |
||
5508 | ((GLubyte *)packedPixel)[index] = |
||
5509 | ((GLubyte)((shoveComponents[0] * 7)+0.5) << 5) & 0xe0; |
||
5510 | ((GLubyte *)packedPixel)[index] |= |
||
5511 | ((GLubyte)((shoveComponents[1] * 7)+0.5) << 2) & 0x1c; |
||
5512 | ((GLubyte *)packedPixel)[index] |= |
||
5513 | ((GLubyte)((shoveComponents[2] * 3)+0.5) ) & 0x03; |
||
5514 | } /* shove332() */ |
||
5515 | |||
5516 | static void extract233rev(int isSwap, |
||
5517 | const void *packedPixel, GLfloat extractComponents[]) |
||
5518 | { |
||
5519 | GLubyte ubyte= *(const GLubyte *)packedPixel; |
||
5520 | |||
5521 | isSwap= isSwap; /* turn off warnings */ |
||
5522 | |||
5523 | /* 0000,0111 == 0x07 */ |
||
5524 | /* 0011,1000 == 0x38 */ |
||
5525 | /* 1100,0000 == 0xC0 */ |
||
5526 | |||
5527 | extractComponents[0]= (float)((ubyte & 0x07) ) / 7.0; |
||
5528 | extractComponents[1]= (float)((ubyte & 0x38) >> 3) / 7.0; |
||
5529 | extractComponents[2]= (float)((ubyte & 0xC0) >> 6) / 3.0; |
||
5530 | } /* extract233rev() */ |
||
5531 | |||
5532 | static void shove233rev(const GLfloat shoveComponents[], |
||
5533 | int index, void *packedPixel) |
||
5534 | { |
||
5535 | /* 0000,0111 == 0x07 */ |
||
5536 | /* 0011,1000 == 0x38 */ |
||
5537 | /* 1100,0000 == 0xC0 */ |
||
5538 | |||
5539 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5540 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5541 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5542 | |||
5543 | /* due to limited precision, need to round before shoving */ |
||
5544 | ((GLubyte *)packedPixel)[index] = |
||
5545 | ((GLubyte)((shoveComponents[0] * 7.0)+0.5) ) & 0x07; |
||
5546 | ((GLubyte *)packedPixel)[index]|= |
||
5547 | ((GLubyte)((shoveComponents[1] * 7.0)+0.5) << 3) & 0x38; |
||
5548 | ((GLubyte *)packedPixel)[index]|= |
||
5549 | ((GLubyte)((shoveComponents[2] * 3.0)+0.5) << 6) & 0xC0; |
||
5550 | } /* shove233rev() */ |
||
5551 | |||
5552 | static void extract565(int isSwap, |
||
5553 | const void *packedPixel, GLfloat extractComponents[]) |
||
5554 | { |
||
5555 | GLushort ushort; |
||
5556 | |||
5557 | if (isSwap) { |
||
5558 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5559 | } |
||
5560 | else { |
||
5561 | ushort= *(const GLushort *)packedPixel; |
||
5562 | } |
||
5563 | |||
5564 | /* 11111000,00000000 == 0xf800 */ |
||
5565 | /* 00000111,11100000 == 0x07e0 */ |
||
5566 | /* 00000000,00011111 == 0x001f */ |
||
5567 | |||
5568 | extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ |
||
5569 | extractComponents[1]=(float)((ushort & 0x07e0) >> 5) / 63.0;/* 63 = 2^6-1*/ |
||
5570 | extractComponents[2]=(float)((ushort & 0x001f) ) / 31.0; |
||
5571 | } /* extract565() */ |
||
5572 | |||
5573 | static void shove565(const GLfloat shoveComponents[], |
||
5574 | int index,void *packedPixel) |
||
5575 | { |
||
5576 | /* 11111000,00000000 == 0xf800 */ |
||
5577 | /* 00000111,11100000 == 0x07e0 */ |
||
5578 | /* 00000000,00011111 == 0x001f */ |
||
5579 | |||
5580 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5581 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5582 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5583 | |||
5584 | /* due to limited precision, need to round before shoving */ |
||
5585 | ((GLushort *)packedPixel)[index] = |
||
5586 | ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; |
||
5587 | ((GLushort *)packedPixel)[index]|= |
||
5588 | ((GLushort)((shoveComponents[1] * 63)+0.5) << 5) & 0x07e0; |
||
5589 | ((GLushort *)packedPixel)[index]|= |
||
5590 | ((GLushort)((shoveComponents[2] * 31)+0.5) ) & 0x001f; |
||
5591 | } /* shove565() */ |
||
5592 | |||
5593 | static void extract565rev(int isSwap, |
||
5594 | const void *packedPixel, GLfloat extractComponents[]) |
||
5595 | { |
||
5596 | GLushort ushort; |
||
5597 | |||
5598 | if (isSwap) { |
||
5599 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5600 | } |
||
5601 | else { |
||
5602 | ushort= *(const GLushort *)packedPixel; |
||
5603 | } |
||
5604 | |||
5605 | /* 00000000,00011111 == 0x001f */ |
||
5606 | /* 00000111,11100000 == 0x07e0 */ |
||
5607 | /* 11111000,00000000 == 0xf800 */ |
||
5608 | |||
5609 | extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; |
||
5610 | extractComponents[1]= (float)((ushort & 0x07E0) >> 5) / 63.0; |
||
5611 | extractComponents[2]= (float)((ushort & 0xF800) >> 11) / 31.0; |
||
5612 | } /* extract565rev() */ |
||
5613 | |||
5614 | static void shove565rev(const GLfloat shoveComponents[], |
||
5615 | int index,void *packedPixel) |
||
5616 | { |
||
5617 | /* 00000000,00011111 == 0x001f */ |
||
5618 | /* 00000111,11100000 == 0x07e0 */ |
||
5619 | /* 11111000,00000000 == 0xf800 */ |
||
5620 | |||
5621 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5622 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5623 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5624 | |||
5625 | /* due to limited precision, need to round before shoving */ |
||
5626 | ((GLushort *)packedPixel)[index] = |
||
5627 | ((GLushort)((shoveComponents[0] * 31.0)+0.5) ) & 0x001F; |
||
5628 | ((GLushort *)packedPixel)[index]|= |
||
5629 | ((GLushort)((shoveComponents[1] * 63.0)+0.5) << 5) & 0x07E0; |
||
5630 | ((GLushort *)packedPixel)[index]|= |
||
5631 | ((GLushort)((shoveComponents[2] * 31.0)+0.5) << 11) & 0xF800; |
||
5632 | } /* shove565rev() */ |
||
5633 | |||
5634 | static void extract4444(int isSwap,const void *packedPixel, |
||
5635 | GLfloat extractComponents[]) |
||
5636 | { |
||
5637 | GLushort ushort; |
||
5638 | |||
5639 | if (isSwap) { |
||
5640 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5641 | } |
||
5642 | else { |
||
5643 | ushort= *(const GLushort *)packedPixel; |
||
5644 | } |
||
5645 | |||
5646 | /* 11110000,00000000 == 0xf000 */ |
||
5647 | /* 00001111,00000000 == 0x0f00 */ |
||
5648 | /* 00000000,11110000 == 0x00f0 */ |
||
5649 | /* 00000000,00001111 == 0x000f */ |
||
5650 | |||
5651 | extractComponents[0]= (float)((ushort & 0xf000) >> 12) / 15.0;/* 15=2^4-1 */ |
||
5652 | extractComponents[1]= (float)((ushort & 0x0f00) >> 8) / 15.0; |
||
5653 | extractComponents[2]= (float)((ushort & 0x00f0) >> 4) / 15.0; |
||
5654 | extractComponents[3]= (float)((ushort & 0x000f) ) / 15.0; |
||
5655 | } /* extract4444() */ |
||
5656 | |||
5657 | static void shove4444(const GLfloat shoveComponents[], |
||
5658 | int index,void *packedPixel) |
||
5659 | { |
||
5660 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5661 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5662 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5663 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5664 | |||
5665 | /* due to limited precision, need to round before shoving */ |
||
5666 | ((GLushort *)packedPixel)[index] = |
||
5667 | ((GLushort)((shoveComponents[0] * 15)+0.5) << 12) & 0xf000; |
||
5668 | ((GLushort *)packedPixel)[index]|= |
||
5669 | ((GLushort)((shoveComponents[1] * 15)+0.5) << 8) & 0x0f00; |
||
5670 | ((GLushort *)packedPixel)[index]|= |
||
5671 | ((GLushort)((shoveComponents[2] * 15)+0.5) << 4) & 0x00f0; |
||
5672 | ((GLushort *)packedPixel)[index]|= |
||
5673 | ((GLushort)((shoveComponents[3] * 15)+0.5) ) & 0x000f; |
||
5674 | } /* shove4444() */ |
||
5675 | |||
5676 | static void extract4444rev(int isSwap,const void *packedPixel, |
||
5677 | GLfloat extractComponents[]) |
||
5678 | { |
||
5679 | GLushort ushort; |
||
5680 | |||
5681 | if (isSwap) { |
||
5682 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5683 | } |
||
5684 | else { |
||
5685 | ushort= *(const GLushort *)packedPixel; |
||
5686 | } |
||
5687 | |||
5688 | /* 00000000,00001111 == 0x000f */ |
||
5689 | /* 00000000,11110000 == 0x00f0 */ |
||
5690 | /* 00001111,00000000 == 0x0f00 */ |
||
5691 | /* 11110000,00000000 == 0xf000 */ |
||
5692 | |||
5693 | /* 15 = 2^4-1 */ |
||
5694 | extractComponents[0]= (float)((ushort & 0x000F) ) / 15.0; |
||
5695 | extractComponents[1]= (float)((ushort & 0x00F0) >> 4) / 15.0; |
||
5696 | extractComponents[2]= (float)((ushort & 0x0F00) >> 8) / 15.0; |
||
5697 | extractComponents[3]= (float)((ushort & 0xF000) >> 12) / 15.0; |
||
5698 | } /* extract4444rev() */ |
||
5699 | |||
5700 | static void shove4444rev(const GLfloat shoveComponents[], |
||
5701 | int index,void *packedPixel) |
||
5702 | { |
||
5703 | /* 00000000,00001111 == 0x000f */ |
||
5704 | /* 00000000,11110000 == 0x00f0 */ |
||
5705 | /* 00001111,00000000 == 0x0f00 */ |
||
5706 | /* 11110000,00000000 == 0xf000 */ |
||
5707 | |||
5708 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5709 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5710 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5711 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5712 | |||
5713 | /* due to limited precision, need to round before shoving */ |
||
5714 | ((GLushort *)packedPixel)[index] = |
||
5715 | ((GLushort)((shoveComponents[0] * 15)+0.5) ) & 0x000F; |
||
5716 | ((GLushort *)packedPixel)[index]|= |
||
5717 | ((GLushort)((shoveComponents[1] * 15)+0.5) << 4) & 0x00F0; |
||
5718 | ((GLushort *)packedPixel)[index]|= |
||
5719 | ((GLushort)((shoveComponents[2] * 15)+0.5) << 8) & 0x0F00; |
||
5720 | ((GLushort *)packedPixel)[index]|= |
||
5721 | ((GLushort)((shoveComponents[3] * 15)+0.5) << 12) & 0xF000; |
||
5722 | } /* shove4444rev() */ |
||
5723 | |||
5724 | static void extract5551(int isSwap,const void *packedPixel, |
||
5725 | GLfloat extractComponents[]) |
||
5726 | { |
||
5727 | GLushort ushort; |
||
5728 | |||
5729 | if (isSwap) { |
||
5730 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5731 | } |
||
5732 | else { |
||
5733 | ushort= *(const GLushort *)packedPixel; |
||
5734 | } |
||
5735 | |||
5736 | /* 11111000,00000000 == 0xf800 */ |
||
5737 | /* 00000111,11000000 == 0x07c0 */ |
||
5738 | /* 00000000,00111110 == 0x003e */ |
||
5739 | /* 00000000,00000001 == 0x0001 */ |
||
5740 | |||
5741 | extractComponents[0]=(float)((ushort & 0xf800) >> 11) / 31.0;/* 31 = 2^5-1*/ |
||
5742 | extractComponents[1]=(float)((ushort & 0x07c0) >> 6) / 31.0; |
||
5743 | extractComponents[2]=(float)((ushort & 0x003e) >> 1) / 31.0; |
||
5744 | extractComponents[3]=(float)((ushort & 0x0001) ); |
||
5745 | } /* extract5551() */ |
||
5746 | |||
5747 | static void shove5551(const GLfloat shoveComponents[], |
||
5748 | int index,void *packedPixel) |
||
5749 | { |
||
5750 | /* 11111000,00000000 == 0xf800 */ |
||
5751 | /* 00000111,11000000 == 0x07c0 */ |
||
5752 | /* 00000000,00111110 == 0x003e */ |
||
5753 | /* 00000000,00000001 == 0x0001 */ |
||
5754 | |||
5755 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5756 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5757 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5758 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5759 | |||
5760 | /* due to limited precision, need to round before shoving */ |
||
5761 | ((GLushort *)packedPixel)[index] = |
||
5762 | ((GLushort)((shoveComponents[0] * 31)+0.5) << 11) & 0xf800; |
||
5763 | ((GLushort *)packedPixel)[index]|= |
||
5764 | ((GLushort)((shoveComponents[1] * 31)+0.5) << 6) & 0x07c0; |
||
5765 | ((GLushort *)packedPixel)[index]|= |
||
5766 | ((GLushort)((shoveComponents[2] * 31)+0.5) << 1) & 0x003e; |
||
5767 | ((GLushort *)packedPixel)[index]|= |
||
5768 | ((GLushort)((shoveComponents[3])+0.5) ) & 0x0001; |
||
5769 | } /* shove5551() */ |
||
5770 | |||
5771 | static void extract1555rev(int isSwap,const void *packedPixel, |
||
5772 | GLfloat extractComponents[]) |
||
5773 | { |
||
5774 | GLushort ushort; |
||
5775 | |||
5776 | if (isSwap) { |
||
5777 | ushort= __GLU_SWAP_2_BYTES(packedPixel); |
||
5778 | } |
||
5779 | else { |
||
5780 | ushort= *(const GLushort *)packedPixel; |
||
5781 | } |
||
5782 | |||
5783 | /* 00000000,00011111 == 0x001F */ |
||
5784 | /* 00000011,11100000 == 0x03E0 */ |
||
5785 | /* 01111100,00000000 == 0x7C00 */ |
||
5786 | /* 10000000,00000000 == 0x8000 */ |
||
5787 | |||
5788 | /* 31 = 2^5-1 */ |
||
5789 | extractComponents[0]= (float)((ushort & 0x001F) ) / 31.0; |
||
5790 | extractComponents[1]= (float)((ushort & 0x03E0) >> 5) / 31.0; |
||
5791 | extractComponents[2]= (float)((ushort & 0x7C00) >> 10) / 31.0; |
||
5792 | extractComponents[3]= (float)((ushort & 0x8000) >> 15); |
||
5793 | } /* extract1555rev() */ |
||
5794 | |||
5795 | static void shove1555rev(const GLfloat shoveComponents[], |
||
5796 | int index,void *packedPixel) |
||
5797 | { |
||
5798 | /* 00000000,00011111 == 0x001F */ |
||
5799 | /* 00000011,11100000 == 0x03E0 */ |
||
5800 | /* 01111100,00000000 == 0x7C00 */ |
||
5801 | /* 10000000,00000000 == 0x8000 */ |
||
5802 | |||
5803 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5804 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5805 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5806 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5807 | |||
5808 | /* due to limited precision, need to round before shoving */ |
||
5809 | ((GLushort *)packedPixel)[index] = |
||
5810 | ((GLushort)((shoveComponents[0] * 31)+0.5) ) & 0x001F; |
||
5811 | ((GLushort *)packedPixel)[index]|= |
||
5812 | ((GLushort)((shoveComponents[1] * 31)+0.5) << 5) & 0x03E0; |
||
5813 | ((GLushort *)packedPixel)[index]|= |
||
5814 | ((GLushort)((shoveComponents[2] * 31)+0.5) << 10) & 0x7C00; |
||
5815 | ((GLushort *)packedPixel)[index]|= |
||
5816 | ((GLushort)((shoveComponents[3])+0.5) << 15) & 0x8000; |
||
5817 | } /* shove1555rev() */ |
||
5818 | |||
5819 | static void extract8888(int isSwap, |
||
5820 | const void *packedPixel, GLfloat extractComponents[]) |
||
5821 | { |
||
5822 | GLuint uint; |
||
5823 | |||
5824 | if (isSwap) { |
||
5825 | uint= __GLU_SWAP_4_BYTES(packedPixel); |
||
5826 | } |
||
5827 | else { |
||
5828 | uint= *(const GLuint *)packedPixel; |
||
5829 | } |
||
5830 | |||
5831 | /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
||
5832 | /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
||
5833 | /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
||
5834 | /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
||
5835 | |||
5836 | /* 255 = 2^8-1 */ |
||
5837 | extractComponents[0]= (float)((uint & 0xff000000) >> 24) / 255.0; |
||
5838 | extractComponents[1]= (float)((uint & 0x00ff0000) >> 16) / 255.0; |
||
5839 | extractComponents[2]= (float)((uint & 0x0000ff00) >> 8) / 255.0; |
||
5840 | extractComponents[3]= (float)((uint & 0x000000ff) ) / 255.0; |
||
5841 | } /* extract8888() */ |
||
5842 | |||
5843 | static void shove8888(const GLfloat shoveComponents[], |
||
5844 | int index,void *packedPixel) |
||
5845 | { |
||
5846 | /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
||
5847 | /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
||
5848 | /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
||
5849 | /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
||
5850 | |||
5851 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5852 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5853 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5854 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5855 | |||
5856 | /* due to limited precision, need to round before shoving */ |
||
5857 | ((GLuint *)packedPixel)[index] = |
||
5858 | ((GLuint)((shoveComponents[0] * 255)+0.5) << 24) & 0xff000000; |
||
5859 | ((GLuint *)packedPixel)[index]|= |
||
5860 | ((GLuint)((shoveComponents[1] * 255)+0.5) << 16) & 0x00ff0000; |
||
5861 | ((GLuint *)packedPixel)[index]|= |
||
5862 | ((GLuint)((shoveComponents[2] * 255)+0.5) << 8) & 0x0000ff00; |
||
5863 | ((GLuint *)packedPixel)[index]|= |
||
5864 | ((GLuint)((shoveComponents[3] * 255)+0.5) ) & 0x000000ff; |
||
5865 | } /* shove8888() */ |
||
5866 | |||
5867 | static void extract8888rev(int isSwap, |
||
5868 | const void *packedPixel,GLfloat extractComponents[]) |
||
5869 | { |
||
5870 | GLuint uint; |
||
5871 | |||
5872 | if (isSwap) { |
||
5873 | uint= __GLU_SWAP_4_BYTES(packedPixel); |
||
5874 | } |
||
5875 | else { |
||
5876 | uint= *(const GLuint *)packedPixel; |
||
5877 | } |
||
5878 | |||
5879 | /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
||
5880 | /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
||
5881 | /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
||
5882 | /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
||
5883 | |||
5884 | /* 255 = 2^8-1 */ |
||
5885 | extractComponents[0]= (float)((uint & 0x000000FF) ) / 255.0; |
||
5886 | extractComponents[1]= (float)((uint & 0x0000FF00) >> 8) / 255.0; |
||
5887 | extractComponents[2]= (float)((uint & 0x00FF0000) >> 16) / 255.0; |
||
5888 | extractComponents[3]= (float)((uint & 0xFF000000) >> 24) / 255.0; |
||
5889 | } /* extract8888rev() */ |
||
5890 | |||
5891 | static void shove8888rev(const GLfloat shoveComponents[], |
||
5892 | int index,void *packedPixel) |
||
5893 | { |
||
5894 | /* 00000000,00000000,00000000,11111111 == 0x000000ff */ |
||
5895 | /* 00000000,00000000,11111111,00000000 == 0x0000ff00 */ |
||
5896 | /* 00000000,11111111,00000000,00000000 == 0x00ff0000 */ |
||
5897 | /* 11111111,00000000,00000000,00000000 == 0xff000000 */ |
||
5898 | |||
5899 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5900 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5901 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5902 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5903 | |||
5904 | /* due to limited precision, need to round before shoving */ |
||
5905 | ((GLuint *)packedPixel)[index] = |
||
5906 | ((GLuint)((shoveComponents[0] * 255)+0.5) ) & 0x000000FF; |
||
5907 | ((GLuint *)packedPixel)[index]|= |
||
5908 | ((GLuint)((shoveComponents[1] * 255)+0.5) << 8) & 0x0000FF00; |
||
5909 | ((GLuint *)packedPixel)[index]|= |
||
5910 | ((GLuint)((shoveComponents[2] * 255)+0.5) << 16) & 0x00FF0000; |
||
5911 | ((GLuint *)packedPixel)[index]|= |
||
5912 | ((GLuint)((shoveComponents[3] * 255)+0.5) << 24) & 0xFF000000; |
||
5913 | } /* shove8888rev() */ |
||
5914 | |||
5915 | static void extract1010102(int isSwap, |
||
5916 | const void *packedPixel,GLfloat extractComponents[]) |
||
5917 | { |
||
5918 | GLuint uint; |
||
5919 | |||
5920 | if (isSwap) { |
||
5921 | uint= __GLU_SWAP_4_BYTES(packedPixel); |
||
5922 | } |
||
5923 | else { |
||
5924 | uint= *(const GLuint *)packedPixel; |
||
5925 | } |
||
5926 | |||
5927 | /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ |
||
5928 | /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ |
||
5929 | /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ |
||
5930 | /* 00000000,00000000,00000000,00000011 == 0x00000003 */ |
||
5931 | |||
5932 | /* 1023 = 2^10-1 */ |
||
5933 | extractComponents[0]= (float)((uint & 0xffc00000) >> 22) / 1023.0; |
||
5934 | extractComponents[1]= (float)((uint & 0x003ff000) >> 12) / 1023.0; |
||
5935 | extractComponents[2]= (float)((uint & 0x00000ffc) >> 2) / 1023.0; |
||
5936 | extractComponents[3]= (float)((uint & 0x00000003) ) / 3.0; |
||
5937 | } /* extract1010102() */ |
||
5938 | |||
5939 | static void shove1010102(const GLfloat shoveComponents[], |
||
5940 | int index,void *packedPixel) |
||
5941 | { |
||
5942 | /* 11111111,11000000,00000000,00000000 == 0xffc00000 */ |
||
5943 | /* 00000000,00111111,11110000,00000000 == 0x003ff000 */ |
||
5944 | /* 00000000,00000000,00001111,11111100 == 0x00000ffc */ |
||
5945 | /* 00000000,00000000,00000000,00000011 == 0x00000003 */ |
||
5946 | |||
5947 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5948 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5949 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
5950 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
5951 | |||
5952 | /* due to limited precision, need to round before shoving */ |
||
5953 | ((GLuint *)packedPixel)[index] = |
||
5954 | ((GLuint)((shoveComponents[0] * 1023)+0.5) << 22) & 0xffc00000; |
||
5955 | ((GLuint *)packedPixel)[index]|= |
||
5956 | ((GLuint)((shoveComponents[1] * 1023)+0.5) << 12) & 0x003ff000; |
||
5957 | ((GLuint *)packedPixel)[index]|= |
||
5958 | ((GLuint)((shoveComponents[2] * 1023)+0.5) << 2) & 0x00000ffc; |
||
5959 | ((GLuint *)packedPixel)[index]|= |
||
5960 | ((GLuint)((shoveComponents[3] * 3)+0.5) ) & 0x00000003; |
||
5961 | } /* shove1010102() */ |
||
5962 | |||
5963 | static void extract2101010rev(int isSwap, |
||
5964 | const void *packedPixel, |
||
5965 | GLfloat extractComponents[]) |
||
5966 | { |
||
5967 | GLuint uint; |
||
5968 | |||
5969 | if (isSwap) { |
||
5970 | uint= __GLU_SWAP_4_BYTES(packedPixel); |
||
5971 | } |
||
5972 | else { |
||
5973 | uint= *(const GLuint *)packedPixel; |
||
5974 | } |
||
5975 | |||
5976 | /* 00000000,00000000,00000011,11111111 == 0x000003FF */ |
||
5977 | /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ |
||
5978 | /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ |
||
5979 | /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ |
||
5980 | |||
5981 | /* 1023 = 2^10-1 */ |
||
5982 | extractComponents[0]= (float)((uint & 0x000003FF) ) / 1023.0; |
||
5983 | extractComponents[1]= (float)((uint & 0x000FFC00) >> 10) / 1023.0; |
||
5984 | extractComponents[2]= (float)((uint & 0x3FF00000) >> 20) / 1023.0; |
||
5985 | extractComponents[3]= (float)((uint & 0xC0000000) >> 30) / 3.0; |
||
5986 | /* 3 = 2^2-1 */ |
||
5987 | } /* extract2101010rev() */ |
||
5988 | |||
5989 | static void shove2101010rev(const GLfloat shoveComponents[], |
||
5990 | int index,void *packedPixel) |
||
5991 | { |
||
5992 | /* 00000000,00000000,00000011,11111111 == 0x000003FF */ |
||
5993 | /* 00000000,00001111,11111100,00000000 == 0x000FFC00 */ |
||
5994 | /* 00111111,11110000,00000000,00000000 == 0x3FF00000 */ |
||
5995 | /* 11000000,00000000,00000000,00000000 == 0xC0000000 */ |
||
5996 | |||
5997 | assert(0.0 <= shoveComponents[0] && shoveComponents[0] <= 1.0); |
||
5998 | assert(0.0 <= shoveComponents[1] && shoveComponents[1] <= 1.0); |
||
5999 | assert(0.0 <= shoveComponents[2] && shoveComponents[2] <= 1.0); |
||
6000 | assert(0.0 <= shoveComponents[3] && shoveComponents[3] <= 1.0); |
||
6001 | |||
6002 | /* due to limited precision, need to round before shoving */ |
||
6003 | ((GLuint *)packedPixel)[index] = |
||
6004 | ((GLuint)((shoveComponents[0] * 1023)+0.5) ) & 0x000003FF; |
||
6005 | ((GLuint *)packedPixel)[index]|= |
||
6006 | ((GLuint)((shoveComponents[1] * 1023)+0.5) << 10) & 0x000FFC00; |
||
6007 | ((GLuint *)packedPixel)[index]|= |
||
6008 | ((GLuint)((shoveComponents[2] * 1023)+0.5) << 20) & 0x3FF00000; |
||
6009 | ((GLuint *)packedPixel)[index]|= |
||
6010 | ((GLuint)((shoveComponents[3] * 3)+0.5) << 30) & 0xC0000000; |
||
6011 | } /* shove2101010rev() */ |
||
6012 | |||
6013 | static void scaleInternalPackedPixel(int components, |
||
6014 | void (*extractPackedPixel) |
||
6015 | (int, const void *,GLfloat []), |
||
6016 | void (*shovePackedPixel) |
||
6017 | (const GLfloat [], int, void *), |
||
6018 | GLint widthIn,GLint heightIn, |
||
6019 | const void *dataIn, |
||
6020 | GLint widthOut,GLint heightOut, |
||
6021 | void *dataOut, |
||
6022 | GLint pixelSizeInBytes, |
||
6023 | GLint rowSizeInBytes,GLint isSwap) |
||
6024 | { |
||
6025 | float convx; |
||
6026 | float convy; |
||
6027 | float percent; |
||
6028 | |||
6029 | /* Max components in a format is 4, so... */ |
||
6030 | float totals[4]; |
||
6031 | float extractTotals[4], extractMoreTotals[4], shoveTotals[4]; |
||
6032 | |||
6033 | float area; |
||
6034 | int i,j,k,xindex; |
||
6035 | |||
6036 | const char *temp, *temp0; |
||
6037 | int outindex; |
||
6038 | |||
6039 | int lowx_int, highx_int, lowy_int, highy_int; |
||
6040 | float x_percent, y_percent; |
||
6041 | float lowx_float, highx_float, lowy_float, highy_float; |
||
6042 | float convy_float, convx_float; |
||
6043 | int convy_int, convx_int; |
||
6044 | int l, m; |
||
6045 | const char *left, *right; |
||
6046 | |||
6047 | if (widthIn == widthOut*2 && heightIn == heightOut*2) { |
||
6048 | halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
||
6049 | widthIn, heightIn, dataIn, dataOut, |
||
6050 | pixelSizeInBytes,rowSizeInBytes,isSwap); |
||
6051 | return; |
||
6052 | } |
||
6053 | convy = (float) heightIn/heightOut; |
||
6054 | convx = (float) widthIn/widthOut; |
||
6055 | convy_int = floor(convy); |
||
6056 | convy_float = convy - convy_int; |
||
6057 | convx_int = floor(convx); |
||
6058 | convx_float = convx - convx_int; |
||
6059 | |||
6060 | area = convx * convy; |
||
6061 | |||
6062 | lowy_int = 0; |
||
6063 | lowy_float = 0; |
||
6064 | highy_int = convy_int; |
||
6065 | highy_float = convy_float; |
||
6066 | |||
6067 | for (i = 0; i < heightOut; i++) { |
||
6068 | lowx_int = 0; |
||
6069 | lowx_float = 0; |
||
6070 | highx_int = convx_int; |
||
6071 | highx_float = convx_float; |
||
6072 | |||
6073 | for (j = 0; j < widthOut; j++) { |
||
6074 | /* |
||
6075 | ** Ok, now apply box filter to box that goes from (lowx, lowy) |
||
6076 | ** to (highx, highy) on input data into this pixel on output |
||
6077 | ** data. |
||
6078 | */ |
||
6079 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
6080 | |||
6081 | /* calculate the value for pixels in the 1st row */ |
||
6082 | xindex = lowx_int*pixelSizeInBytes; |
||
6083 | if((highy_int>lowy_int) && (highx_int>lowx_int)) { |
||
6084 | |||
6085 | y_percent = 1-lowy_float; |
||
6086 | temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; |
||
6087 | percent = y_percent * (1-lowx_float); |
||
6088 | #if 0 |
||
6089 | for (k = 0, temp_index = temp; k < components; |
||
6090 | k++, temp_index += element_size) { |
||
6091 | if (myswap_bytes) { |
||
6092 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6093 | } else { |
||
6094 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6095 | } |
||
6096 | } |
||
6097 | #else |
||
6098 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6099 | for (k = 0; k < components; k++) { |
||
6100 | totals[k]+= extractTotals[k] * percent; |
||
6101 | } |
||
6102 | #endif |
||
6103 | left = temp; |
||
6104 | for(l = lowx_int+1; l < highx_int; l++) { |
||
6105 | temp += pixelSizeInBytes; |
||
6106 | #if 0 |
||
6107 | for (k = 0, temp_index = temp; k < components; |
||
6108 | k++, temp_index += element_size) { |
||
6109 | if (myswap_bytes) { |
||
6110 | totals[k] += |
||
6111 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
6112 | } else { |
||
6113 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
6114 | } |
||
6115 | } |
||
6116 | #else |
||
6117 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6118 | for (k = 0; k < components; k++) { |
||
6119 | totals[k]+= extractTotals[k] * y_percent; |
||
6120 | } |
||
6121 | #endif |
||
6122 | } |
||
6123 | temp += pixelSizeInBytes; |
||
6124 | right = temp; |
||
6125 | percent = y_percent * highx_float; |
||
6126 | #if 0 |
||
6127 | for (k = 0, temp_index = temp; k < components; |
||
6128 | k++, temp_index += element_size) { |
||
6129 | if (myswap_bytes) { |
||
6130 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6131 | } else { |
||
6132 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6133 | } |
||
6134 | } |
||
6135 | #else |
||
6136 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6137 | for (k = 0; k < components; k++) { |
||
6138 | totals[k]+= extractTotals[k] * percent; |
||
6139 | } |
||
6140 | #endif |
||
6141 | |||
6142 | /* calculate the value for pixels in the last row */ |
||
6143 | |||
6144 | y_percent = highy_float; |
||
6145 | percent = y_percent * (1-lowx_float); |
||
6146 | temp = (const char *)dataIn + xindex + highy_int * rowSizeInBytes; |
||
6147 | #if 0 |
||
6148 | for (k = 0, temp_index = temp; k < components; |
||
6149 | k++, temp_index += element_size) { |
||
6150 | if (myswap_bytes) { |
||
6151 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6152 | } else { |
||
6153 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6154 | } |
||
6155 | } |
||
6156 | #else |
||
6157 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6158 | for (k = 0; k < components; k++) { |
||
6159 | totals[k]+= extractTotals[k] * percent; |
||
6160 | } |
||
6161 | #endif |
||
6162 | for(l = lowx_int+1; l < highx_int; l++) { |
||
6163 | temp += pixelSizeInBytes; |
||
6164 | #if 0 |
||
6165 | for (k = 0, temp_index = temp; k < components; |
||
6166 | k++, temp_index += element_size) { |
||
6167 | if (myswap_bytes) { |
||
6168 | totals[k] += |
||
6169 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
6170 | } else { |
||
6171 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
6172 | } |
||
6173 | } |
||
6174 | #else |
||
6175 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6176 | for (k = 0; k < components; k++) { |
||
6177 | totals[k]+= extractTotals[k] * y_percent; |
||
6178 | } |
||
6179 | #endif |
||
6180 | |||
6181 | } |
||
6182 | temp += pixelSizeInBytes; |
||
6183 | percent = y_percent * highx_float; |
||
6184 | #if 0 |
||
6185 | for (k = 0, temp_index = temp; k < components; |
||
6186 | k++, temp_index += element_size) { |
||
6187 | if (myswap_bytes) { |
||
6188 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6189 | } else { |
||
6190 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6191 | } |
||
6192 | } |
||
6193 | #else |
||
6194 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6195 | for (k = 0; k < components; k++) { |
||
6196 | totals[k]+= extractTotals[k] * percent; |
||
6197 | } |
||
6198 | #endif |
||
6199 | |||
6200 | /* calculate the value for pixels in the 1st and last column */ |
||
6201 | for(m = lowy_int+1; m < highy_int; m++) { |
||
6202 | left += rowSizeInBytes; |
||
6203 | right += rowSizeInBytes; |
||
6204 | #if 0 |
||
6205 | for (k = 0; k < components; |
||
6206 | k++, left += element_size, right += element_size) { |
||
6207 | if (myswap_bytes) { |
||
6208 | totals[k] += |
||
6209 | __GLU_SWAP_2_BYTES(left) * (1-lowx_float) + |
||
6210 | __GLU_SWAP_2_BYTES(right) * highx_float; |
||
6211 | } else { |
||
6212 | totals[k] += *(const GLushort*)left * (1-lowx_float) |
||
6213 | + *(const GLushort*)right * highx_float; |
||
6214 | } |
||
6215 | } |
||
6216 | #else |
||
6217 | (*extractPackedPixel)(isSwap,left,extractTotals); |
||
6218 | (*extractPackedPixel)(isSwap,right,extractMoreTotals); |
||
6219 | for (k = 0; k < components; k++) { |
||
6220 | totals[k]+= (extractTotals[k]*(1-lowx_float) + |
||
6221 | extractMoreTotals[k]*highx_float); |
||
6222 | } |
||
6223 | #endif |
||
6224 | } |
||
6225 | } else if (highy_int > lowy_int) { |
||
6226 | x_percent = highx_float - lowx_float; |
||
6227 | percent = (1-lowy_float)*x_percent; |
||
6228 | temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; |
||
6229 | #if 0 |
||
6230 | for (k = 0, temp_index = temp; k < components; |
||
6231 | k++, temp_index += element_size) { |
||
6232 | if (myswap_bytes) { |
||
6233 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6234 | } else { |
||
6235 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6236 | } |
||
6237 | } |
||
6238 | #else |
||
6239 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6240 | for (k = 0; k < components; k++) { |
||
6241 | totals[k]+= extractTotals[k] * percent; |
||
6242 | } |
||
6243 | #endif |
||
6244 | for(m = lowy_int+1; m < highy_int; m++) { |
||
6245 | temp += rowSizeInBytes; |
||
6246 | #if 0 |
||
6247 | for (k = 0, temp_index = temp; k < components; |
||
6248 | k++, temp_index += element_size) { |
||
6249 | if (myswap_bytes) { |
||
6250 | totals[k] += |
||
6251 | __GLU_SWAP_2_BYTES(temp_index) * x_percent; |
||
6252 | } else { |
||
6253 | totals[k] += *(const GLushort*)temp_index * x_percent; |
||
6254 | } |
||
6255 | } |
||
6256 | #else |
||
6257 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6258 | for (k = 0; k < components; k++) { |
||
6259 | totals[k]+= extractTotals[k] * x_percent; |
||
6260 | } |
||
6261 | #endif |
||
6262 | } |
||
6263 | percent = x_percent * highy_float; |
||
6264 | temp += rowSizeInBytes; |
||
6265 | #if 0 |
||
6266 | for (k = 0, temp_index = temp; k < components; |
||
6267 | k++, temp_index += element_size) { |
||
6268 | if (myswap_bytes) { |
||
6269 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6270 | } else { |
||
6271 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6272 | } |
||
6273 | } |
||
6274 | #else |
||
6275 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6276 | for (k = 0; k < components; k++) { |
||
6277 | totals[k]+= extractTotals[k] * percent; |
||
6278 | } |
||
6279 | #endif |
||
6280 | } else if (highx_int > lowx_int) { |
||
6281 | y_percent = highy_float - lowy_float; |
||
6282 | percent = (1-lowx_float)*y_percent; |
||
6283 | temp = (const char *)dataIn + xindex + lowy_int*rowSizeInBytes; |
||
6284 | #if 0 |
||
6285 | for (k = 0, temp_index = temp; k < components; |
||
6286 | k++, temp_index += element_size) { |
||
6287 | if (myswap_bytes) { |
||
6288 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6289 | } else { |
||
6290 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6291 | } |
||
6292 | } |
||
6293 | #else |
||
6294 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6295 | for (k = 0; k < components; k++) { |
||
6296 | totals[k]+= extractTotals[k] * percent; |
||
6297 | } |
||
6298 | #endif |
||
6299 | for (l = lowx_int+1; l < highx_int; l++) { |
||
6300 | temp += pixelSizeInBytes; |
||
6301 | #if 0 |
||
6302 | for (k = 0, temp_index = temp; k < components; |
||
6303 | k++, temp_index += element_size) { |
||
6304 | if (myswap_bytes) { |
||
6305 | totals[k] += |
||
6306 | __GLU_SWAP_2_BYTES(temp_index) * y_percent; |
||
6307 | } else { |
||
6308 | totals[k] += *(const GLushort*)temp_index * y_percent; |
||
6309 | } |
||
6310 | } |
||
6311 | #else |
||
6312 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6313 | for (k = 0; k < components; k++) { |
||
6314 | totals[k]+= extractTotals[k] * y_percent; |
||
6315 | } |
||
6316 | #endif |
||
6317 | } |
||
6318 | temp += pixelSizeInBytes; |
||
6319 | percent = y_percent * highx_float; |
||
6320 | #if 0 |
||
6321 | for (k = 0, temp_index = temp; k < components; |
||
6322 | k++, temp_index += element_size) { |
||
6323 | if (myswap_bytes) { |
||
6324 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6325 | } else { |
||
6326 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6327 | } |
||
6328 | } |
||
6329 | #else |
||
6330 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6331 | for (k = 0; k < components; k++) { |
||
6332 | totals[k]+= extractTotals[k] * percent; |
||
6333 | } |
||
6334 | #endif |
||
6335 | } else { |
||
6336 | percent = (highy_float-lowy_float)*(highx_float-lowx_float); |
||
6337 | temp = (const char *)dataIn + xindex + lowy_int * rowSizeInBytes; |
||
6338 | #if 0 |
||
6339 | for (k = 0, temp_index = temp; k < components; |
||
6340 | k++, temp_index += element_size) { |
||
6341 | if (myswap_bytes) { |
||
6342 | totals[k] += __GLU_SWAP_2_BYTES(temp_index) * percent; |
||
6343 | } else { |
||
6344 | totals[k] += *(const GLushort*)temp_index * percent; |
||
6345 | } |
||
6346 | } |
||
6347 | #else |
||
6348 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6349 | for (k = 0; k < components; k++) { |
||
6350 | totals[k]+= extractTotals[k] * percent; |
||
6351 | } |
||
6352 | #endif |
||
6353 | } |
||
6354 | |||
6355 | /* this is for the pixels in the body */ |
||
6356 | temp0 = (const char *)dataIn + xindex + pixelSizeInBytes + (lowy_int+1)*rowSizeInBytes; |
||
6357 | for (m = lowy_int+1; m < highy_int; m++) { |
||
6358 | temp = temp0; |
||
6359 | for(l = lowx_int+1; l < highx_int; l++) { |
||
6360 | #if 0 |
||
6361 | for (k = 0, temp_index = temp; k < components; |
||
6362 | k++, temp_index += element_size) { |
||
6363 | if (myswap_bytes) { |
||
6364 | totals[k] += __GLU_SWAP_2_BYTES(temp_index); |
||
6365 | } else { |
||
6366 | totals[k] += *(const GLushort*)temp_index; |
||
6367 | } |
||
6368 | } |
||
6369 | #else |
||
6370 | (*extractPackedPixel)(isSwap,temp,extractTotals); |
||
6371 | for (k = 0; k < components; k++) { |
||
6372 | totals[k]+= extractTotals[k]; |
||
6373 | } |
||
6374 | #endif |
||
6375 | temp += pixelSizeInBytes; |
||
6376 | } |
||
6377 | temp0 += rowSizeInBytes; |
||
6378 | } |
||
6379 | |||
6380 | outindex = (j + (i * widthOut)); /* * (components == 1) */ |
||
6381 | #if 0 |
||
6382 | for (k = 0; k < components; k++) { |
||
6383 | dataout[outindex + k] = totals[k]/area; |
||
6384 | /*printf("totals[%d] = %f\n", k, totals[k]);*/ |
||
6385 | } |
||
6386 | #else |
||
6387 | for (k = 0; k < components; k++) { |
||
6388 | shoveTotals[k]= totals[k]/area; |
||
6389 | } |
||
6390 | (*shovePackedPixel)(shoveTotals,outindex,(void *)dataOut); |
||
6391 | #endif |
||
6392 | lowx_int = highx_int; |
||
6393 | lowx_float = highx_float; |
||
6394 | highx_int += convx_int; |
||
6395 | highx_float += convx_float; |
||
6396 | if(highx_float > 1) { |
||
6397 | highx_float -= 1.0; |
||
6398 | highx_int++; |
||
6399 | } |
||
6400 | } |
||
6401 | lowy_int = highy_int; |
||
6402 | lowy_float = highy_float; |
||
6403 | highy_int += convy_int; |
||
6404 | highy_float += convy_float; |
||
6405 | if(highy_float > 1) { |
||
6406 | highy_float -= 1.0; |
||
6407 | highy_int++; |
||
6408 | } |
||
6409 | } |
||
6410 | |||
6411 | assert(outindex == (widthOut*heightOut - 1)); |
||
6412 | } /* scaleInternalPackedPixel() */ |
||
6413 | |||
6414 | /* rowSizeInBytes is at least the width (in bytes) due to padding on |
||
6415 | * inputs; not always equal. Output NEVER has row padding. |
||
6416 | */ |
||
6417 | static void halveImagePackedPixel(int components, |
||
6418 | void (*extractPackedPixel) |
||
6419 | (int, const void *,GLfloat []), |
||
6420 | void (*shovePackedPixel) |
||
6421 | (const GLfloat [],int, void *), |
||
6422 | GLint width, GLint height, |
||
6423 | const void *dataIn, void *dataOut, |
||
6424 | GLint pixelSizeInBytes, |
||
6425 | GLint rowSizeInBytes, GLint isSwap) |
||
6426 | { |
||
6427 | /* handle case where there is only 1 column/row */ |
||
6428 | if (width == 1 || height == 1) { |
||
6429 | assert(!(width == 1 && height == 1)); /* can't be 1x1 */ |
||
6430 | halve1DimagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
||
6431 | width,height,dataIn,dataOut,pixelSizeInBytes, |
||
6432 | rowSizeInBytes,isSwap); |
||
6433 | return; |
||
6434 | } |
||
6435 | |||
6436 | { |
||
6437 | int ii, jj; |
||
6438 | |||
6439 | int halfWidth= width / 2; |
||
6440 | int halfHeight= height / 2; |
||
6441 | const char *src= (const char *) dataIn; |
||
6442 | int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
||
6443 | int outIndex= 0; |
||
6444 | |||
6445 | for (ii= 0; ii< halfHeight; ii++) { |
||
6446 | for (jj= 0; jj< halfWidth; jj++) { |
||
6447 | #define BOX4 4 |
||
6448 | float totals[4]; /* 4 is maximum components */ |
||
6449 | float extractTotals[BOX4][4]; /* 4 is maximum components */ |
||
6450 | int cc; |
||
6451 | |||
6452 | (*extractPackedPixel)(isSwap,src, |
||
6453 | &extractTotals[0][0]); |
||
6454 | (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
||
6455 | &extractTotals[1][0]); |
||
6456 | (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
||
6457 | &extractTotals[2][0]); |
||
6458 | (*extractPackedPixel)(isSwap, |
||
6459 | (src+rowSizeInBytes+pixelSizeInBytes), |
||
6460 | &extractTotals[3][0]); |
||
6461 | for (cc = 0; cc < components; cc++) { |
||
6462 | int kk; |
||
6463 | |||
6464 | /* grab 4 pixels to average */ |
||
6465 | totals[cc]= 0.0; |
||
6466 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
6467 | * extractTotals[2][RED]+extractTotals[3][RED]; |
||
6468 | * totals[RED]/= 4.0; |
||
6469 | */ |
||
6470 | for (kk = 0; kk < BOX4; kk++) { |
||
6471 | totals[cc]+= extractTotals[kk][cc]; |
||
6472 | } |
||
6473 | totals[cc]/= (float)BOX4; |
||
6474 | } |
||
6475 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
6476 | |||
6477 | outIndex++; |
||
6478 | /* skip over to next square of 4 */ |
||
6479 | src+= pixelSizeInBytes + pixelSizeInBytes; |
||
6480 | } |
||
6481 | /* skip past pad bytes, if any, to get to next row */ |
||
6482 | src+= padBytes; |
||
6483 | |||
6484 | /* src is at beginning of a row here, but it's the second row of |
||
6485 | * the square block of 4 pixels that we just worked on so we |
||
6486 | * need to go one more row. |
||
6487 | * i.e., |
||
6488 | * OO... |
||
6489 | * here -->OO... |
||
6490 | * but want -->OO... |
||
6491 | * OO... |
||
6492 | * ... |
||
6493 | */ |
||
6494 | src+= rowSizeInBytes; |
||
6495 | } |
||
6496 | |||
6497 | /* both pointers must reach one byte after the end */ |
||
6498 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); |
||
6499 | assert(outIndex == halfWidth * halfHeight); |
||
6500 | } |
||
6501 | } /* halveImagePackedPixel() */ |
||
6502 | |||
6503 | static void halve1DimagePackedPixel(int components, |
||
6504 | void (*extractPackedPixel) |
||
6505 | (int, const void *,GLfloat []), |
||
6506 | void (*shovePackedPixel) |
||
6507 | (const GLfloat [],int, void *), |
||
6508 | GLint width, GLint height, |
||
6509 | const void *dataIn, void *dataOut, |
||
6510 | GLint pixelSizeInBytes, |
||
6511 | GLint rowSizeInBytes, GLint isSwap) |
||
6512 | { |
||
6513 | int halfWidth= width / 2; |
||
6514 | int halfHeight= height / 2; |
||
6515 | const char *src= (const char *) dataIn; |
||
6516 | int jj; |
||
6517 | |||
6518 | assert(width == 1 || height == 1); /* must be 1D */ |
||
6519 | assert(width != height); /* can't be square */ |
||
6520 | |||
6521 | if (height == 1) { /* 1 row */ |
||
6522 | int outIndex= 0; |
||
6523 | |||
6524 | assert(width != 1); /* widthxheight can't be 1x1 */ |
||
6525 | halfHeight= 1; |
||
6526 | |||
6527 | /* one horizontal row with possible pad bytes */ |
||
6528 | |||
6529 | for (jj= 0; jj< halfWidth; jj++) { |
||
6530 | #define BOX2 2 |
||
6531 | float totals[4]; /* 4 is maximum components */ |
||
6532 | float extractTotals[BOX2][4]; /* 4 is maximum components */ |
||
6533 | int cc; |
||
6534 | |||
6535 | /* average two at a time, instead of four */ |
||
6536 | (*extractPackedPixel)(isSwap,src, |
||
6537 | &extractTotals[0][0]); |
||
6538 | (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
||
6539 | &extractTotals[1][0]); |
||
6540 | for (cc = 0; cc < components; cc++) { |
||
6541 | int kk; |
||
6542 | |||
6543 | /* grab 2 pixels to average */ |
||
6544 | totals[cc]= 0.0; |
||
6545 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
||
6546 | * totals[RED]/= 2.0; |
||
6547 | */ |
||
6548 | for (kk = 0; kk < BOX2; kk++) { |
||
6549 | totals[cc]+= extractTotals[kk][cc]; |
||
6550 | } |
||
6551 | totals[cc]/= (float)BOX2; |
||
6552 | } |
||
6553 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
6554 | |||
6555 | outIndex++; |
||
6556 | /* skip over to next group of 2 */ |
||
6557 | src+= pixelSizeInBytes + pixelSizeInBytes; |
||
6558 | } |
||
6559 | |||
6560 | { |
||
6561 | int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
||
6562 | src+= padBytes; /* for assertion only */ |
||
6563 | } |
||
6564 | assert(src == &((const char *)dataIn)[rowSizeInBytes]); |
||
6565 | assert(outIndex == halfWidth * halfHeight); |
||
6566 | } |
||
6567 | else if (width == 1) { /* 1 column */ |
||
6568 | int outIndex= 0; |
||
6569 | |||
6570 | assert(height != 1); /* widthxheight can't be 1x1 */ |
||
6571 | halfWidth= 1; |
||
6572 | /* one vertical column with possible pad bytes per row */ |
||
6573 | /* average two at a time */ |
||
6574 | |||
6575 | for (jj= 0; jj< halfHeight; jj++) { |
||
6576 | #define BOX2 2 |
||
6577 | float totals[4]; /* 4 is maximum components */ |
||
6578 | float extractTotals[BOX2][4]; /* 4 is maximum components */ |
||
6579 | int cc; |
||
6580 | |||
6581 | /* average two at a time, instead of four */ |
||
6582 | (*extractPackedPixel)(isSwap,src, |
||
6583 | &extractTotals[0][0]); |
||
6584 | (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
||
6585 | &extractTotals[1][0]); |
||
6586 | for (cc = 0; cc < components; cc++) { |
||
6587 | int kk; |
||
6588 | |||
6589 | /* grab 2 pixels to average */ |
||
6590 | totals[cc]= 0.0; |
||
6591 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
||
6592 | * totals[RED]/= 2.0; |
||
6593 | */ |
||
6594 | for (kk = 0; kk < BOX2; kk++) { |
||
6595 | totals[cc]+= extractTotals[kk][cc]; |
||
6596 | } |
||
6597 | totals[cc]/= (float)BOX2; |
||
6598 | } |
||
6599 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
6600 | |||
6601 | outIndex++; |
||
6602 | src+= rowSizeInBytes + rowSizeInBytes; /* go to row after next */ |
||
6603 | } |
||
6604 | |||
6605 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height]); |
||
6606 | assert(outIndex == halfWidth * halfHeight); |
||
6607 | } |
||
6608 | } /* halve1DimagePackedPixel() */ |
||
6609 | |||
6610 | /*===========================================================================*/ |
||
6611 | |||
6612 | #ifdef RESOLVE_3D_TEXTURE_SUPPORT |
||
6613 | /* |
||
6614 | * This section ensures that GLU 1.3 will load and run on |
||
6615 | * a GL 1.1 implementation. It dynamically resolves the |
||
6616 | * call to glTexImage3D() which might not be available. |
||
6617 | * Or is it might be supported as an extension. |
||
6618 | * Contributed by Gerk Huisma |
||
6619 | */ |
||
6620 | |||
6621 | typedef void (GLAPIENTRY *TexImage3Dproc)( GLenum target, GLint level, |
||
6622 | GLenum internalFormat, |
||
6623 | GLsizei width, GLsizei height, |
||
6624 | GLsizei depth, GLint border, |
||
6625 | GLenum format, GLenum type, |
||
6626 | const GLvoid *pixels ); |
||
6627 | |||
6628 | static TexImage3Dproc pTexImage3D = 0; |
||
6629 | |||
6630 | #if !defined(_WIN32) && !defined(__WIN32__) |
||
6631 | # include |
||
6632 | # include |
||
6633 | #else |
||
6634 | WINGDIAPI PROC WINAPI wglGetProcAddress(LPCSTR); |
||
6635 | #endif |
||
6636 | |||
6637 | static void gluTexImage3D( GLenum target, GLint level, |
||
6638 | GLenum internalFormat, |
||
6639 | GLsizei width, GLsizei height, |
||
6640 | GLsizei depth, GLint border, |
||
6641 | GLenum format, GLenum type, |
||
6642 | const GLvoid *pixels ) |
||
6643 | { |
||
6644 | if (!pTexImage3D) { |
||
6645 | #if defined(_WIN32) || defined(__WIN32__) |
||
6646 | pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3D"); |
||
6647 | if (!pTexImage3D) |
||
6648 | pTexImage3D = (TexImage3Dproc) wglGetProcAddress("glTexImage3DEXT"); |
||
6649 | #else |
||
6650 | void *libHandle = dlopen("libgl.so", RTLD_LAZY); |
||
6651 | pTexImage3D = TexImage3Dproc) dlsym(libHandle, "glTexImage3D" ); |
||
6652 | if (!pTexImage3D) |
||
6653 | pTexImage3D = (TexImage3Dproc) dlsym(libHandle,"glTexImage3DEXT"); |
||
6654 | dlclose(libHandle); |
||
6655 | #endif |
||
6656 | } |
||
6657 | |||
6658 | /* Now call glTexImage3D */ |
||
6659 | if (pTexImage3D) |
||
6660 | pTexImage3D(target, level, internalFormat, width, height, |
||
6661 | depth, border, format, type, pixels); |
||
6662 | } |
||
6663 | |||
6664 | #else |
||
6665 | |||
6666 | /* Only bind to a GL 1.2 implementation: */ |
||
6667 | #define gluTexImage3D glTexImage3D |
||
6668 | |||
6669 | #endif |
||
6670 | |||
6671 | static GLint imageSize3D(GLint width, GLint height, GLint depth, |
||
6672 | GLenum format, GLenum type) |
||
6673 | { |
||
6674 | int components= elements_per_group(format,type); |
||
6675 | int bytes_per_row= bytes_per_element(type) * width; |
||
6676 | |||
6677 | assert(width > 0 && height > 0 && depth > 0); |
||
6678 | assert(type != GL_BITMAP); |
||
6679 | |||
6680 | return bytes_per_row * height * depth * components; |
||
6681 | } /* imageSize3D() */ |
||
6682 | |||
6683 | static void fillImage3D(const PixelStorageModes *psm, |
||
6684 | GLint width, GLint height, GLint depth, GLenum format, |
||
6685 | GLenum type, GLboolean indexFormat, |
||
6686 | const void *userImage, GLushort *newImage) |
||
6687 | { |
||
6688 | int myswapBytes; |
||
6689 | int components; |
||
6690 | int groupsPerLine; |
||
6691 | int elementSize; |
||
6692 | int groupSize; |
||
6693 | int rowSize; |
||
6694 | int padding; |
||
6695 | int elementsPerLine; |
||
6696 | int rowsPerImage; |
||
6697 | int imageSize; |
||
6698 | const GLubyte *start, *rowStart, *iter; |
||
6699 | GLushort *iter2; |
||
6700 | int ww, hh, dd, k; |
||
6701 | |||
6702 | myswapBytes= psm->unpack_swap_bytes; |
||
6703 | components= elements_per_group(format,type); |
||
6704 | if (psm->unpack_row_length > 0) { |
||
6705 | groupsPerLine= psm->unpack_row_length; |
||
6706 | } |
||
6707 | else { |
||
6708 | groupsPerLine= width; |
||
6709 | } |
||
6710 | elementSize= bytes_per_element(type); |
||
6711 | groupSize= elementSize * components; |
||
6712 | if (elementSize == 1) myswapBytes= 0; |
||
6713 | |||
6714 | /* 3dstuff begin */ |
||
6715 | if (psm->unpack_image_height > 0) { |
||
6716 | rowsPerImage= psm->unpack_image_height; |
||
6717 | } |
||
6718 | else { |
||
6719 | rowsPerImage= height; |
||
6720 | } |
||
6721 | /* 3dstuff end */ |
||
6722 | |||
6723 | rowSize= groupsPerLine * groupSize; |
||
6724 | padding= rowSize % psm->unpack_alignment; |
||
6725 | if (padding) { |
||
6726 | rowSize+= psm->unpack_alignment - padding; |
||
6727 | } |
||
6728 | |||
6729 | imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
||
6730 | |||
6731 | start= (const GLubyte *)userImage + psm->unpack_skip_rows * rowSize + |
||
6732 | psm->unpack_skip_pixels * groupSize + |
||
6733 | /*3dstuff*/ |
||
6734 | psm->unpack_skip_images * imageSize; |
||
6735 | elementsPerLine = width * components; |
||
6736 | |||
6737 | iter2= newImage; |
||
6738 | for (dd= 0; dd < depth; dd++) { |
||
6739 | rowStart= start; |
||
6740 | |||
6741 | for (hh= 0; hh < height; hh++) { |
||
6742 | iter= rowStart; |
||
6743 | |||
6744 | for (ww= 0; ww < elementsPerLine; ww++) { |
||
6745 | Type_Widget widget; |
||
6746 | float extractComponents[4]; |
||
6747 | |||
6748 | switch(type) { |
||
6749 | case GL_UNSIGNED_BYTE: |
||
6750 | if (indexFormat) { |
||
6751 | *iter2++ = *iter; |
||
6752 | } else { |
||
6753 | *iter2++ = (*iter) * 257; |
||
6754 | } |
||
6755 | break; |
||
6756 | case GL_BYTE: |
||
6757 | if (indexFormat) { |
||
6758 | *iter2++ = *((const GLbyte *) iter); |
||
6759 | } else { |
||
6760 | /* rough approx */ |
||
6761 | *iter2++ = (*((const GLbyte *) iter)) * 516; |
||
6762 | } |
||
6763 | break; |
||
6764 | case GL_UNSIGNED_BYTE_3_3_2: |
||
6765 | extract332(0,iter,extractComponents); |
||
6766 | for (k = 0; k < 3; k++) { |
||
6767 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6768 | } |
||
6769 | break; |
||
6770 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
6771 | extract233rev(0,iter,extractComponents); |
||
6772 | for (k = 0; k < 3; k++) { |
||
6773 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6774 | } |
||
6775 | break; |
||
6776 | case GL_UNSIGNED_SHORT_5_6_5: |
||
6777 | extract565(myswapBytes,iter,extractComponents); |
||
6778 | for (k = 0; k < 3; k++) { |
||
6779 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6780 | } |
||
6781 | break; |
||
6782 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
6783 | extract565rev(myswapBytes,iter,extractComponents); |
||
6784 | for (k = 0; k < 3; k++) { |
||
6785 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6786 | } |
||
6787 | break; |
||
6788 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
6789 | extract4444(myswapBytes,iter,extractComponents); |
||
6790 | for (k = 0; k < 4; k++) { |
||
6791 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6792 | } |
||
6793 | break; |
||
6794 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
6795 | extract4444rev(myswapBytes,iter,extractComponents); |
||
6796 | for (k = 0; k < 4; k++) { |
||
6797 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6798 | } |
||
6799 | break; |
||
6800 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
6801 | extract5551(myswapBytes,iter,extractComponents); |
||
6802 | for (k = 0; k < 4; k++) { |
||
6803 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6804 | } |
||
6805 | break; |
||
6806 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
6807 | extract1555rev(myswapBytes,iter,extractComponents); |
||
6808 | for (k = 0; k < 4; k++) { |
||
6809 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6810 | } |
||
6811 | break; |
||
6812 | case GL_UNSIGNED_SHORT: |
||
6813 | case GL_SHORT: |
||
6814 | if (myswapBytes) { |
||
6815 | widget.ub[0] = iter[1]; |
||
6816 | widget.ub[1] = iter[0]; |
||
6817 | } else { |
||
6818 | widget.ub[0] = iter[0]; |
||
6819 | widget.ub[1] = iter[1]; |
||
6820 | } |
||
6821 | if (type == GL_SHORT) { |
||
6822 | if (indexFormat) { |
||
6823 | *iter2++ = widget.s[0]; |
||
6824 | } else { |
||
6825 | /* rough approx */ |
||
6826 | *iter2++ = widget.s[0]*2; |
||
6827 | } |
||
6828 | } else { |
||
6829 | *iter2++ = widget.us[0]; |
||
6830 | } |
||
6831 | break; |
||
6832 | case GL_UNSIGNED_INT_8_8_8_8: |
||
6833 | extract8888(myswapBytes,iter,extractComponents); |
||
6834 | for (k = 0; k < 4; k++) { |
||
6835 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6836 | } |
||
6837 | break; |
||
6838 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
6839 | extract8888rev(myswapBytes,iter,extractComponents); |
||
6840 | for (k = 0; k < 4; k++) { |
||
6841 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6842 | } |
||
6843 | break; |
||
6844 | case GL_UNSIGNED_INT_10_10_10_2: |
||
6845 | extract1010102(myswapBytes,iter,extractComponents); |
||
6846 | for (k = 0; k < 4; k++) { |
||
6847 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6848 | } |
||
6849 | break; |
||
6850 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
6851 | extract2101010rev(myswapBytes,iter,extractComponents); |
||
6852 | for (k = 0; k < 4; k++) { |
||
6853 | *iter2++ = (GLushort)(extractComponents[k]*65535); |
||
6854 | } |
||
6855 | break; |
||
6856 | case GL_INT: |
||
6857 | case GL_UNSIGNED_INT: |
||
6858 | case GL_FLOAT: |
||
6859 | if (myswapBytes) { |
||
6860 | widget.ub[0] = iter[3]; |
||
6861 | widget.ub[1] = iter[2]; |
||
6862 | widget.ub[2] = iter[1]; |
||
6863 | widget.ub[3] = iter[0]; |
||
6864 | } else { |
||
6865 | widget.ub[0] = iter[0]; |
||
6866 | widget.ub[1] = iter[1]; |
||
6867 | widget.ub[2] = iter[2]; |
||
6868 | widget.ub[3] = iter[3]; |
||
6869 | } |
||
6870 | if (type == GL_FLOAT) { |
||
6871 | if (indexFormat) { |
||
6872 | *iter2++ = widget.f; |
||
6873 | } else { |
||
6874 | *iter2++ = 65535 * widget.f; |
||
6875 | } |
||
6876 | } else if (type == GL_UNSIGNED_INT) { |
||
6877 | if (indexFormat) { |
||
6878 | *iter2++ = widget.ui; |
||
6879 | } else { |
||
6880 | *iter2++ = widget.ui >> 16; |
||
6881 | } |
||
6882 | } else { |
||
6883 | if (indexFormat) { |
||
6884 | *iter2++ = widget.i; |
||
6885 | } else { |
||
6886 | *iter2++ = widget.i >> 15; |
||
6887 | } |
||
6888 | } |
||
6889 | break; |
||
6890 | default: |
||
6891 | assert(0); |
||
6892 | } |
||
6893 | |||
6894 | iter+= elementSize; |
||
6895 | } /* for ww */ |
||
6896 | rowStart+= rowSize; |
||
6897 | |||
6898 | iter= rowStart; /* for assertion purposes */ |
||
6899 | } /* for hh */ |
||
6900 | |||
6901 | start+= imageSize; |
||
6902 | } /* for dd */ |
||
6903 | |||
6904 | /* iterators should be one byte past end */ |
||
6905 | if (!isTypePackedPixel(type)) { |
||
6906 | assert(iter2 == &newImage[width*height*depth*components]); |
||
6907 | } |
||
6908 | else { |
||
6909 | assert(iter2 == &newImage[width*height*depth* |
||
6910 | elements_per_group(format,0)]); |
||
6911 | } |
||
6912 | assert( iter == &((const GLubyte *)userImage)[rowSize*height*depth + |
||
6913 | psm->unpack_skip_rows * rowSize + |
||
6914 | psm->unpack_skip_pixels * groupSize + |
||
6915 | /*3dstuff*/ |
||
6916 | psm->unpack_skip_images * imageSize] ); |
||
6917 | } /* fillImage3D () */ |
||
6918 | |||
6919 | static void scaleInternal3D(GLint components, |
||
6920 | GLint widthIn, GLint heightIn, GLint depthIn, |
||
6921 | const GLushort *dataIn, |
||
6922 | GLint widthOut, GLint heightOut, GLint depthOut, |
||
6923 | GLushort *dataOut) |
||
6924 | { |
||
6925 | float x, lowx, highx, convx, halfconvx; |
||
6926 | float y, lowy, highy, convy, halfconvy; |
||
6927 | float z, lowz, highz, convz, halfconvz; |
||
6928 | float xpercent,ypercent,zpercent; |
||
6929 | float percent; |
||
6930 | /* Max components in a format is 4, so... */ |
||
6931 | float totals[4]; |
||
6932 | float volume; |
||
6933 | int i,j,d,k,zint,yint,xint,xindex,yindex,zindex; |
||
6934 | int temp; |
||
6935 | |||
6936 | convz = (float) depthIn/depthOut; |
||
6937 | convy = (float) heightIn/heightOut; |
||
6938 | convx = (float) widthIn/widthOut; |
||
6939 | halfconvx = convx/2; |
||
6940 | halfconvy = convy/2; |
||
6941 | halfconvz = convz/2; |
||
6942 | for (d = 0; d < depthOut; d++) { |
||
6943 | z = convz * (d+0.5); |
||
6944 | if (depthIn > depthOut) { |
||
6945 | highz = z + halfconvz; |
||
6946 | lowz = z - halfconvz; |
||
6947 | } else { |
||
6948 | highz = z + 0.5; |
||
6949 | lowz = z - 0.5; |
||
6950 | } |
||
6951 | for (i = 0; i < heightOut; i++) { |
||
6952 | y = convy * (i+0.5); |
||
6953 | if (heightIn > heightOut) { |
||
6954 | highy = y + halfconvy; |
||
6955 | lowy = y - halfconvy; |
||
6956 | } else { |
||
6957 | highy = y + 0.5; |
||
6958 | lowy = y - 0.5; |
||
6959 | } |
||
6960 | for (j = 0; j < widthOut; j++) { |
||
6961 | x = convx * (j+0.5); |
||
6962 | if (widthIn > widthOut) { |
||
6963 | highx = x + halfconvx; |
||
6964 | lowx = x - halfconvx; |
||
6965 | } else { |
||
6966 | highx = x + 0.5; |
||
6967 | lowx = x - 0.5; |
||
6968 | } |
||
6969 | |||
6970 | /* |
||
6971 | ** Ok, now apply box filter to box that goes from (lowx, lowy, |
||
6972 | ** lowz) to (highx, highy, highz) on input data into this pixel |
||
6973 | ** on output data. |
||
6974 | */ |
||
6975 | totals[0] = totals[1] = totals[2] = totals[3] = 0.0; |
||
6976 | volume = 0.0; |
||
6977 | |||
6978 | z = lowz; |
||
6979 | zint = floor(z); |
||
6980 | while (z < highz) { |
||
6981 | zindex = (zint + depthIn) % depthIn; |
||
6982 | if (highz < zint+1) { |
||
6983 | zpercent = highz - z; |
||
6984 | } else { |
||
6985 | zpercent = zint+1 - z; |
||
6986 | } |
||
6987 | |||
6988 | y = lowy; |
||
6989 | yint = floor(y); |
||
6990 | while (y < highy) { |
||
6991 | yindex = (yint + heightIn) % heightIn; |
||
6992 | if (highy < yint+1) { |
||
6993 | ypercent = highy - y; |
||
6994 | } else { |
||
6995 | ypercent = yint+1 - y; |
||
6996 | } |
||
6997 | |||
6998 | x = lowx; |
||
6999 | xint = floor(x); |
||
7000 | |||
7001 | while (x < highx) { |
||
7002 | xindex = (xint + widthIn) % widthIn; |
||
7003 | if (highx < xint+1) { |
||
7004 | xpercent = highx - x; |
||
7005 | } else { |
||
7006 | xpercent = xint+1 - x; |
||
7007 | } |
||
7008 | |||
7009 | percent = xpercent * ypercent * zpercent; |
||
7010 | volume += percent; |
||
7011 | |||
7012 | temp = (xindex + (yindex*widthIn) + |
||
7013 | (zindex*widthIn*heightIn)) * components; |
||
7014 | for (k = 0; k < components; k++) { |
||
7015 | assert(0 <= (temp+k) && |
||
7016 | (temp+k) < |
||
7017 | (widthIn*heightIn*depthIn*components)); |
||
7018 | totals[k] += dataIn[temp + k] * percent; |
||
7019 | } |
||
7020 | |||
7021 | xint++; |
||
7022 | x = xint; |
||
7023 | } /* while x */ |
||
7024 | |||
7025 | yint++; |
||
7026 | y = yint; |
||
7027 | } /* while y */ |
||
7028 | |||
7029 | zint++; |
||
7030 | z = zint; |
||
7031 | } /* while z */ |
||
7032 | |||
7033 | temp = (j + (i * widthOut) + |
||
7034 | (d*widthOut*heightOut)) * components; |
||
7035 | for (k = 0; k < components; k++) { |
||
7036 | /* totals[] should be rounded in the case of enlarging an |
||
7037 | * RGB ramp when the type is 332 or 4444 |
||
7038 | */ |
||
7039 | assert(0 <= (temp+k) && |
||
7040 | (temp+k) < (widthOut*heightOut*depthOut*components)); |
||
7041 | dataOut[temp + k] = (totals[k]+0.5)/volume; |
||
7042 | } |
||
7043 | } /* for j */ |
||
7044 | } /* for i */ |
||
7045 | } /* for d */ |
||
7046 | } /* scaleInternal3D() */ |
||
7047 | |||
7048 | static void emptyImage3D(const PixelStorageModes *psm, |
||
7049 | GLint width, GLint height, GLint depth, |
||
7050 | GLenum format, GLenum type, GLboolean indexFormat, |
||
7051 | const GLushort *oldImage, void *userImage) |
||
7052 | { |
||
7053 | int myswapBytes; |
||
7054 | int components; |
||
7055 | int groupsPerLine; |
||
7056 | int elementSize; |
||
7057 | int groupSize; |
||
7058 | int rowSize; |
||
7059 | int padding; |
||
7060 | GLubyte *start, *rowStart, *iter; |
||
7061 | int elementsPerLine; |
||
7062 | const GLushort *iter2; |
||
7063 | int ii, jj, dd, k; |
||
7064 | int rowsPerImage; |
||
7065 | int imageSize; |
||
7066 | |||
7067 | myswapBytes= psm->pack_swap_bytes; |
||
7068 | components = elements_per_group(format,type); |
||
7069 | if (psm->pack_row_length > 0) { |
||
7070 | groupsPerLine = psm->pack_row_length; |
||
7071 | } |
||
7072 | else { |
||
7073 | groupsPerLine = width; |
||
7074 | } |
||
7075 | |||
7076 | elementSize= bytes_per_element(type); |
||
7077 | groupSize= elementSize * components; |
||
7078 | if (elementSize == 1) myswapBytes= 0; |
||
7079 | |||
7080 | /* 3dstuff begin */ |
||
7081 | if (psm->pack_image_height > 0) { |
||
7082 | rowsPerImage= psm->pack_image_height; |
||
7083 | } |
||
7084 | else { |
||
7085 | rowsPerImage= height; |
||
7086 | } |
||
7087 | |||
7088 | /* 3dstuff end */ |
||
7089 | |||
7090 | rowSize = groupsPerLine * groupSize; |
||
7091 | padding = rowSize % psm->pack_alignment; |
||
7092 | if (padding) { |
||
7093 | rowSize+= psm->pack_alignment - padding; |
||
7094 | } |
||
7095 | |||
7096 | imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
||
7097 | |||
7098 | start = (GLubyte *)userImage + psm->pack_skip_rows * rowSize + |
||
7099 | psm->pack_skip_pixels * groupSize + |
||
7100 | /*3dstuff*/ |
||
7101 | psm->pack_skip_images * imageSize; |
||
7102 | elementsPerLine= width * components; |
||
7103 | |||
7104 | iter2 = oldImage; |
||
7105 | for (dd= 0; dd < depth; dd++) { |
||
7106 | rowStart= start; |
||
7107 | |||
7108 | for (ii= 0; ii< height; ii++) { |
||
7109 | iter = rowStart; |
||
7110 | |||
7111 | for (jj = 0; jj < elementsPerLine; jj++) { |
||
7112 | Type_Widget widget; |
||
7113 | float shoveComponents[4]; |
||
7114 | |||
7115 | switch(type){ |
||
7116 | case GL_UNSIGNED_BYTE: |
||
7117 | if (indexFormat) { |
||
7118 | *iter = *iter2++; |
||
7119 | } else { |
||
7120 | *iter = *iter2++ >> 8; |
||
7121 | } |
||
7122 | break; |
||
7123 | case GL_BYTE: |
||
7124 | if (indexFormat) { |
||
7125 | *((GLbyte *) iter) = *iter2++; |
||
7126 | } else { |
||
7127 | *((GLbyte *) iter) = *iter2++ >> 9; |
||
7128 | } |
||
7129 | break; |
||
7130 | case GL_UNSIGNED_BYTE_3_3_2: |
||
7131 | for (k = 0; k < 3; k++) { |
||
7132 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7133 | } |
||
7134 | shove332(shoveComponents,0,(void *)iter); |
||
7135 | break; |
||
7136 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
7137 | for (k = 0; k < 3; k++) { |
||
7138 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7139 | } |
||
7140 | shove233rev(shoveComponents,0,(void *)iter); |
||
7141 | break; |
||
7142 | case GL_UNSIGNED_SHORT_5_6_5: |
||
7143 | for (k = 0; k < 3; k++) { |
||
7144 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7145 | } |
||
7146 | shove565(shoveComponents,0,(void *)&widget.us[0]); |
||
7147 | if (myswapBytes) { |
||
7148 | iter[0] = widget.ub[1]; |
||
7149 | iter[1] = widget.ub[0]; |
||
7150 | } |
||
7151 | else { |
||
7152 | *(GLushort *)iter = widget.us[0]; |
||
7153 | } |
||
7154 | break; |
||
7155 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
7156 | for (k = 0; k < 3; k++) { |
||
7157 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7158 | } |
||
7159 | shove565rev(shoveComponents,0,(void *)&widget.us[0]); |
||
7160 | if (myswapBytes) { |
||
7161 | iter[0] = widget.ub[1]; |
||
7162 | iter[1] = widget.ub[0]; |
||
7163 | } |
||
7164 | else { |
||
7165 | *(GLushort *)iter = widget.us[0]; |
||
7166 | } |
||
7167 | break; |
||
7168 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
7169 | for (k = 0; k < 4; k++) { |
||
7170 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7171 | } |
||
7172 | shove4444(shoveComponents,0,(void *)&widget.us[0]); |
||
7173 | if (myswapBytes) { |
||
7174 | iter[0] = widget.ub[1]; |
||
7175 | iter[1] = widget.ub[0]; |
||
7176 | } else { |
||
7177 | *(GLushort *)iter = widget.us[0]; |
||
7178 | } |
||
7179 | break; |
||
7180 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
7181 | for (k = 0; k < 4; k++) { |
||
7182 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7183 | } |
||
7184 | shove4444rev(shoveComponents,0,(void *)&widget.us[0]); |
||
7185 | if (myswapBytes) { |
||
7186 | iter[0] = widget.ub[1]; |
||
7187 | iter[1] = widget.ub[0]; |
||
7188 | } else { |
||
7189 | *(GLushort *)iter = widget.us[0]; |
||
7190 | } |
||
7191 | break; |
||
7192 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
7193 | for (k = 0; k < 4; k++) { |
||
7194 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7195 | } |
||
7196 | shove5551(shoveComponents,0,(void *)&widget.us[0]); |
||
7197 | if (myswapBytes) { |
||
7198 | iter[0] = widget.ub[1]; |
||
7199 | iter[1] = widget.ub[0]; |
||
7200 | } else { |
||
7201 | *(GLushort *)iter = widget.us[0]; |
||
7202 | } |
||
7203 | break; |
||
7204 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
7205 | for (k = 0; k < 4; k++) { |
||
7206 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7207 | } |
||
7208 | shove1555rev(shoveComponents,0,(void *)&widget.us[0]); |
||
7209 | if (myswapBytes) { |
||
7210 | iter[0] = widget.ub[1]; |
||
7211 | iter[1] = widget.ub[0]; |
||
7212 | } else { |
||
7213 | *(GLushort *)iter = widget.us[0]; |
||
7214 | } |
||
7215 | break; |
||
7216 | case GL_UNSIGNED_SHORT: |
||
7217 | case GL_SHORT: |
||
7218 | if (type == GL_SHORT) { |
||
7219 | if (indexFormat) { |
||
7220 | widget.s[0] = *iter2++; |
||
7221 | } else { |
||
7222 | widget.s[0] = *iter2++ >> 1; |
||
7223 | } |
||
7224 | } else { |
||
7225 | widget.us[0] = *iter2++; |
||
7226 | } |
||
7227 | if (myswapBytes) { |
||
7228 | iter[0] = widget.ub[1]; |
||
7229 | iter[1] = widget.ub[0]; |
||
7230 | } else { |
||
7231 | iter[0] = widget.ub[0]; |
||
7232 | iter[1] = widget.ub[1]; |
||
7233 | } |
||
7234 | break; |
||
7235 | case GL_UNSIGNED_INT_8_8_8_8: |
||
7236 | for (k = 0; k < 4; k++) { |
||
7237 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7238 | } |
||
7239 | shove8888(shoveComponents,0,(void *)&widget.ui); |
||
7240 | if (myswapBytes) { |
||
7241 | iter[3] = widget.ub[0]; |
||
7242 | iter[2] = widget.ub[1]; |
||
7243 | iter[1] = widget.ub[2]; |
||
7244 | iter[0] = widget.ub[3]; |
||
7245 | } else { |
||
7246 | *(GLuint *)iter= widget.ui; |
||
7247 | } |
||
7248 | break; |
||
7249 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
7250 | for (k = 0; k < 4; k++) { |
||
7251 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7252 | } |
||
7253 | shove8888rev(shoveComponents,0,(void *)&widget.ui); |
||
7254 | if (myswapBytes) { |
||
7255 | iter[3] = widget.ub[0]; |
||
7256 | iter[2] = widget.ub[1]; |
||
7257 | iter[1] = widget.ub[2]; |
||
7258 | iter[0] = widget.ub[3]; |
||
7259 | } else { |
||
7260 | *(GLuint *)iter= widget.ui; |
||
7261 | } |
||
7262 | break; |
||
7263 | case GL_UNSIGNED_INT_10_10_10_2: |
||
7264 | for (k = 0; k < 4; k++) { |
||
7265 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7266 | } |
||
7267 | shove1010102(shoveComponents,0,(void *)&widget.ui); |
||
7268 | if (myswapBytes) { |
||
7269 | iter[3] = widget.ub[0]; |
||
7270 | iter[2] = widget.ub[1]; |
||
7271 | iter[1] = widget.ub[2]; |
||
7272 | iter[0] = widget.ub[3]; |
||
7273 | } else { |
||
7274 | *(GLuint *)iter= widget.ui; |
||
7275 | } |
||
7276 | break; |
||
7277 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
7278 | for (k = 0; k < 4; k++) { |
||
7279 | shoveComponents[k]= *iter2++ / 65535.0; |
||
7280 | } |
||
7281 | shove2101010rev(shoveComponents,0,(void *)&widget.ui); |
||
7282 | if (myswapBytes) { |
||
7283 | iter[3] = widget.ub[0]; |
||
7284 | iter[2] = widget.ub[1]; |
||
7285 | iter[1] = widget.ub[2]; |
||
7286 | iter[0] = widget.ub[3]; |
||
7287 | } else { |
||
7288 | *(GLuint *)iter= widget.ui; |
||
7289 | } |
||
7290 | break; |
||
7291 | case GL_INT: |
||
7292 | case GL_UNSIGNED_INT: |
||
7293 | case GL_FLOAT: |
||
7294 | if (type == GL_FLOAT) { |
||
7295 | if (indexFormat) { |
||
7296 | widget.f = *iter2++; |
||
7297 | } else { |
||
7298 | widget.f = *iter2++ / (float) 65535.0; |
||
7299 | } |
||
7300 | } else if (type == GL_UNSIGNED_INT) { |
||
7301 | if (indexFormat) { |
||
7302 | widget.ui = *iter2++; |
||
7303 | } else { |
||
7304 | widget.ui = (unsigned int) *iter2++ * 65537; |
||
7305 | } |
||
7306 | } else { |
||
7307 | if (indexFormat) { |
||
7308 | widget.i = *iter2++; |
||
7309 | } else { |
||
7310 | widget.i = ((unsigned int) *iter2++ * 65537)/2; |
||
7311 | } |
||
7312 | } |
||
7313 | if (myswapBytes) { |
||
7314 | iter[3] = widget.ub[0]; |
||
7315 | iter[2] = widget.ub[1]; |
||
7316 | iter[1] = widget.ub[2]; |
||
7317 | iter[0] = widget.ub[3]; |
||
7318 | } else { |
||
7319 | iter[0] = widget.ub[0]; |
||
7320 | iter[1] = widget.ub[1]; |
||
7321 | iter[2] = widget.ub[2]; |
||
7322 | iter[3] = widget.ub[3]; |
||
7323 | } |
||
7324 | break; |
||
7325 | default: |
||
7326 | assert(0); |
||
7327 | } |
||
7328 | |||
7329 | iter+= elementSize; |
||
7330 | } /* for jj */ |
||
7331 | |||
7332 | rowStart+= rowSize; |
||
7333 | } /* for ii */ |
||
7334 | |||
7335 | start+= imageSize; |
||
7336 | } /* for dd */ |
||
7337 | |||
7338 | /* iterators should be one byte past end */ |
||
7339 | if (!isTypePackedPixel(type)) { |
||
7340 | assert(iter2 == &oldImage[width*height*depth*components]); |
||
7341 | } |
||
7342 | else { |
||
7343 | assert(iter2 == &oldImage[width*height*depth* |
||
7344 | elements_per_group(format,0)]); |
||
7345 | } |
||
7346 | assert( iter == &((GLubyte *)userImage)[rowSize*height*depth + |
||
7347 | psm->unpack_skip_rows * rowSize + |
||
7348 | psm->unpack_skip_pixels * groupSize + |
||
7349 | /*3dstuff*/ |
||
7350 | psm->unpack_skip_images * imageSize] ); |
||
7351 | } /* emptyImage3D() */ |
||
7352 | |||
7353 | static |
||
7354 | int gluScaleImage3D(GLenum format, |
||
7355 | GLint widthIn, GLint heightIn, GLint depthIn, |
||
7356 | GLenum typeIn, const void *dataIn, |
||
7357 | GLint widthOut, GLint heightOut, GLint depthOut, |
||
7358 | GLenum typeOut, void *dataOut) |
||
7359 | { |
||
7360 | int components; |
||
7361 | GLushort *beforeImage, *afterImage; |
||
7362 | PixelStorageModes psm; |
||
7363 | |||
7364 | if (widthIn == 0 || heightIn == 0 || depthIn == 0 || |
||
7365 | widthOut == 0 || heightOut == 0 || depthOut == 0) { |
||
7366 | return 0; |
||
7367 | } |
||
7368 | |||
7369 | if (widthIn < 0 || heightIn < 0 || depthIn < 0 || |
||
7370 | widthOut < 0 || heightOut < 0 || depthOut < 0) { |
||
7371 | return GLU_INVALID_VALUE; |
||
7372 | } |
||
7373 | |||
7374 | if (!legalFormat(format) || !legalType(typeIn) || !legalType(typeOut) || |
||
7375 | typeIn == GL_BITMAP || typeOut == GL_BITMAP) { |
||
7376 | return GLU_INVALID_ENUM; |
||
7377 | } |
||
7378 | if (!isLegalFormatForPackedPixelType(format, typeIn)) { |
||
7379 | return GLU_INVALID_OPERATION; |
||
7380 | } |
||
7381 | if (!isLegalFormatForPackedPixelType(format, typeOut)) { |
||
7382 | return GLU_INVALID_OPERATION; |
||
7383 | } |
||
7384 | |||
7385 | beforeImage = malloc(imageSize3D(widthIn, heightIn, depthIn, format, |
||
7386 | GL_UNSIGNED_SHORT)); |
||
7387 | afterImage = malloc(imageSize3D(widthOut, heightOut, depthOut, format, |
||
7388 | GL_UNSIGNED_SHORT)); |
||
7389 | if (beforeImage == NULL || afterImage == NULL) { |
||
7390 | free(beforeImage); |
||
7391 | free(afterImage); |
||
7392 | return GLU_OUT_OF_MEMORY; |
||
7393 | } |
||
7394 | retrieveStoreModes3D(&psm); |
||
7395 | |||
7396 | fillImage3D(&psm,widthIn,heightIn,depthIn,format,typeIn, is_index(format), |
||
7397 | dataIn, beforeImage); |
||
7398 | components = elements_per_group(format,0); |
||
7399 | scaleInternal3D(components,widthIn,heightIn,depthIn,beforeImage, |
||
7400 | widthOut,heightOut,depthOut,afterImage); |
||
7401 | emptyImage3D(&psm,widthOut,heightOut,depthOut,format,typeOut, |
||
7402 | is_index(format),afterImage, dataOut); |
||
7403 | free((void *) beforeImage); |
||
7404 | free((void *) afterImage); |
||
7405 | |||
7406 | return 0; |
||
7407 | } /* gluScaleImage3D() */ |
||
7408 | |||
7409 | |||
7410 | static void closestFit3D(GLenum target, GLint width, GLint height, GLint depth, |
||
7411 | GLint internalFormat, GLenum format, GLenum type, |
||
7412 | GLint *newWidth, GLint *newHeight, GLint *newDepth) |
||
7413 | { |
||
7414 | GLint widthPowerOf2= nearestPower(width); |
||
7415 | GLint heightPowerOf2= nearestPower(height); |
||
7416 | GLint depthPowerOf2= nearestPower(depth); |
||
7417 | GLint proxyWidth; |
||
7418 | |||
7419 | do { |
||
7420 | /* compute level 1 width & height & depth, clamping each at 1 */ |
||
7421 | GLint widthAtLevelOne= (widthPowerOf2 > 1) ? |
||
7422 | widthPowerOf2 >> 1 : |
||
7423 | widthPowerOf2; |
||
7424 | GLint heightAtLevelOne= (heightPowerOf2 > 1) ? |
||
7425 | heightPowerOf2 >> 1 : |
||
7426 | heightPowerOf2; |
||
7427 | GLint depthAtLevelOne= (depthPowerOf2 > 1) ? |
||
7428 | depthPowerOf2 >> 1 : |
||
7429 | depthPowerOf2; |
||
7430 | GLenum proxyTarget = GL_PROXY_TEXTURE_3D; |
||
7431 | assert(widthAtLevelOne > 0); |
||
7432 | assert(heightAtLevelOne > 0); |
||
7433 | assert(depthAtLevelOne > 0); |
||
7434 | |||
7435 | /* does width x height x depth at level 1 & all their mipmaps fit? */ |
||
7436 | assert(target == GL_TEXTURE_3D || target == GL_PROXY_TEXTURE_3D); |
||
7437 | gluTexImage3D(proxyTarget, 1, /* must be non-zero */ |
||
7438 | internalFormat, |
||
7439 | widthAtLevelOne,heightAtLevelOne,depthAtLevelOne, |
||
7440 | 0,format,type,NULL); |
||
7441 | glGetTexLevelParameteriv(proxyTarget, 1,GL_TEXTURE_WIDTH,&proxyWidth); |
||
7442 | /* does it fit??? */ |
||
7443 | if (proxyWidth == 0) { /* nope, so try again with these sizes */ |
||
7444 | if (widthPowerOf2 == 1 && heightPowerOf2 == 1 && |
||
7445 | depthPowerOf2 == 1) { |
||
7446 | *newWidth= *newHeight= *newDepth= 1; /* must fit 1x1x1 texture */ |
||
7447 | return; |
||
7448 | } |
||
7449 | widthPowerOf2= widthAtLevelOne; |
||
7450 | heightPowerOf2= heightAtLevelOne; |
||
7451 | depthPowerOf2= depthAtLevelOne; |
||
7452 | } |
||
7453 | /* else it does fit */ |
||
7454 | } while (proxyWidth == 0); |
||
7455 | /* loop must terminate! */ |
||
7456 | |||
7457 | /* return the width & height at level 0 that fits */ |
||
7458 | *newWidth= widthPowerOf2; |
||
7459 | *newHeight= heightPowerOf2; |
||
7460 | *newDepth= depthPowerOf2; |
||
7461 | /*printf("Proxy Textures\n");*/ |
||
7462 | } /* closestFit3D() */ |
||
7463 | |||
7464 | static void halveImagePackedPixelSlice(int components, |
||
7465 | void (*extractPackedPixel) |
||
7466 | (int, const void *,GLfloat []), |
||
7467 | void (*shovePackedPixel) |
||
7468 | (const GLfloat [],int, void *), |
||
7469 | GLint width, GLint height, GLint depth, |
||
7470 | const void *dataIn, void *dataOut, |
||
7471 | GLint pixelSizeInBytes, |
||
7472 | GLint rowSizeInBytes, |
||
7473 | GLint imageSizeInBytes, |
||
7474 | GLint isSwap) |
||
7475 | { |
||
7476 | int ii, jj; |
||
7477 | int halfWidth= width / 2; |
||
7478 | int halfHeight= height / 2; |
||
7479 | int halfDepth= depth / 2; |
||
7480 | const char *src= (const char *)dataIn; |
||
7481 | int outIndex= 0; |
||
7482 | |||
7483 | assert((width == 1 || height == 1) && depth >= 2); |
||
7484 | |||
7485 | if (width == height) { /* a 1-pixel column viewed from top */ |
||
7486 | assert(width == 1 && height == 1); |
||
7487 | assert(depth >= 2); |
||
7488 | |||
7489 | for (ii= 0; ii< halfDepth; ii++) { |
||
7490 | float totals[4]; |
||
7491 | float extractTotals[BOX2][4]; |
||
7492 | int cc; |
||
7493 | |||
7494 | (*extractPackedPixel)(isSwap,src,&extractTotals[0][0]); |
||
7495 | (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
||
7496 | &extractTotals[1][0]); |
||
7497 | for (cc = 0; cc < components; cc++) { |
||
7498 | int kk; |
||
7499 | |||
7500 | /* average 2 pixels since only a column */ |
||
7501 | totals[cc]= 0.0; |
||
7502 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
||
7503 | * totals[RED]/= 2.0; |
||
7504 | */ |
||
7505 | for (kk = 0; kk < BOX2; kk++) { |
||
7506 | totals[cc]+= extractTotals[kk][cc]; |
||
7507 | } |
||
7508 | totals[cc]/= (float)BOX2; |
||
7509 | } /* for cc */ |
||
7510 | |||
7511 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
7512 | outIndex++; |
||
7513 | /* skip over to next group of 2 */ |
||
7514 | src+= imageSizeInBytes + imageSizeInBytes; |
||
7515 | } /* for ii */ |
||
7516 | } |
||
7517 | else if (height == 1) { /* horizontal slice viewed from top */ |
||
7518 | assert(width != 1); |
||
7519 | |||
7520 | for (ii= 0; ii< halfDepth; ii++) { |
||
7521 | for (jj= 0; jj< halfWidth; jj++) { |
||
7522 | float totals[4]; |
||
7523 | float extractTotals[BOX4][4]; |
||
7524 | int cc; |
||
7525 | |||
7526 | (*extractPackedPixel)(isSwap,src, |
||
7527 | &extractTotals[0][0]); |
||
7528 | (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
||
7529 | &extractTotals[1][0]); |
||
7530 | (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
||
7531 | &extractTotals[2][0]); |
||
7532 | (*extractPackedPixel)(isSwap, |
||
7533 | (src+imageSizeInBytes+pixelSizeInBytes), |
||
7534 | &extractTotals[3][0]); |
||
7535 | for (cc = 0; cc < components; cc++) { |
||
7536 | int kk; |
||
7537 | |||
7538 | /* grab 4 pixels to average */ |
||
7539 | totals[cc]= 0.0; |
||
7540 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
7541 | * extractTotals[2][RED]+extractTotals[3][RED]; |
||
7542 | * totals[RED]/= 4.0; |
||
7543 | */ |
||
7544 | for (kk = 0; kk < BOX4; kk++) { |
||
7545 | totals[cc]+= extractTotals[kk][cc]; |
||
7546 | } |
||
7547 | totals[cc]/= (float)BOX4; |
||
7548 | } |
||
7549 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
7550 | |||
7551 | outIndex++; |
||
7552 | /* skip over to next horizontal square of 4 */ |
||
7553 | src+= imageSizeInBytes + imageSizeInBytes; |
||
7554 | } |
||
7555 | } |
||
7556 | |||
7557 | /* assert() */ |
||
7558 | } |
||
7559 | else if (width == 1) { /* vertical slice viewed from top */ |
||
7560 | assert(height != 1); |
||
7561 | |||
7562 | for (ii= 0; ii< halfDepth; ii++) { |
||
7563 | for (jj= 0; jj< halfHeight; jj++) { |
||
7564 | float totals[4]; |
||
7565 | float extractTotals[BOX4][4]; |
||
7566 | int cc; |
||
7567 | |||
7568 | (*extractPackedPixel)(isSwap,src, |
||
7569 | &extractTotals[0][0]); |
||
7570 | (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
||
7571 | &extractTotals[1][0]); |
||
7572 | (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
||
7573 | &extractTotals[2][0]); |
||
7574 | (*extractPackedPixel)(isSwap, |
||
7575 | (src+imageSizeInBytes+rowSizeInBytes), |
||
7576 | &extractTotals[3][0]); |
||
7577 | for (cc = 0; cc < components; cc++) { |
||
7578 | int kk; |
||
7579 | |||
7580 | /* grab 4 pixels to average */ |
||
7581 | totals[cc]= 0.0; |
||
7582 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
7583 | * extractTotals[2][RED]+extractTotals[3][RED]; |
||
7584 | * totals[RED]/= 4.0; |
||
7585 | */ |
||
7586 | for (kk = 0; kk < BOX4; kk++) { |
||
7587 | totals[cc]+= extractTotals[kk][cc]; |
||
7588 | } |
||
7589 | totals[cc]/= (float)BOX4; |
||
7590 | } |
||
7591 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
7592 | |||
7593 | outIndex++; |
||
7594 | |||
7595 | /* skip over to next vertical square of 4 */ |
||
7596 | src+= imageSizeInBytes + imageSizeInBytes; |
||
7597 | } |
||
7598 | } |
||
7599 | /* assert() */ |
||
7600 | } |
||
7601 | |||
7602 | } /* halveImagePackedPixelSlice() */ |
||
7603 | |||
7604 | static void halveImagePackedPixel3D(int components, |
||
7605 | void (*extractPackedPixel) |
||
7606 | (int, const void *,GLfloat []), |
||
7607 | void (*shovePackedPixel) |
||
7608 | (const GLfloat [],int, void *), |
||
7609 | GLint width, GLint height, GLint depth, |
||
7610 | const void *dataIn, void *dataOut, |
||
7611 | GLint pixelSizeInBytes, |
||
7612 | GLint rowSizeInBytes, |
||
7613 | GLint imageSizeInBytes, |
||
7614 | GLint isSwap) |
||
7615 | { |
||
7616 | if (depth == 1) { |
||
7617 | assert(1 <= width && 1 <= height); |
||
7618 | |||
7619 | halveImagePackedPixel(components,extractPackedPixel,shovePackedPixel, |
||
7620 | width,height,dataIn,dataOut,pixelSizeInBytes, |
||
7621 | rowSizeInBytes,isSwap); |
||
7622 | return; |
||
7623 | } |
||
7624 | /* a horizontal or vertical slice viewed from top */ |
||
7625 | else if (width == 1 || height == 1) { |
||
7626 | assert(1 <= depth); |
||
7627 | |||
7628 | halveImagePackedPixelSlice(components, |
||
7629 | extractPackedPixel,shovePackedPixel, |
||
7630 | width, height, depth, dataIn, dataOut, |
||
7631 | pixelSizeInBytes, rowSizeInBytes, |
||
7632 | imageSizeInBytes, isSwap); |
||
7633 | return; |
||
7634 | } |
||
7635 | { |
||
7636 | int ii, jj, dd; |
||
7637 | |||
7638 | int halfWidth= width / 2; |
||
7639 | int halfHeight= height / 2; |
||
7640 | int halfDepth= depth / 2; |
||
7641 | const char *src= (const char *) dataIn; |
||
7642 | int padBytes= rowSizeInBytes - (width*pixelSizeInBytes); |
||
7643 | int outIndex= 0; |
||
7644 | |||
7645 | for (dd= 0; dd < halfDepth; dd++) { |
||
7646 | for (ii= 0; ii< halfHeight; ii++) { |
||
7647 | for (jj= 0; jj< halfWidth; jj++) { |
||
7648 | #define BOX8 8 |
||
7649 | float totals[4]; /* 4 is maximum components */ |
||
7650 | float extractTotals[BOX8][4]; /* 4 is maximum components */ |
||
7651 | int cc; |
||
7652 | |||
7653 | (*extractPackedPixel)(isSwap,src, |
||
7654 | &extractTotals[0][0]); |
||
7655 | (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes), |
||
7656 | &extractTotals[1][0]); |
||
7657 | (*extractPackedPixel)(isSwap,(src+rowSizeInBytes), |
||
7658 | &extractTotals[2][0]); |
||
7659 | (*extractPackedPixel)(isSwap, |
||
7660 | (src+rowSizeInBytes+pixelSizeInBytes), |
||
7661 | &extractTotals[3][0]); |
||
7662 | |||
7663 | (*extractPackedPixel)(isSwap,(src+imageSizeInBytes), |
||
7664 | &extractTotals[4][0]); |
||
7665 | (*extractPackedPixel)(isSwap,(src+pixelSizeInBytes+imageSizeInBytes), |
||
7666 | &extractTotals[5][0]); |
||
7667 | (*extractPackedPixel)(isSwap,(src+rowSizeInBytes+imageSizeInBytes), |
||
7668 | &extractTotals[6][0]); |
||
7669 | (*extractPackedPixel)(isSwap, |
||
7670 | (src+rowSizeInBytes+pixelSizeInBytes+imageSizeInBytes), |
||
7671 | &extractTotals[7][0]); |
||
7672 | for (cc = 0; cc < components; cc++) { |
||
7673 | int kk; |
||
7674 | |||
7675 | /* grab 8 pixels to average */ |
||
7676 | totals[cc]= 0.0; |
||
7677 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
7678 | * extractTotals[2][RED]+extractTotals[3][RED]+ |
||
7679 | * extractTotals[4][RED]+extractTotals[5][RED]+ |
||
7680 | * extractTotals[6][RED]+extractTotals[7][RED]; |
||
7681 | * totals[RED]/= 8.0; |
||
7682 | */ |
||
7683 | for (kk = 0; kk < BOX8; kk++) { |
||
7684 | totals[cc]+= extractTotals[kk][cc]; |
||
7685 | } |
||
7686 | totals[cc]/= (float)BOX8; |
||
7687 | } |
||
7688 | (*shovePackedPixel)(totals,outIndex,dataOut); |
||
7689 | |||
7690 | outIndex++; |
||
7691 | /* skip over to next square of 4 */ |
||
7692 | src+= pixelSizeInBytes + pixelSizeInBytes; |
||
7693 | } |
||
7694 | /* skip past pad bytes, if any, to get to next row */ |
||
7695 | src+= padBytes; |
||
7696 | |||
7697 | /* src is at beginning of a row here, but it's the second row of |
||
7698 | * the square block of 4 pixels that we just worked on so we |
||
7699 | * need to go one more row. |
||
7700 | * i.e., |
||
7701 | * OO... |
||
7702 | * here -->OO... |
||
7703 | * but want -->OO... |
||
7704 | * OO... |
||
7705 | * ... |
||
7706 | */ |
||
7707 | src+= rowSizeInBytes; |
||
7708 | } |
||
7709 | |||
7710 | src+= imageSizeInBytes; |
||
7711 | } /* for dd */ |
||
7712 | |||
7713 | /* both pointers must reach one byte after the end */ |
||
7714 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
||
7715 | assert(outIndex == halfWidth * halfHeight * halfDepth); |
||
7716 | } /* for dd */ |
||
7717 | |||
7718 | } /* halveImagePackedPixel3D() */ |
||
7719 | |||
7720 | static int gluBuild3DMipmapLevelsCore(GLenum target, GLint internalFormat, |
||
7721 | GLsizei width, |
||
7722 | GLsizei height, |
||
7723 | GLsizei depth, |
||
7724 | GLsizei widthPowerOf2, |
||
7725 | GLsizei heightPowerOf2, |
||
7726 | GLsizei depthPowerOf2, |
||
7727 | GLenum format, GLenum type, |
||
7728 | GLint userLevel, |
||
7729 | GLint baseLevel,GLint maxLevel, |
||
7730 | const void *data) |
||
7731 | { |
||
7732 | GLint newWidth, newHeight, newDepth; |
||
7733 | GLint level, levels; |
||
7734 | const void *usersImage; |
||
7735 | void *srcImage, *dstImage; |
||
7736 | __GLU_INIT_SWAP_IMAGE; |
||
7737 | GLint memReq; |
||
7738 | GLint cmpts; |
||
7739 | |||
7740 | GLint myswapBytes, groupsPerLine, elementSize, groupSize; |
||
7741 | GLint rowsPerImage, imageSize; |
||
7742 | GLint rowSize, padding; |
||
7743 | PixelStorageModes psm; |
||
7744 | |||
7745 | assert(checkMipmapArgs(internalFormat,format,type) == 0); |
||
7746 | assert(width >= 1 && height >= 1 && depth >= 1); |
||
7747 | assert(type != GL_BITMAP); |
||
7748 | |||
7749 | srcImage = dstImage = NULL; |
||
7750 | |||
7751 | newWidth= widthPowerOf2; |
||
7752 | newHeight= heightPowerOf2; |
||
7753 | newDepth= depthPowerOf2; |
||
7754 | levels = computeLog(newWidth); |
||
7755 | level = computeLog(newHeight); |
||
7756 | if (level > levels) levels=level; |
||
7757 | level = computeLog(newDepth); |
||
7758 | if (level > levels) levels=level; |
||
7759 | |||
7760 | levels+= userLevel; |
||
7761 | |||
7762 | retrieveStoreModes3D(&psm); |
||
7763 | myswapBytes = psm.unpack_swap_bytes; |
||
7764 | cmpts = elements_per_group(format,type); |
||
7765 | if (psm.unpack_row_length > 0) { |
||
7766 | groupsPerLine = psm.unpack_row_length; |
||
7767 | } else { |
||
7768 | groupsPerLine = width; |
||
7769 | } |
||
7770 | |||
7771 | elementSize = bytes_per_element(type); |
||
7772 | groupSize = elementSize * cmpts; |
||
7773 | if (elementSize == 1) myswapBytes = 0; |
||
7774 | |||
7775 | /* 3dstuff begin */ |
||
7776 | if (psm.unpack_image_height > 0) { |
||
7777 | rowsPerImage= psm.unpack_image_height; |
||
7778 | } |
||
7779 | else { |
||
7780 | rowsPerImage= height; |
||
7781 | } |
||
7782 | |||
7783 | /* 3dstuff end */ |
||
7784 | rowSize = groupsPerLine * groupSize; |
||
7785 | padding = (rowSize % psm.unpack_alignment); |
||
7786 | if (padding) { |
||
7787 | rowSize += psm.unpack_alignment - padding; |
||
7788 | } |
||
7789 | |||
7790 | imageSize= rowsPerImage * rowSize; /* 3dstuff */ |
||
7791 | |||
7792 | usersImage = (const GLubyte *)data + psm.unpack_skip_rows * rowSize + |
||
7793 | psm.unpack_skip_pixels * groupSize + |
||
7794 | /* 3dstuff */ |
||
7795 | psm.unpack_skip_images * imageSize; |
||
7796 | |||
7797 | glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); |
||
7798 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); |
||
7799 | glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); |
||
7800 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, 0); |
||
7801 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); |
||
7802 | |||
7803 | level = userLevel; |
||
7804 | |||
7805 | if (width == newWidth && height == newHeight && depth == newDepth) { |
||
7806 | /* Use usersImage for level userLevel */ |
||
7807 | if (baseLevel <= level && level <= maxLevel) { |
||
7808 | gluTexImage3D(target, level, internalFormat, width, |
||
7809 | height, depth, 0, format, type, |
||
7810 | usersImage); |
||
7811 | } |
||
7812 | if(levels == 0) { /* we're done. clean up and return */ |
||
7813 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
7814 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
7815 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
7816 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
7817 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
7818 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
7819 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
7820 | return 0; |
||
7821 | } |
||
7822 | { |
||
7823 | int nextWidth= newWidth/2; |
||
7824 | int nextHeight= newHeight/2; |
||
7825 | int nextDepth= newDepth/2; |
||
7826 | |||
7827 | /* clamp to 1 */ |
||
7828 | if (nextWidth < 1) nextWidth= 1; |
||
7829 | if (nextHeight < 1) nextHeight= 1; |
||
7830 | if (nextDepth < 1) nextDepth= 1; |
||
7831 | memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); |
||
7832 | } |
||
7833 | switch(type) { |
||
7834 | case GL_UNSIGNED_BYTE: |
||
7835 | dstImage = (GLubyte *)malloc(memReq); |
||
7836 | break; |
||
7837 | case GL_BYTE: |
||
7838 | dstImage = (GLbyte *)malloc(memReq); |
||
7839 | break; |
||
7840 | case GL_UNSIGNED_SHORT: |
||
7841 | dstImage = (GLushort *)malloc(memReq); |
||
7842 | break; |
||
7843 | case GL_SHORT: |
||
7844 | dstImage = (GLshort *)malloc(memReq); |
||
7845 | break; |
||
7846 | case GL_UNSIGNED_INT: |
||
7847 | dstImage = (GLuint *)malloc(memReq); |
||
7848 | break; |
||
7849 | case GL_INT: |
||
7850 | dstImage = (GLint *)malloc(memReq); |
||
7851 | break; |
||
7852 | case GL_FLOAT: |
||
7853 | dstImage = (GLfloat *)malloc(memReq); |
||
7854 | break; |
||
7855 | case GL_UNSIGNED_BYTE_3_3_2: |
||
7856 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
7857 | dstImage = (GLubyte *)malloc(memReq); |
||
7858 | break; |
||
7859 | case GL_UNSIGNED_SHORT_5_6_5: |
||
7860 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
7861 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
7862 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
7863 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
7864 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
7865 | dstImage = (GLushort *)malloc(memReq); |
||
7866 | break; |
||
7867 | case GL_UNSIGNED_INT_8_8_8_8: |
||
7868 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
7869 | case GL_UNSIGNED_INT_10_10_10_2: |
||
7870 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
7871 | dstImage = (GLuint *)malloc(memReq); |
||
7872 | break; |
||
7873 | default: |
||
7874 | return GLU_INVALID_ENUM; /* assertion */ |
||
7875 | } |
||
7876 | if (dstImage == NULL) { |
||
7877 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
7878 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
7879 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
7880 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
7881 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
7882 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
7883 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
7884 | return GLU_OUT_OF_MEMORY; |
||
7885 | } |
||
7886 | else |
||
7887 | switch(type) { |
||
7888 | case GL_UNSIGNED_BYTE: |
||
7889 | if (depth > 1) { |
||
7890 | halveImage3D(cmpts,extractUbyte,shoveUbyte, |
||
7891 | width,height,depth, |
||
7892 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7893 | imageSize,myswapBytes); |
||
7894 | } |
||
7895 | else { |
||
7896 | halveImage_ubyte(cmpts,width,height,usersImage,dstImage, |
||
7897 | elementSize,rowSize,groupSize); |
||
7898 | } |
||
7899 | break; |
||
7900 | case GL_BYTE: |
||
7901 | if (depth > 1) { |
||
7902 | halveImage3D(cmpts,extractSbyte,shoveSbyte, |
||
7903 | width,height,depth, |
||
7904 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7905 | imageSize,myswapBytes); |
||
7906 | } |
||
7907 | else { |
||
7908 | halveImage_byte(cmpts,width,height,usersImage,dstImage, |
||
7909 | elementSize,rowSize,groupSize); |
||
7910 | } |
||
7911 | break; |
||
7912 | case GL_UNSIGNED_SHORT: |
||
7913 | if (depth > 1) { |
||
7914 | halveImage3D(cmpts,extractUshort,shoveUshort, |
||
7915 | width,height,depth, |
||
7916 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7917 | imageSize,myswapBytes); |
||
7918 | } |
||
7919 | else { |
||
7920 | halveImage_ushort(cmpts,width,height,usersImage,dstImage, |
||
7921 | elementSize,rowSize,groupSize,myswapBytes); |
||
7922 | } |
||
7923 | break; |
||
7924 | case GL_SHORT: |
||
7925 | if (depth > 1) { |
||
7926 | halveImage3D(cmpts,extractSshort,shoveSshort, |
||
7927 | width,height,depth, |
||
7928 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7929 | imageSize,myswapBytes); |
||
7930 | } |
||
7931 | else { |
||
7932 | halveImage_short(cmpts,width,height,usersImage,dstImage, |
||
7933 | elementSize,rowSize,groupSize,myswapBytes); |
||
7934 | } |
||
7935 | break; |
||
7936 | case GL_UNSIGNED_INT: |
||
7937 | if (depth > 1) { |
||
7938 | halveImage3D(cmpts,extractUint,shoveUint, |
||
7939 | width,height,depth, |
||
7940 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7941 | imageSize,myswapBytes); |
||
7942 | } |
||
7943 | else { |
||
7944 | halveImage_uint(cmpts,width,height,usersImage,dstImage, |
||
7945 | elementSize,rowSize,groupSize,myswapBytes); |
||
7946 | } |
||
7947 | break; |
||
7948 | case GL_INT: |
||
7949 | if (depth > 1) { |
||
7950 | halveImage3D(cmpts,extractSint,shoveSint, |
||
7951 | width,height,depth, |
||
7952 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7953 | imageSize,myswapBytes); |
||
7954 | } |
||
7955 | else { |
||
7956 | halveImage_int(cmpts,width,height,usersImage,dstImage, |
||
7957 | elementSize,rowSize,groupSize,myswapBytes); |
||
7958 | } |
||
7959 | break; |
||
7960 | case GL_FLOAT: |
||
7961 | if (depth > 1 ) { |
||
7962 | halveImage3D(cmpts,extractFloat,shoveFloat, |
||
7963 | width,height,depth, |
||
7964 | usersImage,dstImage,elementSize,groupSize,rowSize, |
||
7965 | imageSize,myswapBytes); |
||
7966 | } |
||
7967 | else { |
||
7968 | halveImage_float(cmpts,width,height,usersImage,dstImage, |
||
7969 | elementSize,rowSize,groupSize,myswapBytes); |
||
7970 | } |
||
7971 | break; |
||
7972 | case GL_UNSIGNED_BYTE_3_3_2: |
||
7973 | assert(format == GL_RGB); |
||
7974 | halveImagePackedPixel3D(3,extract332,shove332, |
||
7975 | width,height,depth,usersImage,dstImage, |
||
7976 | elementSize,rowSize,imageSize,myswapBytes); |
||
7977 | break; |
||
7978 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
7979 | assert(format == GL_RGB); |
||
7980 | halveImagePackedPixel3D(3,extract233rev,shove233rev, |
||
7981 | width,height,depth,usersImage,dstImage, |
||
7982 | elementSize,rowSize,imageSize,myswapBytes); |
||
7983 | break; |
||
7984 | case GL_UNSIGNED_SHORT_5_6_5: |
||
7985 | halveImagePackedPixel3D(3,extract565,shove565, |
||
7986 | width,height,depth,usersImage,dstImage, |
||
7987 | elementSize,rowSize,imageSize,myswapBytes); |
||
7988 | break; |
||
7989 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
7990 | halveImagePackedPixel3D(3,extract565rev,shove565rev, |
||
7991 | width,height,depth,usersImage,dstImage, |
||
7992 | elementSize,rowSize,imageSize,myswapBytes); |
||
7993 | break; |
||
7994 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
7995 | halveImagePackedPixel3D(4,extract4444,shove4444, |
||
7996 | width,height,depth,usersImage,dstImage, |
||
7997 | elementSize,rowSize,imageSize,myswapBytes); |
||
7998 | break; |
||
7999 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
8000 | halveImagePackedPixel3D(4,extract4444rev,shove4444rev, |
||
8001 | width,height,depth,usersImage,dstImage, |
||
8002 | elementSize,rowSize,imageSize,myswapBytes); |
||
8003 | break; |
||
8004 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
8005 | halveImagePackedPixel3D(4,extract5551,shove5551, |
||
8006 | width,height,depth,usersImage,dstImage, |
||
8007 | elementSize,rowSize,imageSize,myswapBytes); |
||
8008 | break; |
||
8009 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
8010 | halveImagePackedPixel3D(4,extract1555rev,shove1555rev, |
||
8011 | width,height,depth,usersImage,dstImage, |
||
8012 | elementSize,rowSize,imageSize,myswapBytes); |
||
8013 | break; |
||
8014 | case GL_UNSIGNED_INT_8_8_8_8: |
||
8015 | halveImagePackedPixel3D(4,extract8888,shove8888, |
||
8016 | width,height,depth,usersImage,dstImage, |
||
8017 | elementSize,rowSize,imageSize,myswapBytes); |
||
8018 | break; |
||
8019 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
8020 | halveImagePackedPixel3D(4,extract8888rev,shove8888rev, |
||
8021 | width,height,depth,usersImage,dstImage, |
||
8022 | elementSize,rowSize,imageSize,myswapBytes); |
||
8023 | break; |
||
8024 | case GL_UNSIGNED_INT_10_10_10_2: |
||
8025 | halveImagePackedPixel3D(4,extract1010102,shove1010102, |
||
8026 | width,height,depth,usersImage,dstImage, |
||
8027 | elementSize,rowSize,imageSize,myswapBytes); |
||
8028 | break; |
||
8029 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
8030 | halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, |
||
8031 | width,height,depth,usersImage,dstImage, |
||
8032 | elementSize,rowSize,imageSize,myswapBytes); |
||
8033 | break; |
||
8034 | default: |
||
8035 | assert(0); |
||
8036 | break; |
||
8037 | } |
||
8038 | newWidth = width/2; |
||
8039 | newHeight = height/2; |
||
8040 | newDepth = depth/2; |
||
8041 | /* clamp to 1 */ |
||
8042 | if (newWidth < 1) newWidth= 1; |
||
8043 | if (newHeight < 1) newHeight= 1; |
||
8044 | if (newDepth < 1) newDepth= 1; |
||
8045 | |||
8046 | myswapBytes = 0; |
||
8047 | rowSize = newWidth * groupSize; |
||
8048 | imageSize= rowSize * newHeight; /* 3dstuff */ |
||
8049 | memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); |
||
8050 | /* Swap srcImage and dstImage */ |
||
8051 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
8052 | switch(type) { |
||
8053 | case GL_UNSIGNED_BYTE: |
||
8054 | dstImage = (GLubyte *)malloc(memReq); |
||
8055 | break; |
||
8056 | case GL_BYTE: |
||
8057 | dstImage = (GLbyte *)malloc(memReq); |
||
8058 | break; |
||
8059 | case GL_UNSIGNED_SHORT: |
||
8060 | dstImage = (GLushort *)malloc(memReq); |
||
8061 | break; |
||
8062 | case GL_SHORT: |
||
8063 | dstImage = (GLshort *)malloc(memReq); |
||
8064 | break; |
||
8065 | case GL_UNSIGNED_INT: |
||
8066 | dstImage = (GLuint *)malloc(memReq); |
||
8067 | break; |
||
8068 | case GL_INT: |
||
8069 | dstImage = (GLint *)malloc(memReq); |
||
8070 | break; |
||
8071 | case GL_FLOAT: |
||
8072 | dstImage = (GLfloat *)malloc(memReq); |
||
8073 | break; |
||
8074 | case GL_UNSIGNED_BYTE_3_3_2: |
||
8075 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
8076 | dstImage = (GLubyte *)malloc(memReq); |
||
8077 | break; |
||
8078 | case GL_UNSIGNED_SHORT_5_6_5: |
||
8079 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
8080 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
8081 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
8082 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
8083 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
8084 | dstImage = (GLushort *)malloc(memReq); |
||
8085 | break; |
||
8086 | case GL_UNSIGNED_INT_8_8_8_8: |
||
8087 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
8088 | case GL_UNSIGNED_INT_10_10_10_2: |
||
8089 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
8090 | dstImage = (GLuint *)malloc(memReq); |
||
8091 | break; |
||
8092 | default: |
||
8093 | return GLU_INVALID_ENUM; /* assertion */ |
||
8094 | } |
||
8095 | if (dstImage == NULL) { |
||
8096 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
8097 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
8098 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
8099 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
8100 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
8101 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
8102 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
8103 | free(srcImage); |
||
8104 | return GLU_OUT_OF_MEMORY; |
||
8105 | } |
||
8106 | /* level userLevel+1 is in srcImage; level userLevel already saved */ |
||
8107 | level = userLevel+1; |
||
8108 | } else {/* user's image is *not* nice power-of-2 sized square */ |
||
8109 | memReq = imageSize3D(newWidth, newHeight, newDepth, format, type); |
||
8110 | switch(type) { |
||
8111 | case GL_UNSIGNED_BYTE: |
||
8112 | dstImage = (GLubyte *)malloc(memReq); |
||
8113 | break; |
||
8114 | case GL_BYTE: |
||
8115 | dstImage = (GLbyte *)malloc(memReq); |
||
8116 | break; |
||
8117 | case GL_UNSIGNED_SHORT: |
||
8118 | dstImage = (GLushort *)malloc(memReq); |
||
8119 | break; |
||
8120 | case GL_SHORT: |
||
8121 | dstImage = (GLshort *)malloc(memReq); |
||
8122 | break; |
||
8123 | case GL_UNSIGNED_INT: |
||
8124 | dstImage = (GLuint *)malloc(memReq); |
||
8125 | break; |
||
8126 | case GL_INT: |
||
8127 | dstImage = (GLint *)malloc(memReq); |
||
8128 | break; |
||
8129 | case GL_FLOAT: |
||
8130 | dstImage = (GLfloat *)malloc(memReq); |
||
8131 | break; |
||
8132 | case GL_UNSIGNED_BYTE_3_3_2: |
||
8133 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
8134 | dstImage = (GLubyte *)malloc(memReq); |
||
8135 | break; |
||
8136 | case GL_UNSIGNED_SHORT_5_6_5: |
||
8137 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
8138 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
8139 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
8140 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
8141 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
8142 | dstImage = (GLushort *)malloc(memReq); |
||
8143 | break; |
||
8144 | case GL_UNSIGNED_INT_8_8_8_8: |
||
8145 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
8146 | case GL_UNSIGNED_INT_10_10_10_2: |
||
8147 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
8148 | dstImage = (GLuint *)malloc(memReq); |
||
8149 | break; |
||
8150 | default: |
||
8151 | return GLU_INVALID_ENUM; /* assertion */ |
||
8152 | } |
||
8153 | |||
8154 | if (dstImage == NULL) { |
||
8155 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
8156 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
8157 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
8158 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
8159 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
8160 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
8161 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
8162 | return GLU_OUT_OF_MEMORY; |
||
8163 | } |
||
8164 | /*printf("Build3DMipmaps(): ScaleImage3D %d %d %d->%d %d %d\n", |
||
8165 | width,height,depth,newWidth,newHeight,newDepth);*/ |
||
8166 | |||
8167 | gluScaleImage3D(format, width, height, depth, type, usersImage, |
||
8168 | newWidth, newHeight, newDepth, type, dstImage); |
||
8169 | |||
8170 | myswapBytes = 0; |
||
8171 | rowSize = newWidth * groupSize; |
||
8172 | imageSize = rowSize * newHeight; /* 3dstuff */ |
||
8173 | /* Swap dstImage and srcImage */ |
||
8174 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
8175 | |||
8176 | if(levels != 0) { /* use as little memory as possible */ |
||
8177 | { |
||
8178 | int nextWidth= newWidth/2; |
||
8179 | int nextHeight= newHeight/2; |
||
8180 | int nextDepth= newDepth/2; |
||
8181 | if (nextWidth < 1) nextWidth= 1; |
||
8182 | if (nextHeight < 1) nextHeight= 1; |
||
8183 | if (nextDepth < 1) nextDepth= 1; |
||
8184 | |||
8185 | memReq = imageSize3D(nextWidth, nextHeight, nextDepth, format, type); |
||
8186 | } |
||
8187 | switch(type) { |
||
8188 | case GL_UNSIGNED_BYTE: |
||
8189 | dstImage = (GLubyte *)malloc(memReq); |
||
8190 | break; |
||
8191 | case GL_BYTE: |
||
8192 | dstImage = (GLbyte *)malloc(memReq); |
||
8193 | break; |
||
8194 | case GL_UNSIGNED_SHORT: |
||
8195 | dstImage = (GLushort *)malloc(memReq); |
||
8196 | break; |
||
8197 | case GL_SHORT: |
||
8198 | dstImage = (GLshort *)malloc(memReq); |
||
8199 | break; |
||
8200 | case GL_UNSIGNED_INT: |
||
8201 | dstImage = (GLuint *)malloc(memReq); |
||
8202 | break; |
||
8203 | case GL_INT: |
||
8204 | dstImage = (GLint *)malloc(memReq); |
||
8205 | break; |
||
8206 | case GL_FLOAT: |
||
8207 | dstImage = (GLfloat *)malloc(memReq); |
||
8208 | break; |
||
8209 | case GL_UNSIGNED_BYTE_3_3_2: |
||
8210 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
8211 | dstImage = (GLubyte *)malloc(memReq); |
||
8212 | break; |
||
8213 | case GL_UNSIGNED_SHORT_5_6_5: |
||
8214 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
8215 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
8216 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
8217 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
8218 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
8219 | dstImage = (GLushort *)malloc(memReq); |
||
8220 | break; |
||
8221 | case GL_UNSIGNED_INT_8_8_8_8: |
||
8222 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
8223 | case GL_UNSIGNED_INT_10_10_10_2: |
||
8224 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
8225 | dstImage = (GLuint *)malloc(memReq); |
||
8226 | break; |
||
8227 | default: |
||
8228 | return GLU_INVALID_ENUM; /* assertion */ |
||
8229 | } |
||
8230 | if (dstImage == NULL) { |
||
8231 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
8232 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
8233 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
8234 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
8235 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
8236 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
8237 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
8238 | free(srcImage); |
||
8239 | return GLU_OUT_OF_MEMORY; |
||
8240 | } |
||
8241 | } |
||
8242 | /* level userLevel is in srcImage; nothing saved yet */ |
||
8243 | level = userLevel; |
||
8244 | } |
||
8245 | |||
8246 | glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); |
||
8247 | if (baseLevel <= level && level <= maxLevel) { |
||
8248 | gluTexImage3D(target, level, internalFormat, newWidth, newHeight, newDepth, |
||
8249 | 0,format, type, (void *)srcImage); |
||
8250 | } |
||
8251 | level++; /* update current level for the loop */ |
||
8252 | for (; level <= levels; level++) { |
||
8253 | switch(type) { |
||
8254 | case GL_UNSIGNED_BYTE: |
||
8255 | if (newDepth > 1) { |
||
8256 | halveImage3D(cmpts,extractUbyte,shoveUbyte, |
||
8257 | newWidth,newHeight,newDepth, |
||
8258 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8259 | imageSize,myswapBytes); |
||
8260 | } |
||
8261 | else { |
||
8262 | halveImage_ubyte(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8263 | elementSize,rowSize,groupSize); |
||
8264 | } |
||
8265 | break; |
||
8266 | case GL_BYTE: |
||
8267 | if (newDepth > 1) { |
||
8268 | halveImage3D(cmpts,extractSbyte,shoveSbyte, |
||
8269 | newWidth,newHeight,newDepth, |
||
8270 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8271 | imageSize,myswapBytes); |
||
8272 | } |
||
8273 | else { |
||
8274 | halveImage_byte(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8275 | elementSize,rowSize,groupSize); |
||
8276 | } |
||
8277 | break; |
||
8278 | case GL_UNSIGNED_SHORT: |
||
8279 | if (newDepth > 1) { |
||
8280 | halveImage3D(cmpts,extractUshort,shoveUshort, |
||
8281 | newWidth,newHeight,newDepth, |
||
8282 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8283 | imageSize,myswapBytes); |
||
8284 | } |
||
8285 | else { |
||
8286 | halveImage_ushort(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8287 | elementSize,rowSize,groupSize,myswapBytes); |
||
8288 | } |
||
8289 | break; |
||
8290 | case GL_SHORT: |
||
8291 | if (newDepth > 1) { |
||
8292 | halveImage3D(cmpts,extractSshort,shoveSshort, |
||
8293 | newWidth,newHeight,newDepth, |
||
8294 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8295 | imageSize,myswapBytes); |
||
8296 | } |
||
8297 | else { |
||
8298 | halveImage_short(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8299 | elementSize,rowSize,groupSize,myswapBytes); |
||
8300 | } |
||
8301 | break; |
||
8302 | case GL_UNSIGNED_INT: |
||
8303 | if (newDepth > 1) { |
||
8304 | halveImage3D(cmpts,extractUint,shoveUint, |
||
8305 | newWidth,newHeight,newDepth, |
||
8306 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8307 | imageSize,myswapBytes); |
||
8308 | } |
||
8309 | else { |
||
8310 | halveImage_uint(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8311 | elementSize,rowSize,groupSize,myswapBytes); |
||
8312 | } |
||
8313 | break; |
||
8314 | case GL_INT: |
||
8315 | if (newDepth > 1) { |
||
8316 | halveImage3D(cmpts,extractSint,shoveSint, |
||
8317 | newWidth,newHeight,newDepth, |
||
8318 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8319 | imageSize,myswapBytes); |
||
8320 | } |
||
8321 | else { |
||
8322 | halveImage_int(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8323 | elementSize,rowSize,groupSize,myswapBytes); |
||
8324 | } |
||
8325 | break; |
||
8326 | case GL_FLOAT: |
||
8327 | if (newDepth > 1) { |
||
8328 | halveImage3D(cmpts,extractFloat,shoveFloat, |
||
8329 | newWidth,newHeight,newDepth, |
||
8330 | srcImage,dstImage,elementSize,groupSize,rowSize, |
||
8331 | imageSize,myswapBytes); |
||
8332 | } |
||
8333 | else { |
||
8334 | halveImage_float(cmpts,newWidth,newHeight,srcImage,dstImage, |
||
8335 | elementSize,rowSize,groupSize,myswapBytes); |
||
8336 | } |
||
8337 | break; |
||
8338 | case GL_UNSIGNED_BYTE_3_3_2: |
||
8339 | halveImagePackedPixel3D(3,extract332,shove332, |
||
8340 | newWidth,newHeight,newDepth, |
||
8341 | srcImage,dstImage,elementSize,rowSize, |
||
8342 | imageSize,myswapBytes); |
||
8343 | break; |
||
8344 | case GL_UNSIGNED_BYTE_2_3_3_REV: |
||
8345 | halveImagePackedPixel3D(3,extract233rev,shove233rev, |
||
8346 | newWidth,newHeight,newDepth, |
||
8347 | srcImage,dstImage,elementSize,rowSize, |
||
8348 | imageSize,myswapBytes); |
||
8349 | break; |
||
8350 | case GL_UNSIGNED_SHORT_5_6_5: |
||
8351 | halveImagePackedPixel3D(3,extract565,shove565, |
||
8352 | newWidth,newHeight,newDepth, |
||
8353 | srcImage,dstImage,elementSize,rowSize, |
||
8354 | imageSize,myswapBytes); |
||
8355 | break; |
||
8356 | case GL_UNSIGNED_SHORT_5_6_5_REV: |
||
8357 | halveImagePackedPixel3D(3,extract565rev,shove565rev, |
||
8358 | newWidth,newHeight,newDepth, |
||
8359 | srcImage,dstImage,elementSize,rowSize, |
||
8360 | imageSize,myswapBytes); |
||
8361 | break; |
||
8362 | case GL_UNSIGNED_SHORT_4_4_4_4: |
||
8363 | halveImagePackedPixel3D(4,extract4444,shove4444, |
||
8364 | newWidth,newHeight,newDepth, |
||
8365 | srcImage,dstImage,elementSize,rowSize, |
||
8366 | imageSize,myswapBytes); |
||
8367 | break; |
||
8368 | case GL_UNSIGNED_SHORT_4_4_4_4_REV: |
||
8369 | halveImagePackedPixel3D(4,extract4444rev,shove4444rev, |
||
8370 | newWidth,newHeight,newDepth, |
||
8371 | srcImage,dstImage,elementSize,rowSize, |
||
8372 | imageSize,myswapBytes); |
||
8373 | break; |
||
8374 | case GL_UNSIGNED_SHORT_5_5_5_1: |
||
8375 | halveImagePackedPixel3D(4,extract5551,shove5551, |
||
8376 | newWidth,newHeight,newDepth, |
||
8377 | srcImage,dstImage,elementSize,rowSize, |
||
8378 | imageSize,myswapBytes); |
||
8379 | break; |
||
8380 | case GL_UNSIGNED_SHORT_1_5_5_5_REV: |
||
8381 | halveImagePackedPixel3D(4,extract1555rev,shove1555rev, |
||
8382 | newWidth,newHeight,newDepth, |
||
8383 | srcImage,dstImage,elementSize,rowSize, |
||
8384 | imageSize,myswapBytes); |
||
8385 | break; |
||
8386 | case GL_UNSIGNED_INT_8_8_8_8: |
||
8387 | halveImagePackedPixel3D(4,extract8888,shove8888, |
||
8388 | newWidth,newHeight,newDepth, |
||
8389 | srcImage,dstImage,elementSize,rowSize, |
||
8390 | imageSize,myswapBytes); |
||
8391 | break; |
||
8392 | case GL_UNSIGNED_INT_8_8_8_8_REV: |
||
8393 | halveImagePackedPixel3D(4,extract8888rev,shove8888rev, |
||
8394 | newWidth,newHeight,newDepth, |
||
8395 | srcImage,dstImage,elementSize,rowSize, |
||
8396 | imageSize,myswapBytes); |
||
8397 | break; |
||
8398 | case GL_UNSIGNED_INT_10_10_10_2: |
||
8399 | halveImagePackedPixel3D(4,extract1010102,shove1010102, |
||
8400 | newWidth,newHeight,newDepth, |
||
8401 | srcImage,dstImage,elementSize,rowSize, |
||
8402 | imageSize,myswapBytes); |
||
8403 | break; |
||
8404 | case GL_UNSIGNED_INT_2_10_10_10_REV: |
||
8405 | halveImagePackedPixel3D(4,extract2101010rev,shove2101010rev, |
||
8406 | newWidth,newHeight,newDepth, |
||
8407 | srcImage,dstImage,elementSize,rowSize, |
||
8408 | imageSize,myswapBytes); |
||
8409 | break; |
||
8410 | default: |
||
8411 | assert(0); |
||
8412 | break; |
||
8413 | } |
||
8414 | |||
8415 | __GLU_SWAP_IMAGE(srcImage,dstImage); |
||
8416 | |||
8417 | if (newWidth > 1) { newWidth /= 2; rowSize /= 2;} |
||
8418 | if (newHeight > 1) { newHeight /= 2; imageSize = rowSize * newHeight; } |
||
8419 | if (newDepth > 1) newDepth /= 2; |
||
8420 | { |
||
8421 | /* call tex image with srcImage untouched since it's not padded */ |
||
8422 | if (baseLevel <= level && level <= maxLevel) { |
||
8423 | gluTexImage3D(target, level, internalFormat, newWidth, newHeight, |
||
8424 | newDepth,0, format, type, (void *) srcImage); |
||
8425 | } |
||
8426 | } |
||
8427 | } /* for level */ |
||
8428 | glPixelStorei(GL_UNPACK_ALIGNMENT, psm.unpack_alignment); |
||
8429 | glPixelStorei(GL_UNPACK_SKIP_ROWS, psm.unpack_skip_rows); |
||
8430 | glPixelStorei(GL_UNPACK_SKIP_PIXELS, psm.unpack_skip_pixels); |
||
8431 | glPixelStorei(GL_UNPACK_ROW_LENGTH, psm.unpack_row_length); |
||
8432 | glPixelStorei(GL_UNPACK_SWAP_BYTES, psm.unpack_swap_bytes); |
||
8433 | glPixelStorei(GL_UNPACK_SKIP_IMAGES, psm.unpack_skip_images); |
||
8434 | glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, psm.unpack_image_height); |
||
8435 | |||
8436 | free(srcImage); /*if you get to here, a srcImage has always been malloc'ed*/ |
||
8437 | if (dstImage) { /* if it's non-rectangular and only 1 level */ |
||
8438 | free(dstImage); |
||
8439 | } |
||
8440 | return 0; |
||
8441 | } /* gluBuild3DMipmapLevelsCore() */ |
||
8442 | |||
8443 | GLint GLAPIENTRY |
||
8444 | gluBuild3DMipmapLevels(GLenum target, GLint internalFormat, |
||
8445 | GLsizei width, GLsizei height, GLsizei depth, |
||
8446 | GLenum format, GLenum type, |
||
8447 | GLint userLevel, GLint baseLevel, GLint maxLevel, |
||
8448 | const void *data) |
||
8449 | { |
||
8450 | int level, levels; |
||
8451 | |||
8452 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
8453 | if (rc != 0) return rc; |
||
8454 | |||
8455 | if (width < 1 || height < 1 || depth < 1) { |
||
8456 | return GLU_INVALID_VALUE; |
||
8457 | } |
||
8458 | |||
8459 | if(type == GL_BITMAP) { |
||
8460 | return GLU_INVALID_ENUM; |
||
8461 | } |
||
8462 | |||
8463 | levels = computeLog(width); |
||
8464 | level = computeLog(height); |
||
8465 | if (level > levels) levels=level; |
||
8466 | level = computeLog(depth); |
||
8467 | if (level > levels) levels=level; |
||
8468 | |||
8469 | levels+= userLevel; |
||
8470 | if (!isLegalLevels(userLevel,baseLevel,maxLevel,levels)) |
||
8471 | return GLU_INVALID_VALUE; |
||
8472 | |||
8473 | return gluBuild3DMipmapLevelsCore(target, internalFormat, |
||
8474 | width, height, depth, |
||
8475 | width, height, depth, |
||
8476 | format, type, |
||
8477 | userLevel, baseLevel, maxLevel, |
||
8478 | data); |
||
8479 | } /* gluBuild3DMipmapLevels() */ |
||
8480 | |||
8481 | GLint GLAPIENTRY |
||
8482 | gluBuild3DMipmaps(GLenum target, GLint internalFormat, |
||
8483 | GLsizei width, GLsizei height, GLsizei depth, |
||
8484 | GLenum format, GLenum type, const void *data) |
||
8485 | { |
||
8486 | GLint widthPowerOf2, heightPowerOf2, depthPowerOf2; |
||
8487 | int level, levels; |
||
8488 | |||
8489 | int rc= checkMipmapArgs(internalFormat,format,type); |
||
8490 | if (rc != 0) return rc; |
||
8491 | |||
8492 | if (width < 1 || height < 1 || depth < 1) { |
||
8493 | return GLU_INVALID_VALUE; |
||
8494 | } |
||
8495 | |||
8496 | if(type == GL_BITMAP) { |
||
8497 | return GLU_INVALID_ENUM; |
||
8498 | } |
||
8499 | |||
8500 | closestFit3D(target,width,height,depth,internalFormat,format,type, |
||
8501 | &widthPowerOf2,&heightPowerOf2,&depthPowerOf2); |
||
8502 | |||
8503 | levels = computeLog(widthPowerOf2); |
||
8504 | level = computeLog(heightPowerOf2); |
||
8505 | if (level > levels) levels=level; |
||
8506 | level = computeLog(depthPowerOf2); |
||
8507 | if (level > levels) levels=level; |
||
8508 | |||
8509 | return gluBuild3DMipmapLevelsCore(target, internalFormat, |
||
8510 | width, height, depth, |
||
8511 | widthPowerOf2, heightPowerOf2, |
||
8512 | depthPowerOf2, |
||
8513 | format, type, 0, 0, levels, |
||
8514 | data); |
||
8515 | } /* gluBuild3DMipmaps() */ |
||
8516 | |||
8517 | static GLdouble extractUbyte(int isSwap, const void *ubyte) |
||
8518 | { |
||
8519 | isSwap= isSwap; /* turn off warnings */ |
||
8520 | |||
8521 | assert(*((const GLubyte *)ubyte) <= 255); |
||
8522 | |||
8523 | return (GLdouble)(*((const GLubyte *)ubyte)); |
||
8524 | } /* extractUbyte() */ |
||
8525 | |||
8526 | static void shoveUbyte(GLdouble value, int index, void *data) |
||
8527 | { |
||
8528 | assert(0.0 <= value && value < 256.0); |
||
8529 | |||
8530 | ((GLubyte *)data)[index]= (GLubyte)value; |
||
8531 | } /* shoveUbyte() */ |
||
8532 | |||
8533 | static GLdouble extractSbyte(int isSwap, const void *sbyte) |
||
8534 | { |
||
8535 | isSwap= isSwap; /* turn off warnings */ |
||
8536 | |||
8537 | assert(*((const GLbyte *)sbyte) <= 127); |
||
8538 | |||
8539 | return (GLdouble)(*((const GLbyte *)sbyte)); |
||
8540 | } /* extractSbyte() */ |
||
8541 | |||
8542 | static void shoveSbyte(GLdouble value, int index, void *data) |
||
8543 | { |
||
8544 | ((GLbyte *)data)[index]= (GLbyte)value; |
||
8545 | } /* shoveSbyte() */ |
||
8546 | |||
8547 | static GLdouble extractUshort(int isSwap, const void *uitem) |
||
8548 | { |
||
8549 | GLushort ushort; |
||
8550 | |||
8551 | if (isSwap) { |
||
8552 | ushort= __GLU_SWAP_2_BYTES(uitem); |
||
8553 | } |
||
8554 | else { |
||
8555 | ushort= *(const GLushort *)uitem; |
||
8556 | } |
||
8557 | |||
8558 | assert(ushort <= 65535); |
||
8559 | |||
8560 | return (GLdouble)ushort; |
||
8561 | } /* extractUshort() */ |
||
8562 | |||
8563 | static void shoveUshort(GLdouble value, int index, void *data) |
||
8564 | { |
||
8565 | assert(0.0 <= value && value < 65536.0); |
||
8566 | |||
8567 | ((GLushort *)data)[index]= (GLushort)value; |
||
8568 | } /* shoveUshort() */ |
||
8569 | |||
8570 | static GLdouble extractSshort(int isSwap, const void *sitem) |
||
8571 | { |
||
8572 | GLshort sshort; |
||
8573 | |||
8574 | if (isSwap) { |
||
8575 | sshort= __GLU_SWAP_2_BYTES(sitem); |
||
8576 | } |
||
8577 | else { |
||
8578 | sshort= *(const GLshort *)sitem; |
||
8579 | } |
||
8580 | |||
8581 | assert(sshort <= 32767); |
||
8582 | |||
8583 | return (GLdouble)sshort; |
||
8584 | } /* extractSshort() */ |
||
8585 | |||
8586 | static void shoveSshort(GLdouble value, int index, void *data) |
||
8587 | { |
||
8588 | assert(0.0 <= value && value < 32768.0); |
||
8589 | |||
8590 | ((GLshort *)data)[index]= (GLshort)value; |
||
8591 | } /* shoveSshort() */ |
||
8592 | |||
8593 | static GLdouble extractUint(int isSwap, const void *uitem) |
||
8594 | { |
||
8595 | GLuint uint; |
||
8596 | |||
8597 | if (isSwap) { |
||
8598 | uint= __GLU_SWAP_4_BYTES(uitem); |
||
8599 | } |
||
8600 | else { |
||
8601 | uint= *(const GLuint *)uitem; |
||
8602 | } |
||
8603 | |||
8604 | assert(uint <= 0xffffffff); |
||
8605 | |||
8606 | return (GLdouble)uint; |
||
8607 | } /* extractUint() */ |
||
8608 | |||
8609 | static void shoveUint(GLdouble value, int index, void *data) |
||
8610 | { |
||
8611 | assert(0.0 <= value && value <= (GLdouble) UINT_MAX); |
||
8612 | |||
8613 | ((GLuint *)data)[index]= (GLuint)value; |
||
8614 | } /* shoveUint() */ |
||
8615 | |||
8616 | static GLdouble extractSint(int isSwap, const void *sitem) |
||
8617 | { |
||
8618 | GLint sint; |
||
8619 | |||
8620 | if (isSwap) { |
||
8621 | sint= __GLU_SWAP_4_BYTES(sitem); |
||
8622 | } |
||
8623 | else { |
||
8624 | sint= *(const GLint *)sitem; |
||
8625 | } |
||
8626 | |||
8627 | assert(sint <= 0x7fffffff); |
||
8628 | |||
8629 | return (GLdouble)sint; |
||
8630 | } /* extractSint() */ |
||
8631 | |||
8632 | static void shoveSint(GLdouble value, int index, void *data) |
||
8633 | { |
||
8634 | assert(0.0 <= value && value <= (GLdouble) INT_MAX); |
||
8635 | |||
8636 | ((GLint *)data)[index]= (GLint)value; |
||
8637 | } /* shoveSint() */ |
||
8638 | |||
8639 | static GLdouble extractFloat(int isSwap, const void *item) |
||
8640 | { |
||
8641 | GLfloat ffloat; |
||
8642 | |||
8643 | if (isSwap) { |
||
8644 | ffloat= __GLU_SWAP_4_BYTES(item); |
||
8645 | } |
||
8646 | else { |
||
8647 | ffloat= *(const GLfloat *)item; |
||
8648 | } |
||
8649 | |||
8650 | assert(ffloat <= 1.0); |
||
8651 | |||
8652 | return (GLdouble)ffloat; |
||
8653 | } /* extractFloat() */ |
||
8654 | |||
8655 | static void shoveFloat(GLdouble value, int index, void *data) |
||
8656 | { |
||
8657 | assert(0.0 <= value && value <= 1.0); |
||
8658 | |||
8659 | ((GLfloat *)data)[index]= value; |
||
8660 | } /* shoveFloat() */ |
||
8661 | |||
8662 | static void halveImageSlice(int components, |
||
8663 | GLdouble (*extract)(int, const void *), |
||
8664 | void (*shove)(GLdouble, int, void *), |
||
8665 | GLint width, GLint height, GLint depth, |
||
8666 | const void *dataIn, void *dataOut, |
||
8667 | GLint elementSizeInBytes, |
||
8668 | GLint groupSizeInBytes, |
||
8669 | GLint rowSizeInBytes, |
||
8670 | GLint imageSizeInBytes, |
||
8671 | GLint isSwap) |
||
8672 | { |
||
8673 | int ii, jj; |
||
8674 | int halfWidth= width / 2; |
||
8675 | int halfHeight= height / 2; |
||
8676 | int halfDepth= depth / 2; |
||
8677 | const char *src= (const char *)dataIn; |
||
8678 | int rowPadBytes= rowSizeInBytes - (width * groupSizeInBytes); |
||
8679 | int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); |
||
8680 | int outIndex= 0; |
||
8681 | |||
8682 | assert((width == 1 || height == 1) && depth >= 2); |
||
8683 | |||
8684 | if (width == height) { /* a 1-pixel column viewed from top */ |
||
8685 | /* printf("1-column\n");*/ |
||
8686 | assert(width == 1 && height == 1); |
||
8687 | assert(depth >= 2); |
||
8688 | |||
8689 | for (ii= 0; ii< halfDepth; ii++) { |
||
8690 | int cc; |
||
8691 | |||
8692 | for (cc = 0; cc < components; cc++) { |
||
8693 | double totals[4]; |
||
8694 | double extractTotals[BOX2][4]; |
||
8695 | int kk; |
||
8696 | |||
8697 | extractTotals[0][cc]= (*extract)(isSwap,src); |
||
8698 | extractTotals[1][cc]= (*extract)(isSwap,(src+imageSizeInBytes)); |
||
8699 | |||
8700 | /* average 2 pixels since only a column */ |
||
8701 | totals[cc]= 0.0; |
||
8702 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]; |
||
8703 | * totals[RED]/= 2.0; |
||
8704 | */ |
||
8705 | for (kk = 0; kk < BOX2; kk++) { |
||
8706 | totals[cc]+= extractTotals[kk][cc]; |
||
8707 | } |
||
8708 | totals[cc]/= (double)BOX2; |
||
8709 | |||
8710 | (*shove)(totals[cc],outIndex,dataOut); |
||
8711 | outIndex++; |
||
8712 | src+= elementSizeInBytes; |
||
8713 | } /* for cc */ |
||
8714 | |||
8715 | /* skip over to next group of 2 */ |
||
8716 | src+= rowSizeInBytes; |
||
8717 | } /* for ii */ |
||
8718 | |||
8719 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
||
8720 | assert(outIndex == halfDepth * components); |
||
8721 | } |
||
8722 | else if (height == 1) { /* horizontal slice viewed from top */ |
||
8723 | /* printf("horizontal slice\n"); */ |
||
8724 | assert(width != 1); |
||
8725 | |||
8726 | for (ii= 0; ii< halfDepth; ii++) { |
||
8727 | for (jj= 0; jj< halfWidth; jj++) { |
||
8728 | int cc; |
||
8729 | |||
8730 | for (cc = 0; cc < components; cc++) { |
||
8731 | int kk; |
||
8732 | double totals[4]; |
||
8733 | double extractTotals[BOX4][4]; |
||
8734 | |||
8735 | extractTotals[0][cc]=(*extract)(isSwap,src); |
||
8736 | extractTotals[1][cc]=(*extract)(isSwap, |
||
8737 | (src+groupSizeInBytes)); |
||
8738 | extractTotals[2][cc]=(*extract)(isSwap, |
||
8739 | (src+imageSizeInBytes)); |
||
8740 | extractTotals[3][cc]=(*extract)(isSwap, |
||
8741 | (src+imageSizeInBytes+groupSizeInBytes)); |
||
8742 | |||
8743 | /* grab 4 pixels to average */ |
||
8744 | totals[cc]= 0.0; |
||
8745 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
8746 | * extractTotals[2][RED]+extractTotals[3][RED]; |
||
8747 | * totals[RED]/= 4.0; |
||
8748 | */ |
||
8749 | for (kk = 0; kk < BOX4; kk++) { |
||
8750 | totals[cc]+= extractTotals[kk][cc]; |
||
8751 | } |
||
8752 | totals[cc]/= (double)BOX4; |
||
8753 | |||
8754 | (*shove)(totals[cc],outIndex,dataOut); |
||
8755 | outIndex++; |
||
8756 | |||
8757 | src+= elementSizeInBytes; |
||
8758 | } /* for cc */ |
||
8759 | |||
8760 | /* skip over to next horizontal square of 4 */ |
||
8761 | src+= groupSizeInBytes; |
||
8762 | } /* for jj */ |
||
8763 | src+= rowPadBytes; |
||
8764 | |||
8765 | src+= rowSizeInBytes; |
||
8766 | } /* for ii */ |
||
8767 | |||
8768 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
||
8769 | assert(outIndex == halfWidth * halfDepth * components); |
||
8770 | } |
||
8771 | else if (width == 1) { /* vertical slice viewed from top */ |
||
8772 | /* printf("vertical slice\n"); */ |
||
8773 | assert(height != 1); |
||
8774 | |||
8775 | for (ii= 0; ii< halfDepth; ii++) { |
||
8776 | for (jj= 0; jj< halfHeight; jj++) { |
||
8777 | int cc; |
||
8778 | |||
8779 | for (cc = 0; cc < components; cc++) { |
||
8780 | int kk; |
||
8781 | double totals[4]; |
||
8782 | double extractTotals[BOX4][4]; |
||
8783 | |||
8784 | extractTotals[0][cc]=(*extract)(isSwap,src); |
||
8785 | extractTotals[1][cc]=(*extract)(isSwap, |
||
8786 | (src+rowSizeInBytes)); |
||
8787 | extractTotals[2][cc]=(*extract)(isSwap, |
||
8788 | (src+imageSizeInBytes)); |
||
8789 | extractTotals[3][cc]=(*extract)(isSwap, |
||
8790 | (src+imageSizeInBytes+rowSizeInBytes)); |
||
8791 | |||
8792 | /* grab 4 pixels to average */ |
||
8793 | totals[cc]= 0.0; |
||
8794 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
8795 | * extractTotals[2][RED]+extractTotals[3][RED]; |
||
8796 | * totals[RED]/= 4.0; |
||
8797 | */ |
||
8798 | for (kk = 0; kk < BOX4; kk++) { |
||
8799 | totals[cc]+= extractTotals[kk][cc]; |
||
8800 | } |
||
8801 | totals[cc]/= (double)BOX4; |
||
8802 | |||
8803 | (*shove)(totals[cc],outIndex,dataOut); |
||
8804 | outIndex++; |
||
8805 | |||
8806 | src+= elementSizeInBytes; |
||
8807 | } /* for cc */ |
||
8808 | src+= rowPadBytes; |
||
8809 | |||
8810 | /* skip over to next vertical square of 4 */ |
||
8811 | src+= rowSizeInBytes; |
||
8812 | } /* for jj */ |
||
8813 | src+= imagePadBytes; |
||
8814 | |||
8815 | src+= imageSizeInBytes; |
||
8816 | } /* for ii */ |
||
8817 | |||
8818 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
||
8819 | assert(outIndex == halfHeight * halfDepth * components); |
||
8820 | } |
||
8821 | |||
8822 | } /* halveImageSlice() */ |
||
8823 | |||
8824 | static void halveImage3D(int components, |
||
8825 | GLdouble (*extract)(int, const void *), |
||
8826 | void (*shove)(GLdouble, int, void *), |
||
8827 | GLint width, GLint height, GLint depth, |
||
8828 | const void *dataIn, void *dataOut, |
||
8829 | GLint elementSizeInBytes, |
||
8830 | GLint groupSizeInBytes, |
||
8831 | GLint rowSizeInBytes, |
||
8832 | GLint imageSizeInBytes, |
||
8833 | GLint isSwap) |
||
8834 | { |
||
8835 | assert(depth > 1); |
||
8836 | |||
8837 | /* a horizontal/vertical/one-column slice viewed from top */ |
||
8838 | if (width == 1 || height == 1) { |
||
8839 | assert(1 <= depth); |
||
8840 | |||
8841 | halveImageSlice(components,extract,shove, width, height, depth, |
||
8842 | dataIn, dataOut, elementSizeInBytes, groupSizeInBytes, |
||
8843 | rowSizeInBytes, imageSizeInBytes, isSwap); |
||
8844 | return; |
||
8845 | } |
||
8846 | { |
||
8847 | int ii, jj, dd; |
||
8848 | |||
8849 | int halfWidth= width / 2; |
||
8850 | int halfHeight= height / 2; |
||
8851 | int halfDepth= depth / 2; |
||
8852 | const char *src= (const char *) dataIn; |
||
8853 | int rowPadBytes= rowSizeInBytes - (width*groupSizeInBytes); |
||
8854 | int imagePadBytes= imageSizeInBytes - (width*height*groupSizeInBytes); |
||
8855 | int outIndex= 0; |
||
8856 | |||
8857 | for (dd= 0; dd < halfDepth; dd++) { |
||
8858 | for (ii= 0; ii< halfHeight; ii++) { |
||
8859 | for (jj= 0; jj< halfWidth; jj++) { |
||
8860 | int cc; |
||
8861 | |||
8862 | for (cc= 0; cc < components; cc++) { |
||
8863 | int kk; |
||
8864 | #define BOX8 8 |
||
8865 | double totals[4]; /* 4 is maximum components */ |
||
8866 | double extractTotals[BOX8][4]; /* 4 is maximum components */ |
||
8867 | |||
8868 | extractTotals[0][cc]= (*extract)(isSwap,src); |
||
8869 | extractTotals[1][cc]= (*extract)(isSwap, |
||
8870 | (src+groupSizeInBytes)); |
||
8871 | extractTotals[2][cc]= (*extract)(isSwap, |
||
8872 | (src+rowSizeInBytes)); |
||
8873 | extractTotals[3][cc]= (*extract)(isSwap, |
||
8874 | (src+rowSizeInBytes+groupSizeInBytes)); |
||
8875 | |||
8876 | extractTotals[4][cc]= (*extract)(isSwap, |
||
8877 | (src+imageSizeInBytes)); |
||
8878 | |||
8879 | extractTotals[5][cc]= (*extract)(isSwap, |
||
8880 | (src+groupSizeInBytes+imageSizeInBytes)); |
||
8881 | extractTotals[6][cc]= (*extract)(isSwap, |
||
8882 | (src+rowSizeInBytes+imageSizeInBytes)); |
||
8883 | extractTotals[7][cc]= (*extract)(isSwap, |
||
8884 | (src+rowSizeInBytes+groupSizeInBytes+imageSizeInBytes)); |
||
8885 | |||
8886 | totals[cc]= 0.0; |
||
8887 | |||
8888 | /* totals[RED]= extractTotals[0][RED]+extractTotals[1][RED]+ |
||
8889 | * extractTotals[2][RED]+extractTotals[3][RED]+ |
||
8890 | * extractTotals[4][RED]+extractTotals[5][RED]+ |
||
8891 | * extractTotals[6][RED]+extractTotals[7][RED]; |
||
8892 | * totals[RED]/= 8.0; |
||
8893 | */ |
||
8894 | for (kk = 0; kk < BOX8; kk++) { |
||
8895 | totals[cc]+= extractTotals[kk][cc]; |
||
8896 | } |
||
8897 | totals[cc]/= (double)BOX8; |
||
8898 | |||
8899 | (*shove)(totals[cc],outIndex,dataOut); |
||
8900 | |||
8901 | outIndex++; |
||
8902 | |||
8903 | src+= elementSizeInBytes; /* go to next component */ |
||
8904 | } /* for cc */ |
||
8905 | |||
8906 | /* skip over to next square of 4 */ |
||
8907 | src+= groupSizeInBytes; |
||
8908 | } /* for jj */ |
||
8909 | /* skip past pad bytes, if any, to get to next row */ |
||
8910 | src+= rowPadBytes; |
||
8911 | |||
8912 | /* src is at beginning of a row here, but it's the second row of |
||
8913 | * the square block of 4 pixels that we just worked on so we |
||
8914 | * need to go one more row. |
||
8915 | * i.e., |
||
8916 | * OO... |
||
8917 | * here -->OO... |
||
8918 | * but want -->OO... |
||
8919 | * OO... |
||
8920 | * ... |
||
8921 | */ |
||
8922 | src+= rowSizeInBytes; |
||
8923 | } /* for ii */ |
||
8924 | |||
8925 | /* skip past pad bytes, if any, to get to next image */ |
||
8926 | src+= imagePadBytes; |
||
8927 | |||
8928 | src+= imageSizeInBytes; |
||
8929 | } /* for dd */ |
||
8930 | |||
8931 | /* both pointers must reach one byte after the end */ |
||
8932 | assert(src == &((const char *)dataIn)[rowSizeInBytes*height*depth]); |
||
8933 | assert(outIndex == halfWidth * halfHeight * halfDepth * components); |
||
8934 | } |
||
8935 | } /* halveImage3D() */ |
||
8936 | |||
8937 | |||
8938 | |||
8939 | /*** mipmap.c ***/>>>>>=>>>>>>>>>>>>=>=>=>=>=>=>=>=>=>>=>=>>=>=>=>>=>=>>>>>>>=>=>=>=>=>>>>>>>>>>=>=>>>>>>=>=>=>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>=>> |
||
8940 |