3
* Mesa 3-D graphics library
6
* Copyright (C) 1999-2002 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.
26
* Gareth Hughes <gareth@valinux.com>
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.
47
#include "texformat.h"
51
#define DEBUG_TEXUTIL 0
54
#ifdef MESA_BIG_ENDIAN
55
#define APPEND16( a, b ) ( (a) << 16 | (b) )
57
#define APPEND16( a, b ) ( (a) | (b) << 16 )
62
GLint xoffset, yoffset, zoffset; /* Subimage offset */
63
GLint width, height, depth; /* Subimage region */
65
GLint dstImageWidth, dstImageHeight; /* Dest image size */
66
/* Needed for subimage replacement */
67
GLenum format, type; /* Source (user) format and type */
69
const struct gl_pixelstore_attrib *unpacking;
71
const GLvoid *srcImage;
77
typedef GLboolean (*convert_func)( const struct convert_info *convert );
79
/* bitvalues for convert->index */
80
#define CONVERT_STRIDE_BIT 0x1
81
#define CONVERT_UNPACKING_BIT 0x2
85
/* =============================================================
86
* Convert to RGBA8888 textures:
89
#define DST_TYPE GLuint
90
#define DST_TEXELS_PER_DWORD 1
92
#define CONVERT_TEXEL( dst, src ) \
93
dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
95
#define CONVERT_DIRECT
97
#define SRC_TEXEL_BYTES 4
99
#define TAG(x) x##_rgba8888_direct
100
#define PRESERVE_DST_TYPE
101
#include "texutil_tmp.h"
104
#define CONVERT_TEXEL( dst, src ) \
105
dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
107
#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
109
#define SRC_TEXEL_BYTES 4
111
#define TAG(x) x##_abgr8888_to_rgba8888
112
#define PRESERVE_DST_TYPE
113
#include "texutil_tmp.h"
116
#define CONVERT_TEXEL( dst, src ) \
117
dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
119
#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
121
#define SRC_TEXEL_BYTES 3
123
#define TAG(x) x##_bgr888_to_rgba8888
124
#include "texutil_tmp.h"
127
#define CONVERT_RGBA8888( name ) \
129
convert_##name##_rgba8888( const struct convert_info *convert ) \
132
GLint index = convert->index; \
134
if ( convert->format == GL_ABGR_EXT && \
135
convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
137
tab = name##_tab_rgba8888_direct; \
139
else if ( convert->format == GL_RGBA && \
140
( convert->type == GL_UNSIGNED_BYTE || \
141
convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
143
tab = name##_tab_abgr8888_to_rgba8888; \
145
else if ( convert->format == GL_RGB && \
146
convert->type == GL_UNSIGNED_BYTE ) \
148
tab = name##_tab_bgr888_to_rgba8888; \
152
/* Can't handle this source format/type combination */ \
156
return tab[index]( convert ); \
159
CONVERT_RGBA8888( texsubimage2d )
160
CONVERT_RGBA8888( texsubimage3d )
164
/* =============================================================
165
* Convert to ARGB8888 textures:
168
#define DST_TYPE GLuint
169
#define DST_TEXELS_PER_DWORD 1
171
#define CONVERT_TEXEL( dst, src ) \
172
dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
174
#define CONVERT_DIRECT
176
#define SRC_TEXEL_BYTES 4
178
#define TAG(x) x##_argb8888_direct
179
#define PRESERVE_DST_TYPE
180
#include "texutil_tmp.h"
183
#define CONVERT_TEXEL( dst, src ) \
184
dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
186
#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
188
#define SRC_TEXEL_BYTES 4
190
#define TAG(x) x##_abgr8888_to_argb8888
191
#define PRESERVE_DST_TYPE
192
#include "texutil_tmp.h"
195
#define CONVERT_TEXEL( dst, src ) \
196
dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
198
#define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
200
#define SRC_TEXEL_BYTES 3
202
#define TAG(x) x##_bgr888_to_argb8888
203
#include "texutil_tmp.h"
206
#define CONVERT_ARGB8888( name ) \
208
convert_##name##_argb8888( const struct convert_info *convert ) \
211
GLint index = convert->index; \
213
if ( convert->format == GL_BGRA && \
214
convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
216
tab = name##_tab_argb8888_direct; \
218
else if ( convert->format == GL_RGBA && \
219
convert->type == GL_UNSIGNED_BYTE ) \
221
tab = name##_tab_abgr8888_to_argb8888; \
223
else if ( convert->format == GL_RGB && \
224
convert->type == GL_UNSIGNED_BYTE ) \
226
tab = name##_tab_bgr888_to_argb8888; \
230
/* Can't handle this source format/type combination */ \
234
return tab[index]( convert ); \
237
CONVERT_ARGB8888( texsubimage2d )
238
CONVERT_ARGB8888( texsubimage3d )
242
/* =============================================================
243
* Convert to RGB888 textures:
247
convert_texsubimage2d_rgb888( const struct convert_info *convert )
249
/* This is a placeholder for now...
255
convert_texsubimage3d_rgb888( const struct convert_info *convert )
257
/* This is a placeholder for now...
264
/* =============================================================
265
* Convert to RGB565 textures:
268
#define DST_TYPE GLushort
269
#define DST_TEXELS_PER_DWORD 2
271
#define CONVERT_TEXEL( dst, src ) \
272
dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
274
#define CONVERT_DIRECT
276
#define SRC_TEXEL_BYTES 2
278
#define TAG(x) x##_rgb565_direct
279
#define PRESERVE_DST_TYPE
280
#include "texutil_tmp.h"
283
#define CONVERT_TEXEL( dst, src ) \
284
dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
286
#define CONVERT_TEXEL_DWORD( dst, src ) \
287
dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
288
PACK_COLOR_565_LE( src[3], src[4], src[5] ) )
290
#define SRC_TEXEL_BYTES 3
292
#define TAG(x) x##_bgr888_to_rgb565
293
#define PRESERVE_DST_TYPE
294
#include "texutil_tmp.h"
297
#define CONVERT_TEXEL( dst, src ) \
298
dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
300
#define CONVERT_TEXEL_DWORD( dst, src ) \
301
dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
302
PACK_COLOR_565_LE( src[4], src[5], src[6] ) )
304
#define SRC_TEXEL_BYTES 4
306
#define TAG(x) x##_abgr8888_to_rgb565
307
#include "texutil_tmp.h"
310
#define CONVERT_RGB565( name ) \
312
convert_##name##_rgb565( const struct convert_info *convert ) \
315
GLint index = convert->index; \
317
if ( convert->format == GL_RGB && \
318
convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
320
tab = name##_tab_rgb565_direct; \
322
else if ( convert->format == GL_RGB && \
323
convert->type == GL_UNSIGNED_BYTE ) \
325
tab = name##_tab_bgr888_to_rgb565; \
327
else if ( convert->format == GL_RGBA && \
328
convert->type == GL_UNSIGNED_BYTE ) \
330
tab = name##_tab_abgr8888_to_rgb565; \
334
/* Can't handle this source format/type combination */ \
338
return tab[index]( convert ); \
341
CONVERT_RGB565( texsubimage2d )
342
CONVERT_RGB565( texsubimage3d )
346
/* =============================================================
347
* Convert to ARGB4444 textures:
350
#define DST_TYPE GLushort
351
#define DST_TEXELS_PER_DWORD 2
353
#define CONVERT_TEXEL( dst, src ) \
354
dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
356
#define CONVERT_DIRECT
358
#define SRC_TEXEL_BYTES 2
360
#define TAG(x) x##_argb4444_direct
361
#define PRESERVE_DST_TYPE
362
#include "texutil_tmp.h"
365
#define CONVERT_TEXEL( dst, src ) \
366
dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
368
#define CONVERT_TEXEL_DWORD( dst, src ) \
369
dst = APPEND16( PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] ), \
370
PACK_COLOR_4444_LE( src[7], src[4], src[5], src[6] ) )
372
#define SRC_TEXEL_BYTES 4
374
#define TAG(x) x##_abgr8888_to_argb4444
375
#include "texutil_tmp.h"
378
#define CONVERT_ARGB4444( name ) \
380
convert_##name##_argb4444( const struct convert_info *convert ) \
383
GLint index = convert->index; \
385
if ( convert->format == GL_BGRA && \
386
convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
388
tab = name##_tab_argb4444_direct; \
390
else if ( convert->format == GL_RGBA && \
391
convert->type == GL_UNSIGNED_BYTE ) \
393
tab = name##_tab_abgr8888_to_argb4444; \
397
/* Can't handle this source format/type combination */ \
401
return tab[index]( convert ); \
404
CONVERT_ARGB4444( texsubimage2d )
405
CONVERT_ARGB4444( texsubimage3d )
409
/* =============================================================
410
* Convert to ARGB1555 textures:
413
#define DST_TYPE GLushort
414
#define DST_TEXELS_PER_DWORD 2
416
#define CONVERT_TEXEL( dst, src ) \
417
dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
419
#define CONVERT_DIRECT
421
#define SRC_TEXEL_BYTES 2
423
#define TAG(x) x##_argb1555_direct
424
#define PRESERVE_DST_TYPE
425
#include "texutil_tmp.h"
428
#ifdef MESA_BIG_ENDIAN
430
#define CONVERT_TEXEL( dst, src ) \
431
{ const GLushort s = *(GLushort *)src; \
432
dst = (s >> 9) | ((s & 0x1ff) << 7); }
434
#define CONVERT_TEXEL_DWORD( dst, src ) \
435
{ const GLuint s = ((fi_type *)src)->i; \
436
dst = (((s & 0xfe00fe00) >> 9) | \
437
((s & 0x01ff01ff) << 7)); }
441
#define CONVERT_TEXEL( dst, src ) \
442
{ const GLushort s = *(GLushort *)src; \
443
dst = (s >> 1) | ((s & 1) << 15); }
445
#define CONVERT_TEXEL_DWORD( dst, src ) \
446
{ const GLuint s = ((fi_type *)src)->i; \
447
dst = (((s & 0xfffefffe) >> 1) | \
448
((s & 0x00010001) << 15)); }
452
#define SRC_TEXEL_BYTES 2
454
#define TAG(x) x##_rgba5551_to_argb1555
455
#define PRESERVE_DST_TYPE
456
#include "texutil_tmp.h"
459
#define CONVERT_TEXEL( dst, src ) \
460
dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
462
#define CONVERT_TEXEL_DWORD( dst, src ) \
463
dst = APPEND16( PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] ), \
464
PACK_COLOR_1555_LE( src[7], src[4], src[5], src[6] ) )
466
#define SRC_TEXEL_BYTES 4
468
#define TAG(x) x##_abgr8888_to_argb1555
469
#include "texutil_tmp.h"
472
#define CONVERT_ARGB1555( name ) \
474
convert_##name##_argb1555( const struct convert_info *convert ) \
477
GLint index = convert->index; \
479
if ( convert->format == GL_BGRA && \
480
convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
482
tab = name##_tab_argb1555_direct; \
484
else if ( convert->format == GL_RGBA && \
485
convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \
487
tab = name##_tab_rgba5551_to_argb1555; \
489
else if ( convert->format == GL_RGBA && \
490
convert->type == GL_UNSIGNED_BYTE ) \
492
tab = name##_tab_abgr8888_to_argb1555; \
496
/* Can't handle this source format/type combination */ \
500
return tab[index]( convert ); \
503
CONVERT_ARGB1555( texsubimage2d )
504
CONVERT_ARGB1555( texsubimage3d )
508
/* =============================================================
509
* Conver to AL88 textures:
512
#define DST_TYPE GLushort
513
#define DST_TEXELS_PER_DWORD 2
515
#define CONVERT_TEXEL( dst, src ) \
516
dst = PACK_COLOR_88_LE( src[0], src[1] )
518
#define CONVERT_DIRECT
520
#define SRC_TEXEL_BYTES 2
522
#define TAG(x) x##_al88_direct
523
#define PRESERVE_DST_TYPE
524
#include "texutil_tmp.h"
527
#define CONVERT_TEXEL( dst, src ) \
528
dst = PACK_COLOR_88_LE( src[0], 0x00 )
530
#define CONVERT_TEXEL_DWORD( dst, src ) \
531
dst = APPEND16( PACK_COLOR_88_LE( src[0], 0x00 ), \
532
PACK_COLOR_88_LE( src[1], 0x00 ) )
534
#define SRC_TEXEL_BYTES 1
536
#define TAG(x) x##_a8_to_al88
537
#define PRESERVE_DST_TYPE
538
#include "texutil_tmp.h"
541
#define CONVERT_TEXEL( dst, src ) \
542
dst = PACK_COLOR_88_LE( 0xff, src[0] )
544
#define CONVERT_TEXEL_DWORD( dst, src ) \
545
dst = APPEND16( PACK_COLOR_88_LE( 0xff, src[0] ), \
546
PACK_COLOR_88_LE( 0xff, src[1] ) )
548
#define SRC_TEXEL_BYTES 1
550
#define TAG(x) x##_l8_to_al88
551
#define PRESERVE_DST_TYPE
552
#include "texutil_tmp.h"
555
#define CONVERT_TEXEL( dst, src ) \
556
dst = PACK_COLOR_88_LE( src[3], src[0] )
558
#define CONVERT_TEXEL_DWORD( dst, src ) \
559
dst = APPEND16( PACK_COLOR_88_LE( src[3], src[0] ), \
560
PACK_COLOR_88_LE( src[7], src[4] ) )
562
#define SRC_TEXEL_BYTES 4
564
#define TAG(x) x##_abgr8888_to_al88
565
#include "texutil_tmp.h"
568
#define CONVERT_AL88( name ) \
570
convert_##name##_al88( const struct convert_info *convert ) \
573
GLint index = convert->index; \
575
if ( convert->format == GL_LUMINANCE_ALPHA && \
576
convert->type == GL_UNSIGNED_BYTE ) \
578
tab = name##_tab_al88_direct; \
580
else if ( convert->format == GL_ALPHA && \
581
convert->type == GL_UNSIGNED_BYTE ) \
583
tab = name##_tab_a8_to_al88; \
585
else if ( convert->format == GL_LUMINANCE && \
586
convert->type == GL_UNSIGNED_BYTE ) \
588
tab = name##_tab_l8_to_al88; \
590
else if ( convert->format == GL_RGBA && \
591
convert->type == GL_UNSIGNED_BYTE ) \
593
tab = name##_tab_abgr8888_to_al88; \
597
/* Can't handle this source format/type combination */ \
601
return tab[index]( convert ); \
604
CONVERT_AL88( texsubimage2d )
605
CONVERT_AL88( texsubimage3d )
609
/* =============================================================
610
* Convert to RGB332 textures:
614
convert_texsubimage2d_rgb332( const struct convert_info *convert )
616
/* This is a placeholder for now...
622
convert_texsubimage3d_rgb332( const struct convert_info *convert )
624
/* This is a placeholder for now...
631
/* =============================================================
632
* Convert to CI8 (and all other single-byte texel) textures:
635
#define DST_TYPE GLubyte
636
#define DST_TEXELS_PER_DWORD 4
638
#define CONVERT_TEXEL( dst, src ) dst = src[0]
640
#define CONVERT_DIRECT
642
#define SRC_TEXEL_BYTES 1
644
#define TAG(x) x##_ci8_direct
645
#include "texutil_tmp.h"
648
#define CONVERT_CI8( name ) \
650
convert_##name##_ci8( const struct convert_info *convert ) \
653
GLint index = convert->index; \
655
if ( ( convert->format == GL_ALPHA || \
656
convert->format == GL_LUMINANCE || \
657
convert->format == GL_INTENSITY || \
658
convert->format == GL_COLOR_INDEX ) && \
659
convert->type == GL_UNSIGNED_BYTE ) \
661
tab = name##_tab_ci8_direct; \
665
/* Can't handle this source format/type combination */ \
669
return tab[index]( convert ); \
672
CONVERT_CI8( texsubimage2d )
673
CONVERT_CI8( texsubimage3d )
676
/* =============================================================
677
* convert to YCBCR textures:
680
#define DST_TYPE GLushort
681
#define DST_TEXELS_PER_DWORD 2
683
#define CONVERT_TEXEL( dst, src ) \
684
dst = (src[0] << 8) | src[1];
686
#define CONVERT_DIRECT
688
#define SRC_TEXEL_BYTES 2
690
#define TAG(x) x##_ycbcr_direct
691
#include "texutil_tmp.h"
694
#define CONVERT_YCBCR( name ) \
696
convert_##name##_ycbcr( const struct convert_info *convert ) \
699
GLint index = convert->index; \
701
if (convert->format != GL_YCBCR_MESA) { \
702
/* Can't handle this source format/type combination */ \
705
tab = name##_tab_ycbcr_direct; \
707
return tab[index]( convert ); \
710
CONVERT_YCBCR( texsubimage2d )
711
CONVERT_YCBCR( texsubimage3d )
714
/* =============================================================
715
* convert to YCBCR_REV textures:
718
#define DST_TYPE GLushort
719
#define DST_TEXELS_PER_DWORD 2
721
#define CONVERT_TEXEL( dst, src ) \
722
dst = (src[1] << 8) | src[0];
724
#define CONVERT_DIRECT
726
#define SRC_TEXEL_BYTES 2
728
#define TAG(x) x##_ycbcr_rev_direct
729
#include "texutil_tmp.h"
732
#define CONVERT_YCBCR_REV( name ) \
734
convert_##name##_ycbcr_rev( const struct convert_info *convert ) \
737
GLint index = convert->index; \
739
if (convert->format != GL_YCBCR_MESA) { \
740
/* Can't handle this source format/type combination */ \
743
tab = name##_tab_ycbcr_rev_direct; \
745
return tab[index]( convert ); \
748
CONVERT_YCBCR_REV( texsubimage2d )
749
CONVERT_YCBCR_REV( texsubimage3d )
753
/* =============================================================
754
* Tables of texture conversion/packing functions.
757
static convert_func convert_texsubimage2d_table[] = {
758
convert_texsubimage2d_rgba8888,
759
convert_texsubimage2d_argb8888,
760
convert_texsubimage2d_rgb888,
761
convert_texsubimage2d_rgb565,
762
convert_texsubimage2d_argb4444,
763
convert_texsubimage2d_argb1555,
764
convert_texsubimage2d_al88,
765
convert_texsubimage2d_rgb332,
766
convert_texsubimage2d_ci8, /* These are all the same... */
767
convert_texsubimage2d_ci8,
768
convert_texsubimage2d_ci8,
769
convert_texsubimage2d_ci8,
770
convert_texsubimage2d_ycbcr,
771
convert_texsubimage2d_ycbcr_rev,
774
static convert_func convert_texsubimage3d_table[] = {
775
convert_texsubimage3d_rgba8888,
776
convert_texsubimage3d_argb8888,
777
convert_texsubimage3d_rgb888,
778
convert_texsubimage3d_rgb565,
779
convert_texsubimage3d_argb4444,
780
convert_texsubimage3d_argb1555,
781
convert_texsubimage3d_al88,
782
convert_texsubimage3d_rgb332,
783
convert_texsubimage3d_ci8, /* These are all the same... */
784
convert_texsubimage3d_ci8,
785
convert_texsubimage3d_ci8,
786
convert_texsubimage3d_ci8,
787
convert_texsubimage3d_ycbcr,
788
convert_texsubimage3d_ycbcr_rev,
792
/* See if we need to care about the pixel store attributes when we're
793
* converting the texture image. This should be stored as
794
* unpacking->_SomeBoolean and updated when the values change, to avoid
795
* testing every time...
797
static INLINE GLboolean
798
convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
799
GLenum format, GLenum type )
801
if ( ( unpacking->Alignment == 1 ||
802
( unpacking->Alignment == 4 && /* Pick up the common Q3A case... */
803
format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
804
unpacking->RowLength == 0 &&
805
unpacking->SkipPixels == 0 &&
806
unpacking->SkipRows == 0 &&
807
unpacking->ImageHeight == 0 &&
808
unpacking->SkipImages == 0 &&
809
unpacking->SwapBytes == GL_FALSE &&
810
unpacking->LsbFirst == GL_FALSE ) {
819
_mesa_convert_texsubimage1d( GLint mesaFormat, /* dest */
822
GLenum format, GLenum type, /* source */
823
const struct gl_pixelstore_attrib *unpacking,
824
const GLvoid *srcImage, GLvoid *dstImage )
826
struct convert_info convert;
832
ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
833
ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
835
/* Make it easier to pass all the parameters around.
837
convert.xoffset = xoffset;
839
convert.width = width;
841
convert.format = format;
843
convert.unpacking = unpacking;
844
convert.srcImage = srcImage;
845
convert.dstImage = dstImage;
849
if ( convert_needs_unpacking( unpacking, format, type ) )
850
convert.index |= CONVERT_UNPACKING_BIT;
852
ASSERT(convert.index < 4);
854
return convert_texsubimage2d_table[mesaFormat]( &convert );
858
/* Convert a user's 2D image into a texture image. This basically
859
* repacks pixel data into the special texture formats used by core Mesa
860
* and the DRI drivers. This function can do full images or subimages.
862
* We return a boolean because this function may not accept some kinds
863
* of source image formats and/or types. For example, if the incoming
864
* format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
865
* be able to do the conversion.
867
* In that case, the incoming image should first be simplified to one of
868
* the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
869
* GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
870
* with the _mesa_transfer_teximage() function. That function will also
871
* do image transfer operations such as scale/bias and convolution.
874
* mesaFormat - one of the MESA_FORMAT_* values from texformat.h
875
* xoffset, yoffset - position in dest image to put data
876
* width, height - incoming image size, also size of dest region.
877
* dstImageWidth - width (row stride) of dest image in pixels
878
* format, type - incoming image format and type
879
* unpacking - describes incoming image unpacking
880
* srcImage - pointer to source image
881
* destImage - pointer to dest image
884
_mesa_convert_texsubimage2d( GLint mesaFormat, /* dest */
885
GLint xoffset, GLint yoffset,
886
GLint width, GLint height,
887
GLint destImageWidth,
888
GLenum format, GLenum type, /* source */
889
const struct gl_pixelstore_attrib *unpacking,
890
const GLvoid *srcImage, GLvoid *dstImage )
892
struct convert_info convert;
898
ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
899
ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
901
/* Make it easier to pass all the parameters around.
903
convert.xoffset = xoffset;
904
convert.yoffset = yoffset;
905
convert.width = width;
906
convert.height = height;
907
convert.dstImageWidth = destImageWidth;
908
convert.format = format; /* src */
909
convert.type = type; /* src */
910
convert.unpacking = unpacking;
911
convert.srcImage = srcImage;
912
convert.dstImage = dstImage;
916
if ( convert_needs_unpacking( unpacking, format, type ) )
917
convert.index |= CONVERT_UNPACKING_BIT;
919
if ( width != destImageWidth )
920
convert.index |= CONVERT_STRIDE_BIT;
922
ASSERT(convert.index < 4);
924
ASSERT(mesaFormat < sizeof(convert_texsubimage2d_table) /
925
sizeof(convert_texsubimage2d_table[0]));
927
return convert_texsubimage2d_table[mesaFormat]( &convert );
931
_mesa_convert_texsubimage3d( GLint mesaFormat, /* dest */
932
GLint xoffset, GLint yoffset, GLint zoffset,
933
GLint width, GLint height, GLint depth,
934
GLint dstImageWidth, GLint dstImageHeight,
935
GLenum format, GLenum type, /* source */
936
const struct gl_pixelstore_attrib *unpacking,
937
const GLvoid *srcImage, GLvoid *dstImage )
939
struct convert_info convert;
945
ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
946
ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
948
/* Make it easier to pass all the parameters around.
950
convert.xoffset = xoffset;
951
convert.yoffset = yoffset;
952
convert.zoffset = zoffset;
953
convert.width = width;
954
convert.height = height;
955
convert.depth = depth;
956
convert.dstImageWidth = dstImageWidth;
957
convert.dstImageHeight = dstImageHeight;
958
convert.format = format;
960
convert.unpacking = unpacking;
961
convert.srcImage = srcImage;
962
convert.dstImage = dstImage;
966
if ( convert_needs_unpacking( unpacking, format, type ) )
967
convert.index |= CONVERT_UNPACKING_BIT;
969
if ( width != dstImageWidth || height != dstImageHeight )
970
convert.index |= CONVERT_STRIDE_BIT;
972
ASSERT(convert.index < 4);
974
return convert_texsubimage3d_table[mesaFormat]( &convert );
979
/* Nearest filtering only (for broken hardware that can't support
980
* all aspect ratios). This can be made a lot faster, but I don't
981
* really care enough...
983
void _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride,
984
GLint srcWidth, GLint srcHeight,
985
GLint dstWidth, GLint dstHeight,
986
const GLvoid *srcImage, GLvoid *dstImage )
990
#define INNER_LOOP( TYPE, HOP, WOP ) \
991
for ( row = 0 ; row < dstHeight ; row++ ) { \
992
GLint srcRow = row HOP hScale; \
993
for ( col = 0 ; col < dstWidth ; col++ ) { \
994
GLint srcCol = col WOP wScale; \
995
dst[col] = src[srcRow * srcWidth + srcCol]; \
997
dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \
1000
#define RESCALE_IMAGE( TYPE ) \
1002
const TYPE *src = (const TYPE *)srcImage; \
1003
TYPE *dst = (TYPE *)dstImage; \
1005
if ( srcHeight <= dstHeight ) { \
1006
const GLint hScale = dstHeight / srcHeight; \
1007
if ( srcWidth <= dstWidth ) { \
1008
const GLint wScale = dstWidth / srcWidth; \
1009
INNER_LOOP( TYPE, /, / ); \
1012
const GLint wScale = srcWidth / dstWidth; \
1013
INNER_LOOP( TYPE, /, * ); \
1017
const GLint hScale = srcHeight / dstHeight; \
1018
if ( srcWidth <= dstWidth ) { \
1019
const GLint wScale = dstWidth / srcWidth; \
1020
INNER_LOOP( TYPE, *, / ); \
1023
const GLint wScale = srcWidth / dstWidth; \
1024
INNER_LOOP( TYPE, *, * ); \
1029
switch ( bytesPerPixel ) {
1031
RESCALE_IMAGE( GLuint );
1035
RESCALE_IMAGE( GLushort );
1039
RESCALE_IMAGE( GLubyte );
1042
_mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");