renamed some vars, added a bunch of comments
[mesa.git] / src / mesa / main / texutil.c
1 /* $Id: texutil.c,v 1.17 2001/03/21 16:44:08 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( src ) \
78 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( src ) \
90 PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
91
92 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( 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( src ) \
102 PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
103
104 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( 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( src ) \
157 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( src ) \
169 PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
170
171 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( 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( src ) \
181 PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
182
183 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( 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( src ) \
257 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( src ) \
269 PACK_COLOR_565( src[0], src[1], src[2] )
270
271 #define CONVERT_TEXEL_DWORD( src ) \
272 ((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( src ) \
283 PACK_COLOR_565( src[0], src[1], src[2] )
284
285 #define CONVERT_TEXEL_DWORD( src ) \
286 ((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( src ) \
339 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( src ) \
351 PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
352
353 #define CONVERT_TEXEL_DWORD( src ) \
354 ((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( src ) \
402 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( src ) \
414 PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
415
416 #define CONVERT_TEXEL_DWORD( src ) \
417 ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) | \
418 (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
419
420 #define SRC_TEXEL_BYTES 4
421
422 #define TAG(x) x##_rgba8888_to_argb1555
423 #include "texutil_tmp.h"
424
425
426 #define CONVERT_ARGB1555( name ) \
427 static GLboolean \
428 convert_##name##_argb1555( struct gl_texture_convert *convert ) \
429 { \
430 convert_func *tab; \
431 GLint index = convert->index; \
432 \
433 if ( convert->format == GL_BGRA && \
434 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
435 { \
436 tab = name##_tab_argb1555_direct; \
437 } \
438 else if ( convert->format == GL_RGBA && \
439 convert->type == GL_UNSIGNED_BYTE ) \
440 { \
441 tab = name##_tab_rgba8888_to_argb1555; \
442 } \
443 else \
444 { \
445 /* Can't handle this source format/type combination */ \
446 return GL_FALSE; \
447 } \
448 \
449 return tab[index]( convert ); \
450 }
451
452 CONVERT_ARGB1555( texsubimage2d )
453 CONVERT_ARGB1555( texsubimage3d )
454
455
456
457 /* ================================================================
458 * AL88 textures:
459 */
460
461 #define DST_TYPE GLushort
462 #define DST_TEXELS_PER_DWORD 2
463
464 #define CONVERT_TEXEL( src ) \
465 PACK_COLOR_88( src[0], src[1] )
466
467 #define CONVERT_DIRECT
468
469 #define SRC_TEXEL_BYTES 2
470
471 #define TAG(x) x##_al88_direct
472 #define PRESERVE_DST_TYPE
473 #include "texutil_tmp.h"
474
475
476 #define CONVERT_TEXEL( src ) \
477 PACK_COLOR_88( src[0], 0x00 )
478
479 #define CONVERT_TEXEL_DWORD( src ) \
480 ((PACK_COLOR_88( src[0], 0x00 )) | \
481 (PACK_COLOR_88( src[1], 0x00 ) << 16))
482
483 #define SRC_TEXEL_BYTES 1
484
485 #define TAG(x) x##_a8_to_al88
486 #define PRESERVE_DST_TYPE
487 #include "texutil_tmp.h"
488
489
490 #define CONVERT_TEXEL( src ) \
491 PACK_COLOR_88( 0xff, src[0] )
492
493 #define CONVERT_TEXEL_DWORD( src ) \
494 ((PACK_COLOR_88( 0xff, src[0] )) | \
495 (PACK_COLOR_88( 0xff, src[1] ) << 16))
496
497 #define SRC_TEXEL_BYTES 1
498
499 #define TAG(x) x##_l8_to_al88
500 #include "texutil_tmp.h"
501
502
503 #define CONVERT_AL88( name ) \
504 static GLboolean \
505 convert_##name##_al88( struct gl_texture_convert *convert ) \
506 { \
507 convert_func *tab; \
508 GLint index = convert->index; \
509 \
510 if ( convert->format == GL_LUMINANCE_ALPHA && \
511 convert->type == GL_UNSIGNED_BYTE ) \
512 { \
513 tab = name##_tab_al88_direct; \
514 } \
515 else if ( convert->format == GL_ALPHA && \
516 convert->type == GL_UNSIGNED_BYTE ) \
517 { \
518 tab = name##_tab_a8_to_al88; \
519 } \
520 else if ( convert->format == GL_LUMINANCE && \
521 convert->type == GL_UNSIGNED_BYTE ) \
522 { \
523 tab = name##_tab_l8_to_al88; \
524 } \
525 else \
526 { \
527 /* Can't handle this source format/type combination */ \
528 return GL_FALSE; \
529 } \
530 \
531 return tab[index]( convert ); \
532 }
533
534 CONVERT_AL88( texsubimage2d )
535 CONVERT_AL88( texsubimage3d )
536
537
538
539 /* ================================================================
540 * RGB332 textures:
541 */
542
543 static GLboolean
544 convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
545 {
546 /* This is a placeholder for now...
547 */
548 return GL_FALSE;
549 }
550
551 static GLboolean
552 convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
553 {
554 /* This is a placeholder for now...
555 */
556 return GL_FALSE;
557 }
558
559
560
561 /* ================================================================
562 * CI8 (and all other single-byte texel) textures:
563 */
564
565 #define DST_TYPE GLubyte
566 #define DST_TEXELS_PER_DWORD 4
567
568 #define CONVERT_TEXEL( src ) src[0]
569
570 #define CONVERT_DIRECT
571
572 #define SRC_TEXEL_BYTES 1
573
574 #define TAG(x) x##_ci8_direct
575 #include "texutil_tmp.h"
576
577
578 #define CONVERT_CI8( name ) \
579 static GLboolean \
580 convert_##name##_ci8( struct gl_texture_convert *convert ) \
581 { \
582 convert_func *tab; \
583 GLint index = convert->index; \
584 \
585 if ( ( convert->format == GL_ALPHA || \
586 convert->format == GL_LUMINANCE || \
587 convert->format == GL_INTENSITY || \
588 convert->format == GL_COLOR_INDEX ) && \
589 convert->type == GL_UNSIGNED_BYTE ) \
590 { \
591 tab = name##_tab_ci8_direct; \
592 } \
593 else \
594 { \
595 /* Can't handle this source format/type combination */ \
596 return GL_FALSE; \
597 } \
598 \
599 return tab[index]( convert ); \
600 }
601
602 CONVERT_CI8( texsubimage2d )
603 CONVERT_CI8( texsubimage3d )
604
605
606
607 /* ================================================================
608 * Global entry points
609 */
610
611 static convert_func gl_convert_texsubimage2d_tab[] = {
612 convert_texsubimage2d_rgba8888,
613 convert_texsubimage2d_argb8888,
614 convert_texsubimage2d_rgb888,
615 convert_texsubimage2d_rgb565,
616 convert_texsubimage2d_argb4444,
617 convert_texsubimage2d_argb1555,
618 convert_texsubimage2d_al88,
619 convert_texsubimage2d_rgb332,
620 convert_texsubimage2d_ci8, /* These are all the same... */
621 convert_texsubimage2d_ci8,
622 convert_texsubimage2d_ci8,
623 convert_texsubimage2d_ci8,
624 };
625
626 static convert_func gl_convert_texsubimage3d_tab[] = {
627 convert_texsubimage3d_rgba8888,
628 convert_texsubimage3d_argb8888,
629 convert_texsubimage3d_rgb888,
630 convert_texsubimage3d_rgb565,
631 convert_texsubimage3d_argb4444,
632 convert_texsubimage3d_argb1555,
633 convert_texsubimage3d_al88,
634 convert_texsubimage3d_rgb332,
635 convert_texsubimage3d_ci8, /* These are all the same... */
636 convert_texsubimage3d_ci8,
637 convert_texsubimage3d_ci8,
638 convert_texsubimage3d_ci8,
639 };
640
641
642 /* See if we need to care about the pixel store attributes when we're
643 * converting the texture image. This should be stored as
644 * packing->_SomeBoolean and updated when the values change, to avoid
645 * testing every time...
646 */
647 static INLINE GLboolean
648 convert_needs_packing( const struct gl_pixelstore_attrib *packing,
649 GLenum format, GLenum type )
650 {
651 if ( ( packing->Alignment == 1 ||
652 ( packing->Alignment == 4 && /* Pick up the common Q3A case... */
653 format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
654 packing->RowLength == 0 &&
655 packing->SkipPixels == 0 &&
656 packing->SkipRows == 0 &&
657 packing->ImageHeight == 0 &&
658 packing->SkipImages == 0 &&
659 packing->SwapBytes == GL_FALSE &&
660 packing->LsbFirst == GL_FALSE ) {
661 return GL_FALSE;
662 } else {
663 return GL_TRUE;
664 }
665 }
666
667
668 GLboolean
669 _mesa_convert_texsubimage1d( GLint mesaFormat,
670 GLint xoffset,
671 GLint width,
672 GLenum format, GLenum type,
673 const struct gl_pixelstore_attrib *packing,
674 const GLvoid *srcImage, GLvoid *dstImage )
675 {
676 struct gl_texture_convert convert;
677
678 ASSERT( packing );
679 ASSERT( srcImage );
680 ASSERT( dstImage );
681
682 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
683 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
684
685 /* Make it easier to pass all the parameters around.
686 */
687 convert.xoffset = xoffset;
688 convert.yoffset = 0;
689 convert.width = width;
690 convert.height = 1;
691 convert.format = format;
692 convert.type = type;
693 convert.packing = packing;
694 convert.srcImage = srcImage;
695 convert.dstImage = dstImage;
696
697 convert.index = 0;
698
699 if ( convert_needs_packing( packing, format, type ) )
700 convert.index |= CONVERT_PACKING_BIT;
701
702 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
703 }
704
705
706 /*
707 * Convert a user's 2D image into a texture image. This basically repacks
708 * pixel data into the special texture formats used by core Mesa and the DRI
709 * drivers. This function can do full images or subimages.
710 *
711 * We return a boolean because this function may not accept some kinds of
712 * source image formats and/or types. For example, if the incoming
713 * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
714 * be able to do the conversion.
715 *
716 * In that case, the incoming image should first be simplified to one of
717 * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
718 * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
719 * with the _mesa_transfer_teximage() function. That function will also
720 * do image transfer operations such as scale/bias and convolution.
721 *
722 * Input:
723 * mesaFormat - one of the MESA_FORMAT_* values from texformat.h
724 * xoffset, yoffset - position in dest image to put data
725 * width, height - incoming image size, also size of dest region.
726 * dstImageWidth - width (row stride) of dest image in pixels
727 * format, type - incoming image format and type
728 * packing - describes incoming image packing
729 * srcImage - pointer to source image
730 * destImage - pointer to dest image
731 */
732 GLboolean
733 _mesa_convert_texsubimage2d( GLint mesaFormat,
734 GLint xoffset, GLint yoffset,
735 GLint width, GLint height,
736 GLint destImageWidth,
737 GLenum format, GLenum type,
738 const struct gl_pixelstore_attrib *packing,
739 const GLvoid *srcImage, GLvoid *dstImage )
740 {
741 struct gl_texture_convert convert;
742
743 ASSERT( packing );
744 ASSERT( srcImage );
745 ASSERT( dstImage );
746
747 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
748 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
749
750 /* Make it easier to pass all the parameters around.
751 */
752 convert.xoffset = xoffset;
753 convert.yoffset = yoffset;
754 convert.width = width;
755 convert.height = height;
756 convert.dstImageWidth = destImageWidth;
757 convert.format = format;
758 convert.type = type;
759 convert.packing = packing;
760 convert.srcImage = srcImage;
761 convert.dstImage = dstImage;
762
763 convert.index = 0;
764
765 if ( convert_needs_packing( packing, format, type ) )
766 convert.index |= CONVERT_PACKING_BIT;
767
768 if ( width != destImageWidth )
769 convert.index |= CONVERT_STRIDE_BIT;
770
771 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
772 }
773
774 GLboolean
775 _mesa_convert_texsubimage3d( GLint mesaFormat,
776 GLint xoffset, GLint yoffset, GLint zoffset,
777 GLint width, GLint height, GLint depth,
778 GLint dstImageWidth, GLint dstImageHeight,
779 GLenum format, GLenum type,
780 const struct gl_pixelstore_attrib *packing,
781 const GLvoid *srcImage, GLvoid *dstImage )
782 {
783 struct gl_texture_convert convert;
784
785 ASSERT( packing );
786 ASSERT( srcImage );
787 ASSERT( dstImage );
788
789 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
790 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
791
792 /* Make it easier to pass all the parameters around.
793 */
794 convert.xoffset = xoffset;
795 convert.yoffset = yoffset;
796 convert.zoffset = zoffset;
797 convert.width = width;
798 convert.height = height;
799 convert.depth = depth;
800 convert.dstImageWidth = dstImageWidth;
801 convert.dstImageHeight = dstImageHeight;
802 convert.format = format;
803 convert.type = type;
804 convert.packing = packing;
805 convert.srcImage = srcImage;
806 convert.dstImage = dstImage;
807
808 convert.index = 0;
809
810 if ( convert_needs_packing( packing, format, type ) )
811 convert.index |= CONVERT_PACKING_BIT;
812
813 if ( width != dstImageWidth || height != dstImageHeight )
814 convert.index |= CONVERT_STRIDE_BIT;
815
816 return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
817 }
818
819
820
821 /* Nearest filtering only (for broken hardware that can't support
822 * all aspect ratios). This can be made a lot faster, but I don't
823 * really care enough...
824 */
825 void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
826 GLint srcWidth, GLint srcHeight,
827 GLint dstWidth, GLint dstHeight,
828 const GLvoid *srcImage, GLvoid *dstImage )
829 {
830 GLint row, col;
831
832 #define INNER_LOOP( HOP, WOP ) \
833 for ( row = 0 ; row < dstHeight ; row++ ) { \
834 GLint srcRow = row HOP hScale; \
835 for ( col = 0 ; col < dstWidth ; col++ ) { \
836 GLint srcCol = col WOP wScale; \
837 *dst++ = src[srcRow * srcWidth + srcCol]; \
838 } \
839 } \
840
841 #define RESCALE_IMAGE( TYPE ) \
842 do { \
843 const TYPE *src = (const TYPE *)srcImage; \
844 TYPE *dst = (TYPE *)dstImage; \
845 \
846 if ( srcHeight <= dstHeight ) { \
847 const GLint hScale = dstHeight / srcHeight; \
848 if ( srcWidth <= dstWidth ) { \
849 const GLint wScale = dstWidth / srcWidth; \
850 INNER_LOOP( /, / ); \
851 } \
852 else { \
853 const GLint wScale = srcWidth / dstWidth; \
854 INNER_LOOP( /, * ); \
855 } \
856 } \
857 else { \
858 const GLint hScale = srcHeight / dstHeight; \
859 if ( srcWidth <= dstWidth ) { \
860 const GLint wScale = dstWidth / srcWidth; \
861 INNER_LOOP( *, / ); \
862 } \
863 else { \
864 const GLint wScale = srcWidth / dstWidth; \
865 INNER_LOOP( *, * ); \
866 } \
867 } \
868 } while (0)
869
870 switch ( texFormat->TexelBytes ) {
871 case 4:
872 RESCALE_IMAGE( GLuint );
873 break;
874
875 case 2:
876 RESCALE_IMAGE( GLushort );
877 break;
878
879 case 1:
880 RESCALE_IMAGE( GLubyte );
881 break;
882 }
883 }