3 * Mesa 3-D graphics library
6 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 * Functions for texture image conversion. This takes care of converting
32 * typical GL_RGBA/GLubyte textures into hardware-specific formats.
33 * We can handle non-standard row strides and pixel unpacking parameters.
45 #include "texformat.h"
49 #define DEBUG_TEXUTIL 0
52 #ifdef MESA_BIG_ENDIAN
53 #define APPEND16( a, b ) ( (a) << 16 | (b) )
55 #define APPEND16( a, b ) ( (a) | (b) << 16 )
60 GLint xoffset
, yoffset
, zoffset
; /* Subimage offset */
61 GLint width
, height
, depth
; /* Subimage region */
63 GLint dstImageWidth
, dstImageHeight
; /* Dest image size */
64 /* Needed for subimage replacement */
65 GLenum format
, type
; /* Source (user) format and type */
67 const struct gl_pixelstore_attrib
*unpacking
;
69 const GLvoid
*srcImage
;
75 typedef GLboolean (*convert_func
)( const struct convert_info
*convert
);
77 /* bitvalues for convert->index */
78 #define CONVERT_STRIDE_BIT 0x1
79 #define CONVERT_UNPACKING_BIT 0x2
83 /* =============================================================
84 * Convert to RGBA8888 textures:
87 #define DST_TYPE GLuint
88 #define DST_TEXELS_PER_DWORD 1
90 #define CONVERT_TEXEL( dst, src ) \
91 dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
93 #define CONVERT_DIRECT
95 #define SRC_TEXEL_BYTES 4
97 #define TAG(x) x##_rgba8888_direct
98 #define PRESERVE_DST_TYPE
99 #include "texutil_tmp.h"
102 #define CONVERT_TEXEL( dst, src ) \
103 dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
105 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
107 #define SRC_TEXEL_BYTES 4
109 #define TAG(x) x##_abgr8888_to_rgba8888
110 #define PRESERVE_DST_TYPE
111 #include "texutil_tmp.h"
114 #define CONVERT_TEXEL( dst, src ) \
115 dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
117 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
119 #define SRC_TEXEL_BYTES 3
121 #define TAG(x) x##_bgr888_to_rgba8888
122 #include "texutil_tmp.h"
125 #define CONVERT_RGBA8888( name ) \
127 convert_##name##_rgba8888( const struct convert_info *convert ) \
130 GLint index = convert->index; \
132 if ( convert->format == GL_ABGR_EXT && \
133 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
135 tab = name##_tab_rgba8888_direct; \
137 else if ( convert->format == GL_RGBA && \
138 ( convert->type == GL_UNSIGNED_BYTE || \
139 convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
141 tab = name##_tab_abgr8888_to_rgba8888; \
143 else if ( convert->format == GL_RGB && \
144 convert->type == GL_UNSIGNED_BYTE ) \
146 tab = name##_tab_bgr888_to_rgba8888; \
150 /* Can't handle this source format/type combination */ \
154 return tab[index]( convert ); \
157 CONVERT_RGBA8888( texsubimage2d
)
158 CONVERT_RGBA8888( texsubimage3d
)
162 /* =============================================================
163 * Convert to ARGB8888 textures:
166 #define DST_TYPE GLuint
167 #define DST_TEXELS_PER_DWORD 1
169 #define CONVERT_TEXEL( dst, src ) \
170 dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
172 #define CONVERT_DIRECT
174 #define SRC_TEXEL_BYTES 4
176 #define TAG(x) x##_argb8888_direct
177 #define PRESERVE_DST_TYPE
178 #include "texutil_tmp.h"
181 #define CONVERT_TEXEL( dst, src ) \
182 dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
184 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
186 #define SRC_TEXEL_BYTES 4
188 #define TAG(x) x##_abgr8888_to_argb8888
189 #define PRESERVE_DST_TYPE
190 #include "texutil_tmp.h"
193 #define CONVERT_TEXEL( dst, src ) \
194 dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
196 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
198 #define SRC_TEXEL_BYTES 3
200 #define TAG(x) x##_bgr888_to_argb8888
201 #include "texutil_tmp.h"
204 #define CONVERT_ARGB8888( name ) \
206 convert_##name##_argb8888( const struct convert_info *convert ) \
209 GLint index = convert->index; \
211 if ( convert->format == GL_BGRA && \
212 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
214 tab = name##_tab_argb8888_direct; \
216 else if ( convert->format == GL_RGBA && \
217 convert->type == GL_UNSIGNED_BYTE ) \
219 tab = name##_tab_abgr8888_to_argb8888; \
221 else if ( convert->format == GL_RGB && \
222 convert->type == GL_UNSIGNED_BYTE ) \
224 tab = name##_tab_bgr888_to_argb8888; \
228 /* Can't handle this source format/type combination */ \
232 return tab[index]( convert ); \
235 CONVERT_ARGB8888( texsubimage2d
)
236 CONVERT_ARGB8888( texsubimage3d
)
240 /* =============================================================
241 * Convert to RGB888 textures:
245 convert_texsubimage2d_rgb888( const struct convert_info
*convert
)
247 /* This is a placeholder for now...
253 convert_texsubimage3d_rgb888( const struct convert_info
*convert
)
255 /* This is a placeholder for now...
262 /* =============================================================
263 * Convert to RGB565 textures:
266 #define DST_TYPE GLushort
267 #define DST_TEXELS_PER_DWORD 2
269 #define CONVERT_TEXEL( dst, src ) \
270 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
272 #define CONVERT_DIRECT
274 #define SRC_TEXEL_BYTES 2
276 #define TAG(x) x##_rgb565_direct
277 #define PRESERVE_DST_TYPE
278 #include "texutil_tmp.h"
281 #define CONVERT_TEXEL( dst, src ) \
282 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
284 #define CONVERT_TEXEL_DWORD( dst, src ) \
285 dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
286 PACK_COLOR_565_LE( src[3], src[4], src[5] ) )
288 #define SRC_TEXEL_BYTES 3
290 #define TAG(x) x##_bgr888_to_rgb565
291 #define PRESERVE_DST_TYPE
292 #include "texutil_tmp.h"
295 #define CONVERT_TEXEL( dst, src ) \
296 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
298 #define CONVERT_TEXEL_DWORD( dst, src ) \
299 dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
300 PACK_COLOR_565_LE( src[4], src[5], src[6] ) )
302 #define SRC_TEXEL_BYTES 4
304 #define TAG(x) x##_abgr8888_to_rgb565
305 #include "texutil_tmp.h"
308 #define CONVERT_RGB565( name ) \
310 convert_##name##_rgb565( const struct convert_info *convert ) \
313 GLint index = convert->index; \
315 if ( convert->format == GL_RGB && \
316 convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
318 tab = name##_tab_rgb565_direct; \
320 else if ( convert->format == GL_RGB && \
321 convert->type == GL_UNSIGNED_BYTE ) \
323 tab = name##_tab_bgr888_to_rgb565; \
325 else if ( convert->format == GL_RGBA && \
326 convert->type == GL_UNSIGNED_BYTE ) \
328 tab = name##_tab_abgr8888_to_rgb565; \
332 /* Can't handle this source format/type combination */ \
336 return tab[index]( convert ); \
339 CONVERT_RGB565( texsubimage2d
)
340 CONVERT_RGB565( texsubimage3d
)
344 /* =============================================================
345 * Convert to ARGB4444 textures:
348 #define DST_TYPE GLushort
349 #define DST_TEXELS_PER_DWORD 2
351 #define CONVERT_TEXEL( dst, src ) \
352 dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
354 #define CONVERT_DIRECT
356 #define SRC_TEXEL_BYTES 2
358 #define TAG(x) x##_argb4444_direct
359 #define PRESERVE_DST_TYPE
360 #include "texutil_tmp.h"
363 #define CONVERT_TEXEL( dst, src ) \
364 dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
366 #define CONVERT_TEXEL_DWORD( dst, src ) \
367 dst = APPEND16( PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] ), \
368 PACK_COLOR_4444_LE( src[7], src[4], src[5], src[6] ) )
370 #define SRC_TEXEL_BYTES 4
372 #define TAG(x) x##_abgr8888_to_argb4444
373 #include "texutil_tmp.h"
376 #define CONVERT_ARGB4444( name ) \
378 convert_##name##_argb4444( const struct convert_info *convert ) \
381 GLint index = convert->index; \
383 if ( convert->format == GL_BGRA && \
384 convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
386 tab = name##_tab_argb4444_direct; \
388 else if ( convert->format == GL_RGBA && \
389 convert->type == GL_UNSIGNED_BYTE ) \
391 tab = name##_tab_abgr8888_to_argb4444; \
395 /* Can't handle this source format/type combination */ \
399 return tab[index]( convert ); \
402 CONVERT_ARGB4444( texsubimage2d
)
403 CONVERT_ARGB4444( texsubimage3d
)
407 /* =============================================================
408 * Convert to ARGB1555 textures:
411 #define DST_TYPE GLushort
412 #define DST_TEXELS_PER_DWORD 2
414 #define CONVERT_TEXEL( dst, src ) \
415 dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
417 #define CONVERT_DIRECT
419 #define SRC_TEXEL_BYTES 2
421 #define TAG(x) x##_argb1555_direct
422 #define PRESERVE_DST_TYPE
423 #include "texutil_tmp.h"
426 #ifdef MESA_BIG_ENDIAN
428 #define CONVERT_TEXEL( dst, src ) \
429 { const GLushort s = *(GLushort *)src; \
430 dst = (s >> 9) | ((s & 0x1ff) << 7); }
432 #define CONVERT_TEXEL_DWORD( dst, src ) \
433 { const GLuint s = ((fi_type *)src)->i; \
434 dst = (((s & 0xfe00fe00) >> 9) | \
435 ((s & 0x01ff01ff) << 7)); }
439 #define CONVERT_TEXEL( dst, src ) \
440 { const GLushort s = *(GLushort *)src; \
441 dst = (s >> 1) | ((s & 1) << 15); }
443 #define CONVERT_TEXEL_DWORD( dst, src ) \
444 { const GLuint s = ((fi_type *)src)->i; \
445 dst = (((s & 0xfffefffe) >> 1) | \
446 ((s & 0x00010001) << 15)); }
450 #define SRC_TEXEL_BYTES 2
452 #define TAG(x) x##_rgba5551_to_argb1555
453 #define PRESERVE_DST_TYPE
454 #include "texutil_tmp.h"
457 #define CONVERT_TEXEL( dst, src ) \
458 dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
460 #define CONVERT_TEXEL_DWORD( dst, src ) \
461 dst = APPEND16( PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] ), \
462 PACK_COLOR_1555_LE( src[7], src[4], src[5], src[6] ) )
464 #define SRC_TEXEL_BYTES 4
466 #define TAG(x) x##_abgr8888_to_argb1555
467 #include "texutil_tmp.h"
470 #define CONVERT_ARGB1555( name ) \
472 convert_##name##_argb1555( const struct convert_info *convert ) \
475 GLint index = convert->index; \
477 if ( convert->format == GL_BGRA && \
478 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
480 tab = name##_tab_argb1555_direct; \
482 else if ( convert->format == GL_RGBA && \
483 convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \
485 tab = name##_tab_rgba5551_to_argb1555; \
487 else if ( convert->format == GL_RGBA && \
488 convert->type == GL_UNSIGNED_BYTE ) \
490 tab = name##_tab_abgr8888_to_argb1555; \
494 /* Can't handle this source format/type combination */ \
498 return tab[index]( convert ); \
501 CONVERT_ARGB1555( texsubimage2d
)
502 CONVERT_ARGB1555( texsubimage3d
)
506 /* =============================================================
510 #define DST_TYPE GLushort
511 #define DST_TEXELS_PER_DWORD 2
513 #define CONVERT_TEXEL( dst, src ) \
514 dst = PACK_COLOR_88_LE( src[0], src[1] )
516 #define CONVERT_DIRECT
518 #define SRC_TEXEL_BYTES 2
520 #define TAG(x) x##_al88_direct
521 #define PRESERVE_DST_TYPE
522 #include "texutil_tmp.h"
525 #define CONVERT_TEXEL( dst, src ) \
526 dst = PACK_COLOR_88_LE( src[0], 0x00 )
528 #define CONVERT_TEXEL_DWORD( dst, src ) \
529 dst = APPEND16( PACK_COLOR_88_LE( src[0], 0x00 ), \
530 PACK_COLOR_88_LE( src[1], 0x00 ) )
532 #define SRC_TEXEL_BYTES 1
534 #define TAG(x) x##_a8_to_al88
535 #define PRESERVE_DST_TYPE
536 #include "texutil_tmp.h"
539 #define CONVERT_TEXEL( dst, src ) \
540 dst = PACK_COLOR_88_LE( 0xff, src[0] )
542 #define CONVERT_TEXEL_DWORD( dst, src ) \
543 dst = APPEND16( PACK_COLOR_88_LE( 0xff, src[0] ), \
544 PACK_COLOR_88_LE( 0xff, src[1] ) )
546 #define SRC_TEXEL_BYTES 1
548 #define TAG(x) x##_l8_to_al88
549 #define PRESERVE_DST_TYPE
550 #include "texutil_tmp.h"
553 #define CONVERT_TEXEL( dst, src ) \
554 dst = PACK_COLOR_88_LE( src[3], src[0] )
556 #define CONVERT_TEXEL_DWORD( dst, src ) \
557 dst = APPEND16( PACK_COLOR_88_LE( src[3], src[0] ), \
558 PACK_COLOR_88_LE( src[7], src[4] ) )
560 #define SRC_TEXEL_BYTES 4
562 #define TAG(x) x##_abgr8888_to_al88
563 #include "texutil_tmp.h"
566 #define CONVERT_AL88( name ) \
568 convert_##name##_al88( const struct convert_info *convert ) \
571 GLint index = convert->index; \
573 if ( convert->format == GL_LUMINANCE_ALPHA && \
574 convert->type == GL_UNSIGNED_BYTE ) \
576 tab = name##_tab_al88_direct; \
578 else if ( convert->format == GL_ALPHA && \
579 convert->type == GL_UNSIGNED_BYTE ) \
581 tab = name##_tab_a8_to_al88; \
583 else if ( convert->format == GL_LUMINANCE && \
584 convert->type == GL_UNSIGNED_BYTE ) \
586 tab = name##_tab_l8_to_al88; \
588 else if ( convert->format == GL_RGBA && \
589 convert->type == GL_UNSIGNED_BYTE ) \
591 tab = name##_tab_abgr8888_to_al88; \
595 /* Can't handle this source format/type combination */ \
599 return tab[index]( convert ); \
602 CONVERT_AL88( texsubimage2d
)
603 CONVERT_AL88( texsubimage3d
)
607 /* =============================================================
608 * Convert to RGB332 textures:
612 convert_texsubimage2d_rgb332( const struct convert_info
*convert
)
614 /* This is a placeholder for now...
620 convert_texsubimage3d_rgb332( const struct convert_info
*convert
)
622 /* This is a placeholder for now...
629 /* =============================================================
630 * CI8 (and all other single-byte texel) textures:
633 #define DST_TYPE GLubyte
634 #define DST_TEXELS_PER_DWORD 4
636 #define CONVERT_TEXEL( dst, src ) dst = src[0]
638 #define CONVERT_DIRECT
640 #define SRC_TEXEL_BYTES 1
642 #define TAG(x) x##_ci8_direct
643 #include "texutil_tmp.h"
646 #define CONVERT_CI8( name ) \
648 convert_##name##_ci8( const struct convert_info *convert ) \
651 GLint index = convert->index; \
653 if ( ( convert->format == GL_ALPHA || \
654 convert->format == GL_LUMINANCE || \
655 convert->format == GL_INTENSITY || \
656 convert->format == GL_COLOR_INDEX ) && \
657 convert->type == GL_UNSIGNED_BYTE ) \
659 tab = name##_tab_ci8_direct; \
663 /* Can't handle this source format/type combination */ \
667 return tab[index]( convert ); \
670 CONVERT_CI8( texsubimage2d
)
671 CONVERT_CI8( texsubimage3d
)
674 /* =============================================================
675 * convert to YCBCR textures:
678 #define DST_TYPE GLushort
679 #define DST_TEXELS_PER_DWORD 2
681 #define CONVERT_TEXEL( dst, src ) \
682 dst = (src[0] << 8) | src[1];
684 #define CONVERT_DIRECT
686 #define SRC_TEXEL_BYTES 2
688 #define TAG(x) x##_ycbcr_direct
689 #include "texutil_tmp.h"
692 #define CONVERT_YCBCR( name ) \
694 convert_##name##_ycbcr( const struct convert_info *convert ) \
697 GLint index = convert->index; \
699 if (convert->format != GL_YCBCR_MESA) { \
700 /* Can't handle this source format/type combination */ \
703 tab = name##_tab_ycbcr_direct; \
705 return tab[index]( convert ); \
708 CONVERT_YCBCR( texsubimage2d
)
709 CONVERT_YCBCR( texsubimage3d
)
712 /* =============================================================
713 * convert to YCBCR_REV textures:
716 #define DST_TYPE GLushort
717 #define DST_TEXELS_PER_DWORD 2
719 #define CONVERT_TEXEL( dst, src ) \
720 dst = (src[1] << 8) | src[0];
722 #define CONVERT_DIRECT
724 #define SRC_TEXEL_BYTES 2
726 #define TAG(x) x##_ycbcr_rev_direct
727 #include "texutil_tmp.h"
730 #define CONVERT_YCBCR_REV( name ) \
732 convert_##name##_ycbcr_rev( const struct convert_info *convert ) \
735 GLint index = convert->index; \
737 if (convert->format != GL_YCBCR_MESA) { \
738 /* Can't handle this source format/type combination */ \
741 tab = name##_tab_ycbcr_rev_direct; \
743 return tab[index]( convert ); \
746 CONVERT_YCBCR_REV( texsubimage2d
)
747 CONVERT_YCBCR_REV( texsubimage3d
)
751 /* =============================================================
752 * Global entry points
755 static convert_func convert_texsubimage2d_tab
[] = {
756 convert_texsubimage2d_rgba8888
,
757 convert_texsubimage2d_argb8888
,
758 convert_texsubimage2d_rgb888
,
759 convert_texsubimage2d_rgb565
,
760 convert_texsubimage2d_argb4444
,
761 convert_texsubimage2d_argb1555
,
762 convert_texsubimage2d_al88
,
763 convert_texsubimage2d_rgb332
,
764 convert_texsubimage2d_ci8
, /* These are all the same... */
765 convert_texsubimage2d_ci8
,
766 convert_texsubimage2d_ci8
,
767 convert_texsubimage2d_ci8
,
768 convert_texsubimage2d_ycbcr
,
769 convert_texsubimage2d_ycbcr_rev
,
772 static convert_func convert_texsubimage3d_tab
[] = {
773 convert_texsubimage3d_rgba8888
,
774 convert_texsubimage3d_argb8888
,
775 convert_texsubimage3d_rgb888
,
776 convert_texsubimage3d_rgb565
,
777 convert_texsubimage3d_argb4444
,
778 convert_texsubimage3d_argb1555
,
779 convert_texsubimage3d_al88
,
780 convert_texsubimage3d_rgb332
,
781 convert_texsubimage3d_ci8
, /* These are all the same... */
782 convert_texsubimage3d_ci8
,
783 convert_texsubimage3d_ci8
,
784 convert_texsubimage3d_ci8
,
785 convert_texsubimage3d_ycbcr
,
786 convert_texsubimage3d_ycbcr_rev
,
790 /* See if we need to care about the pixel store attributes when we're
791 * converting the texture image. This should be stored as
792 * unpacking->_SomeBoolean and updated when the values change, to avoid
793 * testing every time...
795 static INLINE GLboolean
796 convert_needs_unpacking( const struct gl_pixelstore_attrib
*unpacking
,
797 GLenum format
, GLenum type
)
799 if ( ( unpacking
->Alignment
== 1 ||
800 ( unpacking
->Alignment
== 4 && /* Pick up the common Q3A case... */
801 format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) ) &&
802 unpacking
->RowLength
== 0 &&
803 unpacking
->SkipPixels
== 0 &&
804 unpacking
->SkipRows
== 0 &&
805 unpacking
->ImageHeight
== 0 &&
806 unpacking
->SkipImages
== 0 &&
807 unpacking
->SwapBytes
== GL_FALSE
&&
808 unpacking
->LsbFirst
== GL_FALSE
) {
817 _mesa_convert_texsubimage1d( GLint mesaFormat
,
820 GLenum format
, GLenum type
,
821 const struct gl_pixelstore_attrib
*unpacking
,
822 const GLvoid
*srcImage
, GLvoid
*dstImage
)
824 struct convert_info convert
;
830 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
831 ASSERT( mesaFormat
<= MESA_FORMAT_YCBCR_REV
);
833 /* Make it easier to pass all the parameters around.
835 convert
.xoffset
= xoffset
;
837 convert
.width
= width
;
839 convert
.format
= format
;
841 convert
.unpacking
= unpacking
;
842 convert
.srcImage
= srcImage
;
843 convert
.dstImage
= dstImage
;
847 if ( convert_needs_unpacking( unpacking
, format
, type
) )
848 convert
.index
|= CONVERT_UNPACKING_BIT
;
850 ASSERT(convert
.index
< 4);
852 return convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
856 /* Convert a user's 2D image into a texture image. This basically
857 * repacks pixel data into the special texture formats used by core Mesa
858 * and the DRI drivers. This function can do full images or subimages.
860 * We return a boolean because this function may not accept some kinds
861 * of source image formats and/or types. For example, if the incoming
862 * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
863 * be able to do the conversion.
865 * In that case, the incoming image should first be simplified to one of
866 * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
867 * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
868 * with the _mesa_transfer_teximage() function. That function will also
869 * do image transfer operations such as scale/bias and convolution.
872 * mesaFormat - one of the MESA_FORMAT_* values from texformat.h
873 * xoffset, yoffset - position in dest image to put data
874 * width, height - incoming image size, also size of dest region.
875 * dstImageWidth - width (row stride) of dest image in pixels
876 * format, type - incoming image format and type
877 * unpacking - describes incoming image unpacking
878 * srcImage - pointer to source image
879 * destImage - pointer to dest image
882 _mesa_convert_texsubimage2d( GLint mesaFormat
, /* dest */
883 GLint xoffset
, GLint yoffset
,
884 GLint width
, GLint height
,
885 GLint destImageWidth
,
886 GLenum format
, GLenum type
, /* source */
887 const struct gl_pixelstore_attrib
*unpacking
,
888 const GLvoid
*srcImage
, GLvoid
*dstImage
)
890 struct convert_info convert
;
896 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
897 ASSERT( mesaFormat
<= MESA_FORMAT_YCBCR_REV
);
899 /* Make it easier to pass all the parameters around.
901 convert
.xoffset
= xoffset
;
902 convert
.yoffset
= yoffset
;
903 convert
.width
= width
;
904 convert
.height
= height
;
905 convert
.dstImageWidth
= destImageWidth
;
906 convert
.format
= format
;
908 convert
.unpacking
= unpacking
;
909 convert
.srcImage
= srcImage
;
910 convert
.dstImage
= dstImage
;
914 if ( convert_needs_unpacking( unpacking
, format
, type
) )
915 convert
.index
|= CONVERT_UNPACKING_BIT
;
917 if ( width
!= destImageWidth
)
918 convert
.index
|= CONVERT_STRIDE_BIT
;
920 return convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
924 _mesa_convert_texsubimage3d( GLint mesaFormat
, /* dest */
925 GLint xoffset
, GLint yoffset
, GLint zoffset
,
926 GLint width
, GLint height
, GLint depth
,
927 GLint dstImageWidth
, GLint dstImageHeight
,
928 GLenum format
, GLenum type
, /* source */
929 const struct gl_pixelstore_attrib
*unpacking
,
930 const GLvoid
*srcImage
, GLvoid
*dstImage
)
932 struct convert_info convert
;
938 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
939 ASSERT( mesaFormat
<= MESA_FORMAT_YCBCR_REV
);
941 /* Make it easier to pass all the parameters around.
943 convert
.xoffset
= xoffset
;
944 convert
.yoffset
= yoffset
;
945 convert
.zoffset
= zoffset
;
946 convert
.width
= width
;
947 convert
.height
= height
;
948 convert
.depth
= depth
;
949 convert
.dstImageWidth
= dstImageWidth
;
950 convert
.dstImageHeight
= dstImageHeight
;
951 convert
.format
= format
;
953 convert
.unpacking
= unpacking
;
954 convert
.srcImage
= srcImage
;
955 convert
.dstImage
= dstImage
;
959 if ( convert_needs_unpacking( unpacking
, format
, type
) )
960 convert
.index
|= CONVERT_UNPACKING_BIT
;
962 if ( width
!= dstImageWidth
|| height
!= dstImageHeight
)
963 convert
.index
|= CONVERT_STRIDE_BIT
;
965 return convert_texsubimage3d_tab
[mesaFormat
]( &convert
);
970 /* Nearest filtering only (for broken hardware that can't support
971 * all aspect ratios). This can be made a lot faster, but I don't
972 * really care enough...
974 void _mesa_rescale_teximage2d( GLuint bytesPerPixel
, GLuint dstRowStride
,
975 GLint srcWidth
, GLint srcHeight
,
976 GLint dstWidth
, GLint dstHeight
,
977 const GLvoid
*srcImage
, GLvoid
*dstImage
)
981 #define INNER_LOOP( TYPE, HOP, WOP ) \
982 for ( row = 0 ; row < dstHeight ; row++ ) { \
983 GLint srcRow = row HOP hScale; \
984 for ( col = 0 ; col < dstWidth ; col++ ) { \
985 GLint srcCol = col WOP wScale; \
986 dst[col] = src[srcRow * srcWidth + srcCol]; \
988 dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \
991 #define RESCALE_IMAGE( TYPE ) \
993 const TYPE *src = (const TYPE *)srcImage; \
994 TYPE *dst = (TYPE *)dstImage; \
996 if ( srcHeight <= dstHeight ) { \
997 const GLint hScale = dstHeight / srcHeight; \
998 if ( srcWidth <= dstWidth ) { \
999 const GLint wScale = dstWidth / srcWidth; \
1000 INNER_LOOP( TYPE, /, / ); \
1003 const GLint wScale = srcWidth / dstWidth; \
1004 INNER_LOOP( TYPE, /, * ); \
1008 const GLint hScale = srcHeight / dstHeight; \
1009 if ( srcWidth <= dstWidth ) { \
1010 const GLint wScale = dstWidth / srcWidth; \
1011 INNER_LOOP( TYPE, *, / ); \
1014 const GLint wScale = srcWidth / dstWidth; \
1015 INNER_LOOP( TYPE, *, * ); \
1020 switch ( bytesPerPixel
) {
1022 RESCALE_IMAGE( GLuint
);
1026 RESCALE_IMAGE( GLushort
);
1030 RESCALE_IMAGE( GLubyte
);
1033 _mesa_problem(NULL
,"unexpected bytes/pixel in _mesa_rescale_teximage2d");