pass dst and src to CONVERT_TEXEL() macros to fix non-ANSI problems
[mesa.git] / src / mesa / main / texutil.c
1 /* $Id: texutil.c,v 1.20 2001/03/27 20:32:24 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 */
29
30 #ifdef PC_HEADER
31 #include "all.h"
32 #else
33 #include "glheader.h"
34 #include "context.h"
35 #include "enums.h"
36 #include "image.h"
37 #include "macros.h"
38 #include "mem.h"
39 #include "mtypes.h"
40 #include "texformat.h"
41 #include "texutil.h"
42 #endif
43
44 #define DBG 0
45
46
47 struct gl_texture_convert {
48 GLint xoffset, yoffset, zoffset; /* Subimage offset */
49 GLint width, height, depth; /* Subimage region */
50
51 GLint dstImageWidth, dstImageHeight; /* Dest image size */
52 /* Needed for subimage replacement */
53 GLenum format, type; /* Source (user) format and type */
54
55 const struct gl_pixelstore_attrib *packing;
56
57 const GLvoid *srcImage;
58 GLvoid *dstImage;
59
60 GLint index;
61 };
62
63 typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
64
65 #define CONVERT_STRIDE_BIT 0x1
66 #define CONVERT_PACKING_BIT 0x2
67
68
69
70 /* ================================================================
71 * RGBA8888 textures:
72 */
73
74 #define DST_TYPE GLuint
75 #define DST_TEXELS_PER_DWORD 1
76
77 #define CONVERT_TEXEL( dst, src ) \
78 dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
79
80 #define CONVERT_DIRECT
81
82 #define SRC_TEXEL_BYTES 4
83
84 #define TAG(x) x##_rgba8888_direct
85 #define PRESERVE_DST_TYPE
86 #include "texutil_tmp.h"
87
88
89 #define CONVERT_TEXEL( dst, src ) \
90 dst = PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
91
92 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
93
94 #define SRC_TEXEL_BYTES 4
95
96 #define TAG(x) x##_abgr8888_to_rgba8888
97 #define PRESERVE_DST_TYPE
98 #include "texutil_tmp.h"
99
100
101 #define CONVERT_TEXEL( dst, src ) \
102 dst = PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
103
104 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
105
106 #define SRC_TEXEL_BYTES 3
107
108 #define TAG(x) x##_bgr888_to_rgba8888
109 #include "texutil_tmp.h"
110
111
112 #define CONVERT_RGBA8888( name ) \
113 static GLboolean \
114 convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
115 { \
116 convert_func *tab; \
117 GLint index = convert->index; \
118 \
119 if ( convert->format == GL_ABGR_EXT && \
120 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
121 { \
122 tab = name##_tab_rgba8888_direct; \
123 } \
124 else if ( convert->format == GL_RGBA && \
125 ( convert->type == GL_UNSIGNED_BYTE || \
126 convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
127 { \
128 tab = name##_tab_abgr8888_to_rgba8888; \
129 } \
130 else if ( convert->format == GL_RGB && \
131 convert->type == GL_UNSIGNED_BYTE ) \
132 { \
133 tab = name##_tab_bgr888_to_rgba8888; \
134 } \
135 else \
136 { \
137 /* Can't handle this source format/type combination */ \
138 return GL_FALSE; \
139 } \
140 \
141 return tab[index]( convert ); \
142 }
143
144 CONVERT_RGBA8888( texsubimage2d )
145 CONVERT_RGBA8888( texsubimage3d )
146
147
148
149 /* ================================================================
150 * ARGB8888 textures:
151 */
152
153 #define DST_TYPE GLuint
154 #define DST_TEXELS_PER_DWORD 1
155
156 #define CONVERT_TEXEL( dst, src ) \
157 dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
158
159 #define CONVERT_DIRECT
160
161 #define SRC_TEXEL_BYTES 4
162
163 #define TAG(x) x##_argb8888_direct
164 #define PRESERVE_DST_TYPE
165 #include "texutil_tmp.h"
166
167
168 #define CONVERT_TEXEL( dst, src ) \
169 dst = PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
170
171 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
172
173 #define SRC_TEXEL_BYTES 4
174
175 #define TAG(x) x##_abgr8888_to_argb8888
176 #define PRESERVE_DST_TYPE
177 #include "texutil_tmp.h"
178
179
180 #define CONVERT_TEXEL( dst, src ) \
181 dst = PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
182
183 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
184
185 #define SRC_TEXEL_BYTES 3
186
187 #define TAG(x) x##_bgr888_to_argb8888
188 #include "texutil_tmp.h"
189
190
191 #define CONVERT_ARGB8888( name ) \
192 static GLboolean \
193 convert_##name##_argb8888( struct gl_texture_convert *convert ) \
194 { \
195 convert_func *tab; \
196 GLint index = convert->index; \
197 \
198 if ( convert->format == GL_BGRA && \
199 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
200 { \
201 tab = name##_tab_argb8888_direct; \
202 } \
203 else if ( convert->format == GL_RGBA && \
204 convert->type == GL_UNSIGNED_BYTE ) \
205 { \
206 tab = name##_tab_abgr8888_to_argb8888; \
207 } \
208 else if ( convert->format == GL_RGB && \
209 convert->type == GL_UNSIGNED_BYTE ) \
210 { \
211 tab = name##_tab_bgr888_to_argb8888; \
212 } \
213 else \
214 { \
215 /* Can't handle this source format/type combination */ \
216 return GL_FALSE; \
217 } \
218 \
219 return tab[index]( convert ); \
220 }
221
222 CONVERT_ARGB8888( texsubimage2d )
223 CONVERT_ARGB8888( texsubimage3d )
224
225
226
227 /* ================================================================
228 * RGB888 textures:
229 */
230
231 static GLboolean
232 convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
233 {
234 /* This is a placeholder for now...
235 */
236 return GL_FALSE;
237 }
238
239 static GLboolean
240 convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
241 {
242 /* This is a placeholder for now...
243 */
244 return GL_FALSE;
245 }
246
247
248
249 /* ================================================================
250 * RGB565 textures:
251 */
252
253 #define DST_TYPE GLushort
254 #define DST_TEXELS_PER_DWORD 2
255
256 #define CONVERT_TEXEL( dst, src ) \
257 dst = PACK_COLOR_565( src[0], src[1], src[2] )
258
259 #define CONVERT_DIRECT
260
261 #define SRC_TEXEL_BYTES 2
262
263 #define TAG(x) x##_rgb565_direct
264 #define PRESERVE_DST_TYPE
265 #include "texutil_tmp.h"
266
267
268 #define CONVERT_TEXEL( dst, src ) \
269 dst = PACK_COLOR_565( src[0], src[1], src[2] )
270
271 #define CONVERT_TEXEL_DWORD( dst, src ) \
272 dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
273 (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
274
275 #define SRC_TEXEL_BYTES 3
276
277 #define TAG(x) x##_bgr888_to_rgb565
278 #define PRESERVE_DST_TYPE
279 #include "texutil_tmp.h"
280
281
282 #define CONVERT_TEXEL( dst, src ) \
283 dst = PACK_COLOR_565( src[0], src[1], src[2] )
284
285 #define CONVERT_TEXEL_DWORD( dst, src ) \
286 dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
287 (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
288
289 #define SRC_TEXEL_BYTES 4
290
291 #define TAG(x) x##_abgr8888_to_rgb565
292 #include "texutil_tmp.h"
293
294
295 #define CONVERT_RGB565( name ) \
296 static GLboolean \
297 convert_##name##_rgb565( struct gl_texture_convert *convert ) \
298 { \
299 convert_func *tab; \
300 GLint index = convert->index; \
301 \
302 if ( convert->format == GL_RGB && \
303 convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
304 { \
305 tab = name##_tab_rgb565_direct; \
306 } \
307 else if ( convert->format == GL_RGB && \
308 convert->type == GL_UNSIGNED_BYTE ) \
309 { \
310 tab = name##_tab_bgr888_to_rgb565; \
311 } \
312 else if ( convert->format == GL_RGBA && \
313 convert->type == GL_UNSIGNED_BYTE ) \
314 { \
315 tab = name##_tab_abgr8888_to_rgb565; \
316 } \
317 else \
318 { \
319 /* Can't handle this source format/type combination */ \
320 return GL_FALSE; \
321 } \
322 \
323 return tab[index]( convert ); \
324 }
325
326 CONVERT_RGB565( texsubimage2d )
327 CONVERT_RGB565( texsubimage3d )
328
329
330
331 /* ================================================================
332 * ARGB4444 textures:
333 */
334
335 #define DST_TYPE GLushort
336 #define DST_TEXELS_PER_DWORD 2
337
338 #define CONVERT_TEXEL( dst, src ) \
339 dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
340
341 #define CONVERT_DIRECT
342
343 #define SRC_TEXEL_BYTES 2
344
345 #define TAG(x) x##_argb4444_direct
346 #define PRESERVE_DST_TYPE
347 #include "texutil_tmp.h"
348
349
350 #define CONVERT_TEXEL( dst, src ) \
351 dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
352
353 #define CONVERT_TEXEL_DWORD( dst, src ) \
354 dst = ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) |\
355 (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
356
357 #define SRC_TEXEL_BYTES 4
358
359 #define TAG(x) x##_rgba8888_to_argb4444
360 #include "texutil_tmp.h"
361
362
363 #define CONVERT_ARGB4444( name ) \
364 static GLboolean \
365 convert_##name##_argb4444( struct gl_texture_convert *convert ) \
366 { \
367 convert_func *tab; \
368 GLint index = convert->index; \
369 \
370 if ( convert->format == GL_BGRA && \
371 convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
372 { \
373 tab = name##_tab_argb4444_direct; \
374 } \
375 else if ( convert->format == GL_RGBA && \
376 convert->type == GL_UNSIGNED_BYTE ) \
377 { \
378 tab = name##_tab_rgba8888_to_argb4444; \
379 } \
380 else \
381 { \
382 /* Can't handle this source format/type combination */ \
383 return GL_FALSE; \
384 } \
385 \
386 return tab[index]( convert ); \
387 }
388
389 CONVERT_ARGB4444( texsubimage2d )
390 CONVERT_ARGB4444( texsubimage3d )
391
392
393
394 /* ================================================================
395 * ARGB1555 textures:
396 */
397
398 #define DST_TYPE GLushort
399 #define DST_TEXELS_PER_DWORD 2
400
401 #define CONVERT_TEXEL( dst, src ) \
402 dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
403
404 #define CONVERT_DIRECT
405
406 #define SRC_TEXEL_BYTES 2
407
408 #define TAG(x) x##_argb1555_direct
409 #define PRESERVE_DST_TYPE
410 #include "texutil_tmp.h"
411
412
413 #define CONVERT_TEXEL( dst, src ) \
414 { const GLushort s = *(GLushort *)src; \
415 dst = (s >> 1) | ((s & 1) << 15); }
416
417 #define CONVERT_TEXEL_DWORD( dst, src ) \
418 { const GLuint s = *(GLuint *)src; \
419 dst = (((s & 0xfffefffe) >> 1) | \
420 ((s & 0x00010001) << 15)); }
421
422 #define SRC_TEXEL_BYTES 2
423
424 #define TAG(x) x##_rgba5551_to_argb1555
425 #define PRESERVE_DST_TYPE
426 #include "texutil_tmp.h"
427
428
429 #define CONVERT_TEXEL( dst, src ) \
430 dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
431
432 #define CONVERT_TEXEL_DWORD( dst, src ) \
433 dst = ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) |\
434 (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
435
436 #define SRC_TEXEL_BYTES 4
437
438 #define TAG(x) x##_rgba8888_to_argb1555
439 #include "texutil_tmp.h"
440
441
442 #define CONVERT_ARGB1555( name ) \
443 static GLboolean \
444 convert_##name##_argb1555( struct gl_texture_convert *convert ) \
445 { \
446 convert_func *tab; \
447 GLint index = convert->index; \
448 \
449 if ( convert->format == GL_BGRA && \
450 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
451 { \
452 tab = name##_tab_argb1555_direct; \
453 } \
454 else if ( convert->format == GL_RGBA && \
455 convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \
456 { \
457 tab = name##_tab_rgba5551_to_argb1555; \
458 } \
459 else if ( convert->format == GL_RGBA && \
460 convert->type == GL_UNSIGNED_BYTE ) \
461 { \
462 tab = name##_tab_rgba8888_to_argb1555; \
463 } \
464 else \
465 { \
466 /* Can't handle this source format/type combination */ \
467 return GL_FALSE; \
468 } \
469 \
470 return tab[index]( convert ); \
471 }
472
473 CONVERT_ARGB1555( texsubimage2d )
474 CONVERT_ARGB1555( texsubimage3d )
475
476
477
478 /* ================================================================
479 * AL88 textures:
480 */
481
482 #define DST_TYPE GLushort
483 #define DST_TEXELS_PER_DWORD 2
484
485 #define CONVERT_TEXEL( dst, src ) \
486 dst = PACK_COLOR_88( src[0], src[1] )
487
488 #define CONVERT_DIRECT
489
490 #define SRC_TEXEL_BYTES 2
491
492 #define TAG(x) x##_al88_direct
493 #define PRESERVE_DST_TYPE
494 #include "texutil_tmp.h"
495
496
497 #define CONVERT_TEXEL( dst, src ) \
498 dst = PACK_COLOR_88( src[0], 0x00 )
499
500 #define CONVERT_TEXEL_DWORD( dst, src ) \
501 dst = ((PACK_COLOR_88( src[0], 0x00 )) | \
502 (PACK_COLOR_88( src[1], 0x00 ) << 16))
503
504 #define SRC_TEXEL_BYTES 1
505
506 #define TAG(x) x##_a8_to_al88
507 #define PRESERVE_DST_TYPE
508 #include "texutil_tmp.h"
509
510
511 #define CONVERT_TEXEL( dst, src ) \
512 dst = PACK_COLOR_88( 0xff, src[0] )
513
514 #define CONVERT_TEXEL_DWORD( dst, src ) \
515 dst = ((PACK_COLOR_88( 0xff, src[0] )) | \
516 (PACK_COLOR_88( 0xff, src[1] ) << 16))
517
518 #define SRC_TEXEL_BYTES 1
519
520 #define TAG(x) x##_l8_to_al88
521 #define PRESERVE_DST_TYPE
522 #include "texutil_tmp.h"
523
524
525 #define CONVERT_TEXEL( dst, src ) \
526 dst = PACK_COLOR_88( src[3], src[0] )
527
528 #define CONVERT_TEXEL_DWORD( dst, src ) \
529 dst = ((PACK_COLOR_88( src[3], src[0] )) | \
530 (PACK_COLOR_88( src[7], src[1] ) << 16))
531
532 #define SRC_TEXEL_BYTES 4
533
534 #define TAG(x) x##_abgr8888_to_al88
535 #include "texutil_tmp.h"
536
537
538 #define CONVERT_AL88( name ) \
539 static GLboolean \
540 convert_##name##_al88( struct gl_texture_convert *convert ) \
541 { \
542 convert_func *tab; \
543 GLint index = convert->index; \
544 \
545 if ( convert->format == GL_LUMINANCE_ALPHA && \
546 convert->type == GL_UNSIGNED_BYTE ) \
547 { \
548 tab = name##_tab_al88_direct; \
549 } \
550 else if ( convert->format == GL_ALPHA && \
551 convert->type == GL_UNSIGNED_BYTE ) \
552 { \
553 tab = name##_tab_a8_to_al88; \
554 } \
555 else if ( convert->format == GL_LUMINANCE && \
556 convert->type == GL_UNSIGNED_BYTE ) \
557 { \
558 tab = name##_tab_l8_to_al88; \
559 } \
560 else if ( convert->format == GL_RGBA && \
561 convert->type == GL_UNSIGNED_BYTE ) \
562 { \
563 tab = name##_tab_abgr8888_to_al88; \
564 } \
565 else \
566 { \
567 /* Can't handle this source format/type combination */ \
568 return GL_FALSE; \
569 } \
570 \
571 return tab[index]( convert ); \
572 }
573
574 CONVERT_AL88( texsubimage2d )
575 CONVERT_AL88( texsubimage3d )
576
577
578
579 /* ================================================================
580 * RGB332 textures:
581 */
582
583 static GLboolean
584 convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
585 {
586 /* This is a placeholder for now...
587 */
588 return GL_FALSE;
589 }
590
591 static GLboolean
592 convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
593 {
594 /* This is a placeholder for now...
595 */
596 return GL_FALSE;
597 }
598
599
600
601 /* ================================================================
602 * CI8 (and all other single-byte texel) textures:
603 */
604
605 #define DST_TYPE GLubyte
606 #define DST_TEXELS_PER_DWORD 4
607
608 #define CONVERT_TEXEL( dst, src ) dst = src[0]
609
610 #define CONVERT_DIRECT
611
612 #define SRC_TEXEL_BYTES 1
613
614 #define TAG(x) x##_ci8_direct
615 #include "texutil_tmp.h"
616
617
618 #define CONVERT_CI8( name ) \
619 static GLboolean \
620 convert_##name##_ci8( struct gl_texture_convert *convert ) \
621 { \
622 convert_func *tab; \
623 GLint index = convert->index; \
624 \
625 if ( ( convert->format == GL_ALPHA || \
626 convert->format == GL_LUMINANCE || \
627 convert->format == GL_INTENSITY || \
628 convert->format == GL_COLOR_INDEX ) && \
629 convert->type == GL_UNSIGNED_BYTE ) \
630 { \
631 tab = name##_tab_ci8_direct; \
632 } \
633 else \
634 { \
635 /* Can't handle this source format/type combination */ \
636 return GL_FALSE; \
637 } \
638 \
639 return tab[index]( convert ); \
640 }
641
642 CONVERT_CI8( texsubimage2d )
643 CONVERT_CI8( texsubimage3d )
644
645
646
647 /* ================================================================
648 * Global entry points
649 */
650
651 static convert_func gl_convert_texsubimage2d_tab[] = {
652 convert_texsubimage2d_rgba8888,
653 convert_texsubimage2d_argb8888,
654 convert_texsubimage2d_rgb888,
655 convert_texsubimage2d_rgb565,
656 convert_texsubimage2d_argb4444,
657 convert_texsubimage2d_argb1555,
658 convert_texsubimage2d_al88,
659 convert_texsubimage2d_rgb332,
660 convert_texsubimage2d_ci8, /* These are all the same... */
661 convert_texsubimage2d_ci8,
662 convert_texsubimage2d_ci8,
663 convert_texsubimage2d_ci8,
664 };
665
666 static convert_func gl_convert_texsubimage3d_tab[] = {
667 convert_texsubimage3d_rgba8888,
668 convert_texsubimage3d_argb8888,
669 convert_texsubimage3d_rgb888,
670 convert_texsubimage3d_rgb565,
671 convert_texsubimage3d_argb4444,
672 convert_texsubimage3d_argb1555,
673 convert_texsubimage3d_al88,
674 convert_texsubimage3d_rgb332,
675 convert_texsubimage3d_ci8, /* These are all the same... */
676 convert_texsubimage3d_ci8,
677 convert_texsubimage3d_ci8,
678 convert_texsubimage3d_ci8,
679 };
680
681
682 /* See if we need to care about the pixel store attributes when we're
683 * converting the texture image. This should be stored as
684 * packing->_SomeBoolean and updated when the values change, to avoid
685 * testing every time...
686 */
687 static INLINE GLboolean
688 convert_needs_packing( const struct gl_pixelstore_attrib *packing,
689 GLenum format, GLenum type )
690 {
691 if ( ( packing->Alignment == 1 ||
692 ( packing->Alignment == 4 && /* Pick up the common Q3A case... */
693 format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
694 packing->RowLength == 0 &&
695 packing->SkipPixels == 0 &&
696 packing->SkipRows == 0 &&
697 packing->ImageHeight == 0 &&
698 packing->SkipImages == 0 &&
699 packing->SwapBytes == GL_FALSE &&
700 packing->LsbFirst == GL_FALSE ) {
701 return GL_FALSE;
702 } else {
703 return GL_TRUE;
704 }
705 }
706
707
708 GLboolean
709 _mesa_convert_texsubimage1d( GLint mesaFormat,
710 GLint xoffset,
711 GLint width,
712 GLenum format, GLenum type,
713 const struct gl_pixelstore_attrib *packing,
714 const GLvoid *srcImage, GLvoid *dstImage )
715 {
716 struct gl_texture_convert convert;
717
718 ASSERT( packing );
719 ASSERT( srcImage );
720 ASSERT( dstImage );
721
722 ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
723 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
724
725 /* Make it easier to pass all the parameters around.
726 */
727 convert.xoffset = xoffset;
728 convert.yoffset = 0;
729 convert.width = width;
730 convert.height = 1;
731 convert.format = format;
732 convert.type = type;
733 convert.packing = packing;
734 convert.srcImage = srcImage;
735 convert.dstImage = dstImage;
736
737 convert.index = 0;
738
739 if ( convert_needs_packing( packing, format, type ) )
740 convert.index |= CONVERT_PACKING_BIT;
741
742 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
743 }
744
745
746 /*
747 * Convert a user's 2D image into a texture image. This basically repacks
748 * pixel data into the special texture formats used by core Mesa and the DRI
749 * drivers. This function can do full images or subimages.
750 *
751 * We return a boolean because this function may not accept some kinds of
752 * source image formats and/or types. For example, if the incoming
753 * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
754 * be able to do the conversion.
755 *
756 * In that case, the incoming image should first be simplified to one of
757 * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
758 * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
759 * with the _mesa_transfer_teximage() function. That function will also
760 * do image transfer operations such as scale/bias and convolution.
761 *
762 * Input:
763 * mesaFormat - one of the MESA_FORMAT_* values from texformat.h
764 * xoffset, yoffset - position in dest image to put data
765 * width, height - incoming image size, also size of dest region.
766 * dstImageWidth - width (row stride) of dest image in pixels
767 * format, type - incoming image format and type
768 * packing - describes incoming image packing
769 * srcImage - pointer to source image
770 * destImage - pointer to dest image
771 */
772 GLboolean
773 _mesa_convert_texsubimage2d( GLint mesaFormat,
774 GLint xoffset, GLint yoffset,
775 GLint width, GLint height,
776 GLint destImageWidth,
777 GLenum format, GLenum type,
778 const struct gl_pixelstore_attrib *packing,
779 const GLvoid *srcImage, GLvoid *dstImage )
780 {
781 struct gl_texture_convert convert;
782
783 ASSERT( packing );
784 ASSERT( srcImage );
785 ASSERT( dstImage );
786
787 ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
788 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
789
790 /* Make it easier to pass all the parameters around.
791 */
792 convert.xoffset = xoffset;
793 convert.yoffset = yoffset;
794 convert.width = width;
795 convert.height = height;
796 convert.dstImageWidth = destImageWidth;
797 convert.format = format;
798 convert.type = type;
799 convert.packing = packing;
800 convert.srcImage = srcImage;
801 convert.dstImage = dstImage;
802
803 convert.index = 0;
804
805 if ( convert_needs_packing( packing, format, type ) )
806 convert.index |= CONVERT_PACKING_BIT;
807
808 if ( width != destImageWidth )
809 convert.index |= CONVERT_STRIDE_BIT;
810
811 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
812 }
813
814 GLboolean
815 _mesa_convert_texsubimage3d( GLint mesaFormat,
816 GLint xoffset, GLint yoffset, GLint zoffset,
817 GLint width, GLint height, GLint depth,
818 GLint dstImageWidth, GLint dstImageHeight,
819 GLenum format, GLenum type,
820 const struct gl_pixelstore_attrib *packing,
821 const GLvoid *srcImage, GLvoid *dstImage )
822 {
823 struct gl_texture_convert convert;
824
825 ASSERT( packing );
826 ASSERT( srcImage );
827 ASSERT( dstImage );
828
829 ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
830 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
831
832 /* Make it easier to pass all the parameters around.
833 */
834 convert.xoffset = xoffset;
835 convert.yoffset = yoffset;
836 convert.zoffset = zoffset;
837 convert.width = width;
838 convert.height = height;
839 convert.depth = depth;
840 convert.dstImageWidth = dstImageWidth;
841 convert.dstImageHeight = dstImageHeight;
842 convert.format = format;
843 convert.type = type;
844 convert.packing = packing;
845 convert.srcImage = srcImage;
846 convert.dstImage = dstImage;
847
848 convert.index = 0;
849
850 if ( convert_needs_packing( packing, format, type ) )
851 convert.index |= CONVERT_PACKING_BIT;
852
853 if ( width != dstImageWidth || height != dstImageHeight )
854 convert.index |= CONVERT_STRIDE_BIT;
855
856 return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
857 }
858
859
860
861 /* Nearest filtering only (for broken hardware that can't support
862 * all aspect ratios). This can be made a lot faster, but I don't
863 * really care enough...
864 */
865 void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
866 GLint srcWidth, GLint srcHeight,
867 GLint dstWidth, GLint dstHeight,
868 const GLvoid *srcImage, GLvoid *dstImage )
869 {
870 GLint row, col;
871
872 #define INNER_LOOP( HOP, WOP ) \
873 for ( row = 0 ; row < dstHeight ; row++ ) { \
874 GLint srcRow = row HOP hScale; \
875 for ( col = 0 ; col < dstWidth ; col++ ) { \
876 GLint srcCol = col WOP wScale; \
877 *dst++ = src[srcRow * srcWidth + srcCol]; \
878 } \
879 } \
880
881 #define RESCALE_IMAGE( TYPE ) \
882 do { \
883 const TYPE *src = (const TYPE *)srcImage; \
884 TYPE *dst = (TYPE *)dstImage; \
885 \
886 if ( srcHeight <= dstHeight ) { \
887 const GLint hScale = dstHeight / srcHeight; \
888 if ( srcWidth <= dstWidth ) { \
889 const GLint wScale = dstWidth / srcWidth; \
890 INNER_LOOP( /, / ); \
891 } \
892 else { \
893 const GLint wScale = srcWidth / dstWidth; \
894 INNER_LOOP( /, * ); \
895 } \
896 } \
897 else { \
898 const GLint hScale = srcHeight / dstHeight; \
899 if ( srcWidth <= dstWidth ) { \
900 const GLint wScale = dstWidth / srcWidth; \
901 INNER_LOOP( *, / ); \
902 } \
903 else { \
904 const GLint wScale = srcWidth / dstWidth; \
905 INNER_LOOP( *, * ); \
906 } \
907 } \
908 } while (0)
909
910 switch ( texFormat->TexelBytes ) {
911 case 4:
912 RESCALE_IMAGE( GLuint );
913 break;
914
915 case 2:
916 RESCALE_IMAGE( GLushort );
917 break;
918
919 case 1:
920 RESCALE_IMAGE( GLubyte );
921 break;
922 }
923 }