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