~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/extras/Mesa/src/texutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Mesa 3-D graphics library
 
4
 * Version:  4.0.3
 
5
 *
 
6
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
 
7
 *
 
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:
 
14
 *
 
15
 * The above copyright notice and this permission notice shall be included
 
16
 * in all copies or substantial portions of the Software.
 
17
 *
 
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.
 
24
 *
 
25
 * Authors:
 
26
 *    Gareth Hughes <gareth@valinux.com>
 
27
 */
 
28
 
 
29
/*
 
30
 * Description:
 
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.
 
34
 */
 
35
 
 
36
 
 
37
#ifdef PC_HEADER
 
38
#include "all.h"
 
39
#else
 
40
#include "glheader.h"
 
41
#include "context.h"
 
42
#include "enums.h"
 
43
#include "image.h"
 
44
#include "macros.h"
 
45
#include "mem.h"
 
46
#include "mtypes.h"
 
47
#include "texformat.h"
 
48
#include "texutil.h"
 
49
#endif
 
50
 
 
51
#define DEBUG_TEXUTIL 0
 
52
 
 
53
 
 
54
#ifdef MESA_BIG_ENDIAN
 
55
#define APPEND16( a, b )        ( (a) << 16 | (b) )
 
56
#else
 
57
#define APPEND16( a, b )        ( (a) | (b) << 16 )
 
58
#endif
 
59
 
 
60
 
 
61
struct convert_info {
 
62
   GLint xoffset, yoffset, zoffset;     /* Subimage offset */
 
63
   GLint width, height, depth;          /* Subimage region */
 
64
 
 
65
   GLint dstImageWidth, dstImageHeight; /* Dest image size */
 
66
                                        /* Needed for subimage replacement */
 
67
   GLenum format, type;                 /* Source (user) format and type */
 
68
 
 
69
   const struct gl_pixelstore_attrib *unpacking;
 
70
 
 
71
   const GLvoid *srcImage;
 
72
   GLvoid *dstImage;
 
73
 
 
74
   GLint index;
 
75
};
 
76
 
 
77
typedef GLboolean (*convert_func)( const struct convert_info *convert );
 
78
 
 
79
/* bitvalues for convert->index */
 
80
#define CONVERT_STRIDE_BIT      0x1
 
81
#define CONVERT_UNPACKING_BIT   0x2
 
82
 
 
83
 
 
84
 
 
85
/* =============================================================
 
86
 * Convert to RGBA8888 textures:
 
87
 */
 
88
 
 
89
#define DST_TYPE                GLuint
 
90
#define DST_TEXELS_PER_DWORD    1
 
91
 
 
92
#define CONVERT_TEXEL( dst, src )                                       \
 
93
        dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
 
94
 
 
95
#define CONVERT_DIRECT
 
96
 
 
97
#define SRC_TEXEL_BYTES         4
 
98
 
 
99
#define TAG(x) x##_rgba8888_direct
 
100
#define PRESERVE_DST_TYPE
 
101
#include "texutil_tmp.h"
 
102
 
 
103
 
 
104
#define CONVERT_TEXEL( dst, src )                                       \
 
105
        dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
 
106
 
 
107
#define CONVERT_TEXEL_DWORD( dst, src )         CONVERT_TEXEL( dst, src )
 
108
 
 
109
#define SRC_TEXEL_BYTES         4
 
110
 
 
111
#define TAG(x) x##_abgr8888_to_rgba8888
 
112
#define PRESERVE_DST_TYPE
 
113
#include "texutil_tmp.h"
 
114
 
 
115
 
 
116
#define CONVERT_TEXEL( dst, src )                                       \
 
117
        dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
 
118
 
 
119
#define CONVERT_TEXEL_DWORD( dst, src )         CONVERT_TEXEL( dst, src )
 
120
 
 
121
#define SRC_TEXEL_BYTES         3
 
122
 
 
123
#define TAG(x) x##_bgr888_to_rgba8888
 
124
#include "texutil_tmp.h"
 
125
 
 
126
 
 
127
#define CONVERT_RGBA8888( name )                                        \
 
128
static GLboolean                                                        \
 
129
convert_##name##_rgba8888( const struct convert_info *convert )         \
 
130
{                                                                       \
 
131
   convert_func *tab;                                                   \
 
132
   GLint index = convert->index;                                        \
 
133
                                                                        \
 
134
   if ( convert->format == GL_ABGR_EXT &&                               \
 
135
        convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )                  \
 
136
   {                                                                    \
 
137
      tab = name##_tab_rgba8888_direct;                                 \
 
138
   }                                                                    \
 
139
   else if ( convert->format == GL_RGBA &&                              \
 
140
             ( convert->type == GL_UNSIGNED_BYTE ||                     \
 
141
               convert->type == GL_UNSIGNED_INT_8_8_8_8 ) )             \
 
142
   {                                                                    \
 
143
      tab = name##_tab_abgr8888_to_rgba8888;                            \
 
144
   }                                                                    \
 
145
   else if ( convert->format == GL_RGB &&                               \
 
146
             convert->type == GL_UNSIGNED_BYTE )                        \
 
147
   {                                                                    \
 
148
      tab = name##_tab_bgr888_to_rgba8888;                              \
 
149
   }                                                                    \
 
150
   else                                                                 \
 
151
   {                                                                    \
 
152
      /* Can't handle this source format/type combination */            \
 
153
      return GL_FALSE;                                                  \
 
154
   }                                                                    \
 
155
                                                                        \
 
156
   return tab[index]( convert );                                        \
 
157
}
 
158
 
 
159
CONVERT_RGBA8888( texsubimage2d )
 
160
CONVERT_RGBA8888( texsubimage3d )
 
161
 
 
162
 
 
163
 
 
164
/* =============================================================
 
165
 * Convert to ARGB8888 textures:
 
166
 */
 
167
 
 
168
#define DST_TYPE                GLuint
 
169
#define DST_TEXELS_PER_DWORD    1
 
170
 
 
171
#define CONVERT_TEXEL( dst, src )                                       \
 
172
        dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
 
173
 
 
174
#define CONVERT_DIRECT
 
175
 
 
176
#define SRC_TEXEL_BYTES         4
 
177
 
 
178
#define TAG(x) x##_argb8888_direct
 
179
#define PRESERVE_DST_TYPE
 
180
#include "texutil_tmp.h"
 
181
 
 
182
 
 
183
#define CONVERT_TEXEL( dst, src )                                       \
 
184
        dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
 
185
 
 
186
#define CONVERT_TEXEL_DWORD( dst, src )         CONVERT_TEXEL( dst, src )
 
187
 
 
188
#define SRC_TEXEL_BYTES         4
 
189
 
 
190
#define TAG(x) x##_abgr8888_to_argb8888
 
191
#define PRESERVE_DST_TYPE
 
192
#include "texutil_tmp.h"
 
193
 
 
194
 
 
195
#define CONVERT_TEXEL( dst, src )                                       \
 
196
        dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
 
197
 
 
198
#define CONVERT_TEXEL_DWORD( dst, src )         CONVERT_TEXEL( dst, src )
 
199
 
 
200
#define SRC_TEXEL_BYTES         3
 
201
 
 
202
#define TAG(x) x##_bgr888_to_argb8888
 
203
#include "texutil_tmp.h"
 
204
 
 
205
 
 
206
#define CONVERT_ARGB8888( name )                                        \
 
207
static GLboolean                                                        \
 
208
convert_##name##_argb8888( const struct convert_info *convert )         \
 
209
{                                                                       \
 
210
   convert_func *tab;                                                   \
 
211
   GLint index = convert->index;                                        \
 
212
                                                                        \
 
213
   if ( convert->format == GL_BGRA &&                                   \
 
214
        convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )                  \
 
215
   {                                                                    \
 
216
      tab = name##_tab_argb8888_direct;                                 \
 
217
   }                                                                    \
 
218
   else if ( convert->format == GL_RGBA &&                              \
 
219
             convert->type == GL_UNSIGNED_BYTE )                        \
 
220
   {                                                                    \
 
221
      tab = name##_tab_abgr8888_to_argb8888;                            \
 
222
   }                                                                    \
 
223
   else if ( convert->format == GL_RGB &&                               \
 
224
             convert->type == GL_UNSIGNED_BYTE )                        \
 
225
   {                                                                    \
 
226
      tab = name##_tab_bgr888_to_argb8888;                              \
 
227
   }                                                                    \
 
228
   else                                                                 \
 
229
   {                                                                    \
 
230
      /* Can't handle this source format/type combination */            \
 
231
      return GL_FALSE;                                                  \
 
232
   }                                                                    \
 
233
                                                                        \
 
234
   return tab[index]( convert );                                        \
 
235
}
 
236
 
 
237
CONVERT_ARGB8888( texsubimage2d )
 
238
CONVERT_ARGB8888( texsubimage3d )
 
239
 
 
240
 
 
241
 
 
242
/* =============================================================
 
243
 * Convert to RGB888 textures:
 
244
 */
 
245
 
 
246
static GLboolean
 
247
convert_texsubimage2d_rgb888( const struct convert_info *convert )
 
248
{
 
249
   /* This is a placeholder for now...
 
250
    */
 
251
   return GL_FALSE;
 
252
}
 
253
 
 
254
static GLboolean
 
255
convert_texsubimage3d_rgb888( const struct convert_info *convert )
 
256
{
 
257
   /* This is a placeholder for now...
 
258
    */
 
259
   return GL_FALSE;
 
260
}
 
261
 
 
262
 
 
263
 
 
264
/* =============================================================
 
265
 * Convert to RGB565 textures:
 
266
 */
 
267
 
 
268
#define DST_TYPE                GLushort
 
269
#define DST_TEXELS_PER_DWORD    2
 
270
 
 
271
#define CONVERT_TEXEL( dst, src )                                       \
 
272
        dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
273
 
 
274
#define CONVERT_DIRECT
 
275
 
 
276
#define SRC_TEXEL_BYTES         2
 
277
 
 
278
#define TAG(x) x##_rgb565_direct
 
279
#define PRESERVE_DST_TYPE
 
280
#include "texutil_tmp.h"
 
281
 
 
282
 
 
283
#define CONVERT_TEXEL( dst, src )                                       \
 
284
        dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
285
 
 
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] ) )
 
289
 
 
290
#define SRC_TEXEL_BYTES         3
 
291
 
 
292
#define TAG(x) x##_bgr888_to_rgb565
 
293
#define PRESERVE_DST_TYPE
 
294
#include "texutil_tmp.h"
 
295
 
 
296
 
 
297
#define CONVERT_TEXEL( dst, src )                                       \
 
298
        dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
 
299
 
 
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] ) )
 
303
 
 
304
#define SRC_TEXEL_BYTES         4
 
305
 
 
306
#define TAG(x) x##_abgr8888_to_rgb565
 
307
#include "texutil_tmp.h"
 
308
 
 
309
 
 
310
#define CONVERT_RGB565( name )                                          \
 
311
static GLboolean                                                        \
 
312
convert_##name##_rgb565( const struct convert_info *convert )           \
 
313
{                                                                       \
 
314
   convert_func *tab;                                                   \
 
315
   GLint index = convert->index;                                        \
 
316
                                                                        \
 
317
   if ( convert->format == GL_RGB &&                                    \
 
318
        convert->type == GL_UNSIGNED_SHORT_5_6_5 )                      \
 
319
   {                                                                    \
 
320
      tab = name##_tab_rgb565_direct;                                   \
 
321
   }                                                                    \
 
322
   else if ( convert->format == GL_RGB &&                               \
 
323
             convert->type == GL_UNSIGNED_BYTE )                        \
 
324
   {                                                                    \
 
325
      tab = name##_tab_bgr888_to_rgb565;                                \
 
326
   }                                                                    \
 
327
   else if ( convert->format == GL_RGBA &&                              \
 
328
             convert->type == GL_UNSIGNED_BYTE )                        \
 
329
   {                                                                    \
 
330
      tab = name##_tab_abgr8888_to_rgb565;                              \
 
331
   }                                                                    \
 
332
   else                                                                 \
 
333
   {                                                                    \
 
334
      /* Can't handle this source format/type combination */            \
 
335
      return GL_FALSE;                                                  \
 
336
   }                                                                    \
 
337
                                                                        \
 
338
   return tab[index]( convert );                                        \
 
339
}
 
340
 
 
341
CONVERT_RGB565( texsubimage2d )
 
342
CONVERT_RGB565( texsubimage3d )
 
343
 
 
344
 
 
345
 
 
346
/* =============================================================
 
347
 * Convert to ARGB4444 textures:
 
348
 */
 
349
 
 
350
#define DST_TYPE                GLushort
 
351
#define DST_TEXELS_PER_DWORD    2
 
352
 
 
353
#define CONVERT_TEXEL( dst, src )                                       \
 
354
        dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
 
355
 
 
356
#define CONVERT_DIRECT
 
357
 
 
358
#define SRC_TEXEL_BYTES         2
 
359
 
 
360
#define TAG(x) x##_argb4444_direct
 
361
#define PRESERVE_DST_TYPE
 
362
#include "texutil_tmp.h"
 
363
 
 
364
 
 
365
#define CONVERT_TEXEL( dst, src )                                       \
 
366
        dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
 
367
 
 
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] ) )
 
371
 
 
372
#define SRC_TEXEL_BYTES         4
 
373
 
 
374
#define TAG(x) x##_abgr8888_to_argb4444
 
375
#include "texutil_tmp.h"
 
376
 
 
377
 
 
378
#define CONVERT_ARGB4444( name )                                        \
 
379
static GLboolean                                                        \
 
380
convert_##name##_argb4444( const struct convert_info *convert )         \
 
381
{                                                                       \
 
382
   convert_func *tab;                                                   \
 
383
   GLint index = convert->index;                                        \
 
384
                                                                        \
 
385
   if ( convert->format == GL_BGRA &&                                   \
 
386
        convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV )                \
 
387
   {                                                                    \
 
388
      tab = name##_tab_argb4444_direct;                                 \
 
389
   }                                                                    \
 
390
   else if ( convert->format == GL_RGBA &&                              \
 
391
             convert->type == GL_UNSIGNED_BYTE )                        \
 
392
   {                                                                    \
 
393
      tab = name##_tab_abgr8888_to_argb4444;                            \
 
394
   }                                                                    \
 
395
   else                                                                 \
 
396
   {                                                                    \
 
397
      /* Can't handle this source format/type combination */            \
 
398
      return GL_FALSE;                                                  \
 
399
   }                                                                    \
 
400
                                                                        \
 
401
   return tab[index]( convert );                                        \
 
402
}
 
403
 
 
404
CONVERT_ARGB4444( texsubimage2d )
 
405
CONVERT_ARGB4444( texsubimage3d )
 
406
 
 
407
 
 
408
 
 
409
/* =============================================================
 
410
 * Convert to ARGB1555 textures:
 
411
 */
 
412
 
 
413
#define DST_TYPE                GLushort
 
414
#define DST_TEXELS_PER_DWORD    2
 
415
 
 
416
#define CONVERT_TEXEL( dst, src )                                       \
 
417
        dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
 
418
 
 
419
#define CONVERT_DIRECT
 
420
 
 
421
#define SRC_TEXEL_BYTES         2
 
422
 
 
423
#define TAG(x) x##_argb1555_direct
 
424
#define PRESERVE_DST_TYPE
 
425
#include "texutil_tmp.h"
 
426
 
 
427
 
 
428
#ifdef MESA_BIG_ENDIAN
 
429
 
 
430
#define CONVERT_TEXEL( dst, src )                                       \
 
431
        { const GLushort s = *(GLushort *)src;                          \
 
432
          dst = (s >> 9) | ((s & 0x1ff) << 7); }
 
433
 
 
434
#define CONVERT_TEXEL_DWORD( dst, src )                                 \
 
435
        { const GLuint s = ((fi_type *)src)->i;                         \
 
436
          dst = (((s & 0xfe00fe00) >> 9) |                              \
 
437
                 ((s & 0x01ff01ff) << 7)); }
 
438
 
 
439
#else
 
440
 
 
441
#define CONVERT_TEXEL( dst, src )                                       \
 
442
        { const GLushort s = *(GLushort *)src;                          \
 
443
          dst = (s >> 1) | ((s & 1) << 15); }
 
444
 
 
445
#define CONVERT_TEXEL_DWORD( dst, src )                                 \
 
446
        { const GLuint s = ((fi_type *)src)->i;                         \
 
447
          dst = (((s & 0xfffefffe) >> 1) |                              \
 
448
                 ((s & 0x00010001) << 15)); }
 
449
 
 
450
#endif
 
451
 
 
452
#define SRC_TEXEL_BYTES         2
 
453
 
 
454
#define TAG(x) x##_rgba5551_to_argb1555
 
455
#define PRESERVE_DST_TYPE
 
456
#include "texutil_tmp.h"
 
457
 
 
458
 
 
459
#define CONVERT_TEXEL( dst, src )                                       \
 
460
        dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
 
461
 
 
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] ) )
 
465
 
 
466
#define SRC_TEXEL_BYTES         4
 
467
 
 
468
#define TAG(x) x##_abgr8888_to_argb1555
 
469
#include "texutil_tmp.h"
 
470
 
 
471
 
 
472
#define CONVERT_ARGB1555( name )                                        \
 
473
static GLboolean                                                        \
 
474
convert_##name##_argb1555( const struct convert_info *convert )         \
 
475
{                                                                       \
 
476
   convert_func *tab;                                                   \
 
477
   GLint index = convert->index;                                        \
 
478
                                                                        \
 
479
   if ( convert->format == GL_BGRA &&                                   \
 
480
        convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV )                \
 
481
   {                                                                    \
 
482
      tab = name##_tab_argb1555_direct;                                 \
 
483
   }                                                                    \
 
484
   else if ( convert->format == GL_RGBA &&                              \
 
485
             convert->type == GL_UNSIGNED_SHORT_5_5_5_1 )               \
 
486
   {                                                                    \
 
487
      tab = name##_tab_rgba5551_to_argb1555;                            \
 
488
   }                                                                    \
 
489
   else if ( convert->format == GL_RGBA &&                              \
 
490
             convert->type == GL_UNSIGNED_BYTE )                        \
 
491
   {                                                                    \
 
492
      tab = name##_tab_abgr8888_to_argb1555;                            \
 
493
   }                                                                    \
 
494
   else                                                                 \
 
495
   {                                                                    \
 
496
      /* Can't handle this source format/type combination */            \
 
497
      return GL_FALSE;                                                  \
 
498
   }                                                                    \
 
499
                                                                        \
 
500
   return tab[index]( convert );                                        \
 
501
}
 
502
 
 
503
CONVERT_ARGB1555( texsubimage2d )
 
504
CONVERT_ARGB1555( texsubimage3d )
 
505
 
 
506
 
 
507
 
 
508
/* =============================================================
 
509
 * Conver to AL88 textures:
 
510
 */
 
511
 
 
512
#define DST_TYPE                GLushort
 
513
#define DST_TEXELS_PER_DWORD    2
 
514
 
 
515
#define CONVERT_TEXEL( dst, src )                                       \
 
516
        dst = PACK_COLOR_88_LE( src[0], src[1] )
 
517
 
 
518
#define CONVERT_DIRECT
 
519
 
 
520
#define SRC_TEXEL_BYTES         2
 
521
 
 
522
#define TAG(x) x##_al88_direct
 
523
#define PRESERVE_DST_TYPE
 
524
#include "texutil_tmp.h"
 
525
 
 
526
 
 
527
#define CONVERT_TEXEL( dst, src )                                       \
 
528
        dst = PACK_COLOR_88_LE( src[0], 0x00 )
 
529
 
 
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 ) )
 
533
 
 
534
#define SRC_TEXEL_BYTES         1
 
535
 
 
536
#define TAG(x) x##_a8_to_al88
 
537
#define PRESERVE_DST_TYPE
 
538
#include "texutil_tmp.h"
 
539
 
 
540
 
 
541
#define CONVERT_TEXEL( dst, src )                                       \
 
542
        dst = PACK_COLOR_88_LE( 0xff, src[0] )
 
543
 
 
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] ) )
 
547
 
 
548
#define SRC_TEXEL_BYTES         1
 
549
 
 
550
#define TAG(x) x##_l8_to_al88
 
551
#define PRESERVE_DST_TYPE
 
552
#include "texutil_tmp.h"
 
553
 
 
554
 
 
555
#define CONVERT_TEXEL( dst, src )                                       \
 
556
        dst = PACK_COLOR_88_LE( src[3], src[0] )
 
557
 
 
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] ) )
 
561
 
 
562
#define SRC_TEXEL_BYTES         4
 
563
 
 
564
#define TAG(x) x##_abgr8888_to_al88
 
565
#include "texutil_tmp.h"
 
566
 
 
567
 
 
568
#define CONVERT_AL88( name )                                            \
 
569
static GLboolean                                                        \
 
570
convert_##name##_al88( const struct convert_info *convert )             \
 
571
{                                                                       \
 
572
   convert_func *tab;                                                   \
 
573
   GLint index = convert->index;                                        \
 
574
                                                                        \
 
575
   if ( convert->format == GL_LUMINANCE_ALPHA &&                        \
 
576
        convert->type == GL_UNSIGNED_BYTE )                             \
 
577
   {                                                                    \
 
578
      tab = name##_tab_al88_direct;                                     \
 
579
   }                                                                    \
 
580
   else if ( convert->format == GL_ALPHA &&                             \
 
581
             convert->type == GL_UNSIGNED_BYTE )                        \
 
582
   {                                                                    \
 
583
      tab = name##_tab_a8_to_al88;                                      \
 
584
   }                                                                    \
 
585
   else if ( convert->format == GL_LUMINANCE &&                         \
 
586
             convert->type == GL_UNSIGNED_BYTE )                        \
 
587
   {                                                                    \
 
588
      tab = name##_tab_l8_to_al88;                                      \
 
589
   }                                                                    \
 
590
   else if ( convert->format == GL_RGBA &&                              \
 
591
             convert->type == GL_UNSIGNED_BYTE )                        \
 
592
   {                                                                    \
 
593
      tab = name##_tab_abgr8888_to_al88;                                \
 
594
   }                                                                    \
 
595
   else                                                                 \
 
596
   {                                                                    \
 
597
      /* Can't handle this source format/type combination */            \
 
598
      return GL_FALSE;                                                  \
 
599
   }                                                                    \
 
600
                                                                        \
 
601
   return tab[index]( convert );                                        \
 
602
}
 
603
 
 
604
CONVERT_AL88( texsubimage2d )
 
605
CONVERT_AL88( texsubimage3d )
 
606
 
 
607
 
 
608
 
 
609
/* =============================================================
 
610
 * Convert to RGB332 textures:
 
611
 */
 
612
 
 
613
static GLboolean
 
614
convert_texsubimage2d_rgb332( const struct convert_info *convert )
 
615
{
 
616
   /* This is a placeholder for now...
 
617
    */
 
618
   return GL_FALSE;
 
619
}
 
620
 
 
621
static GLboolean
 
622
convert_texsubimage3d_rgb332( const struct convert_info *convert )
 
623
{
 
624
   /* This is a placeholder for now...
 
625
    */
 
626
   return GL_FALSE;
 
627
}
 
628
 
 
629
 
 
630
 
 
631
/* =============================================================
 
632
 * Convert to CI8 (and all other single-byte texel) textures:
 
633
 */
 
634
 
 
635
#define DST_TYPE                GLubyte
 
636
#define DST_TEXELS_PER_DWORD    4
 
637
 
 
638
#define CONVERT_TEXEL( dst, src )       dst = src[0]
 
639
 
 
640
#define CONVERT_DIRECT
 
641
 
 
642
#define SRC_TEXEL_BYTES         1
 
643
 
 
644
#define TAG(x) x##_ci8_direct
 
645
#include "texutil_tmp.h"
 
646
 
 
647
 
 
648
#define CONVERT_CI8( name )                                             \
 
649
static GLboolean                                                        \
 
650
convert_##name##_ci8( const struct convert_info *convert )              \
 
651
{                                                                       \
 
652
   convert_func *tab;                                                   \
 
653
   GLint index = convert->index;                                        \
 
654
                                                                        \
 
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 )                             \
 
660
   {                                                                    \
 
661
      tab = name##_tab_ci8_direct;                                      \
 
662
   }                                                                    \
 
663
   else                                                                 \
 
664
   {                                                                    \
 
665
      /* Can't handle this source format/type combination */            \
 
666
      return GL_FALSE;                                                  \
 
667
   }                                                                    \
 
668
                                                                        \
 
669
   return tab[index]( convert );                                        \
 
670
}
 
671
 
 
672
CONVERT_CI8( texsubimage2d )
 
673
CONVERT_CI8( texsubimage3d )
 
674
 
 
675
 
 
676
/* =============================================================
 
677
 * convert to YCBCR textures:
 
678
 */
 
679
 
 
680
#define DST_TYPE                GLushort
 
681
#define DST_TEXELS_PER_DWORD    2
 
682
 
 
683
#define CONVERT_TEXEL( dst, src ) \
 
684
   dst = (src[0] << 8) | src[1];
 
685
 
 
686
#define CONVERT_DIRECT
 
687
 
 
688
#define SRC_TEXEL_BYTES         2
 
689
 
 
690
#define TAG(x) x##_ycbcr_direct
 
691
#include "texutil_tmp.h"
 
692
 
 
693
 
 
694
#define CONVERT_YCBCR( name )                                           \
 
695
static GLboolean                                                        \
 
696
convert_##name##_ycbcr( const struct convert_info *convert )            \
 
697
{                                                                       \
 
698
   convert_func *tab;                                                   \
 
699
   GLint index = convert->index;                                        \
 
700
                                                                        \
 
701
   if (convert->format != GL_YCBCR_MESA) {                              \
 
702
      /* Can't handle this source format/type combination */            \
 
703
      return GL_FALSE;                                                  \
 
704
   }                                                                    \
 
705
   tab = name##_tab_ycbcr_direct;                                       \
 
706
                                                                        \
 
707
   return tab[index]( convert );                                        \
 
708
}
 
709
 
 
710
CONVERT_YCBCR( texsubimage2d )
 
711
CONVERT_YCBCR( texsubimage3d )
 
712
 
 
713
 
 
714
/* =============================================================
 
715
 * convert to YCBCR_REV textures:
 
716
 */
 
717
 
 
718
#define DST_TYPE                GLushort
 
719
#define DST_TEXELS_PER_DWORD    2
 
720
 
 
721
#define CONVERT_TEXEL( dst, src ) \
 
722
   dst = (src[1] << 8) | src[0];
 
723
 
 
724
#define CONVERT_DIRECT
 
725
 
 
726
#define SRC_TEXEL_BYTES         2
 
727
 
 
728
#define TAG(x) x##_ycbcr_rev_direct
 
729
#include "texutil_tmp.h"
 
730
 
 
731
 
 
732
#define CONVERT_YCBCR_REV( name )                                       \
 
733
static GLboolean                                                        \
 
734
convert_##name##_ycbcr_rev( const struct convert_info *convert )        \
 
735
{                                                                       \
 
736
   convert_func *tab;                                                   \
 
737
   GLint index = convert->index;                                        \
 
738
                                                                        \
 
739
   if (convert->format != GL_YCBCR_MESA) {                              \
 
740
      /* Can't handle this source format/type combination */            \
 
741
      return GL_FALSE;                                                  \
 
742
   }                                                                    \
 
743
   tab = name##_tab_ycbcr_rev_direct;                                   \
 
744
                                                                        \
 
745
   return tab[index]( convert );                                        \
 
746
}
 
747
 
 
748
CONVERT_YCBCR_REV( texsubimage2d )
 
749
CONVERT_YCBCR_REV( texsubimage3d )
 
750
 
 
751
 
 
752
 
 
753
/* =============================================================
 
754
 * Tables of texture conversion/packing functions.
 
755
 */
 
756
 
 
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,
 
772
};
 
773
 
 
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,
 
789
};
 
790
 
 
791
 
 
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...
 
796
 */
 
797
static INLINE GLboolean
 
798
convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
 
799
                       GLenum format, GLenum type )
 
800
{
 
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 ) {
 
811
      return GL_FALSE;
 
812
   } else {
 
813
      return GL_TRUE;
 
814
   }
 
815
}
 
816
 
 
817
 
 
818
GLboolean
 
819
_mesa_convert_texsubimage1d( GLint mesaFormat,  /* dest */
 
820
                             GLint xoffset,
 
821
                             GLint width,
 
822
                             GLenum format, GLenum type,  /* source */
 
823
                             const struct gl_pixelstore_attrib *unpacking,
 
824
                             const GLvoid *srcImage, GLvoid *dstImage )
 
825
{
 
826
   struct convert_info convert;
 
827
 
 
828
   ASSERT( unpacking );
 
829
   ASSERT( srcImage );
 
830
   ASSERT( dstImage );
 
831
 
 
832
   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
 
833
   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
834
 
 
835
   /* Make it easier to pass all the parameters around.
 
836
    */
 
837
   convert.xoffset = xoffset;
 
838
   convert.yoffset = 0;
 
839
   convert.width = width;
 
840
   convert.height = 1;
 
841
   convert.format = format;
 
842
   convert.type = type;
 
843
   convert.unpacking = unpacking;
 
844
   convert.srcImage = srcImage;
 
845
   convert.dstImage = dstImage;
 
846
 
 
847
   convert.index = 0;
 
848
 
 
849
   if ( convert_needs_unpacking( unpacking, format, type ) )
 
850
      convert.index |= CONVERT_UNPACKING_BIT;
 
851
 
 
852
   ASSERT(convert.index < 4);
 
853
 
 
854
   return convert_texsubimage2d_table[mesaFormat]( &convert );
 
855
}
 
856
 
 
857
 
 
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.
 
861
 *
 
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.
 
866
 *
 
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.
 
872
 *
 
873
 * Input:
 
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
 
882
 */
 
883
GLboolean
 
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 )
 
891
{
 
892
   struct convert_info convert;
 
893
 
 
894
   ASSERT( unpacking );
 
895
   ASSERT( srcImage );
 
896
   ASSERT( dstImage );
 
897
 
 
898
   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
 
899
   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
900
 
 
901
   /* Make it easier to pass all the parameters around.
 
902
    */
 
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;
 
913
 
 
914
   convert.index = 0;
 
915
 
 
916
   if ( convert_needs_unpacking( unpacking, format, type ) )
 
917
      convert.index |= CONVERT_UNPACKING_BIT;
 
918
 
 
919
   if ( width != destImageWidth )
 
920
      convert.index |= CONVERT_STRIDE_BIT;
 
921
 
 
922
   ASSERT(convert.index < 4);
 
923
 
 
924
   ASSERT(mesaFormat < sizeof(convert_texsubimage2d_table) /
 
925
                       sizeof(convert_texsubimage2d_table[0]));
 
926
 
 
927
   return convert_texsubimage2d_table[mesaFormat]( &convert );
 
928
}
 
929
 
 
930
GLboolean
 
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 )
 
938
{
 
939
   struct convert_info convert;
 
940
 
 
941
   ASSERT( unpacking );
 
942
   ASSERT( srcImage );
 
943
   ASSERT( dstImage );
 
944
 
 
945
   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
 
946
   ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
 
947
 
 
948
   /* Make it easier to pass all the parameters around.
 
949
    */
 
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;
 
959
   convert.type = type;
 
960
   convert.unpacking = unpacking;
 
961
   convert.srcImage = srcImage;
 
962
   convert.dstImage = dstImage;
 
963
 
 
964
   convert.index = 0;
 
965
 
 
966
   if ( convert_needs_unpacking( unpacking, format, type ) )
 
967
      convert.index |= CONVERT_UNPACKING_BIT;
 
968
 
 
969
   if ( width != dstImageWidth || height != dstImageHeight )
 
970
      convert.index |= CONVERT_STRIDE_BIT;
 
971
 
 
972
   ASSERT(convert.index < 4);
 
973
 
 
974
   return convert_texsubimage3d_table[mesaFormat]( &convert );
 
975
}
 
976
 
 
977
 
 
978
 
 
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...
 
982
 */
 
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 )
 
987
{
 
988
   GLint row, col;
 
989
 
 
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];                    \
 
996
      }                                                                 \
 
997
      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);                  \
 
998
   }                                                                    \
 
999
 
 
1000
#define RESCALE_IMAGE( TYPE )                                           \
 
1001
do {                                                                    \
 
1002
   const TYPE *src = (const TYPE *)srcImage;                            \
 
1003
   TYPE *dst = (TYPE *)dstImage;                                        \
 
1004
                                                                        \
 
1005
   if ( srcHeight <= dstHeight ) {                                      \
 
1006
      const GLint hScale = dstHeight / srcHeight;                       \
 
1007
      if ( srcWidth <= dstWidth ) {                                     \
 
1008
         const GLint wScale = dstWidth / srcWidth;                      \
 
1009
         INNER_LOOP( TYPE, /, / );                                      \
 
1010
      }                                                                 \
 
1011
      else {                                                            \
 
1012
         const GLint wScale = srcWidth / dstWidth;                      \
 
1013
         INNER_LOOP( TYPE, /, * );                                      \
 
1014
      }                                                                 \
 
1015
   }                                                                    \
 
1016
   else {                                                               \
 
1017
      const GLint hScale = srcHeight / dstHeight;                       \
 
1018
      if ( srcWidth <= dstWidth ) {                                     \
 
1019
         const GLint wScale = dstWidth / srcWidth;                      \
 
1020
         INNER_LOOP( TYPE, *, / );                                      \
 
1021
      }                                                                 \
 
1022
      else {                                                            \
 
1023
         const GLint wScale = srcWidth / dstWidth;                      \
 
1024
         INNER_LOOP( TYPE, *, * );                                      \
 
1025
      }                                                                 \
 
1026
   }                                                                    \
 
1027
} while (0)
 
1028
 
 
1029
   switch ( bytesPerPixel ) {
 
1030
   case 4:
 
1031
      RESCALE_IMAGE( GLuint );
 
1032
      break;
 
1033
 
 
1034
   case 2:
 
1035
      RESCALE_IMAGE( GLushort );
 
1036
      break;
 
1037
 
 
1038
   case 1:
 
1039
      RESCALE_IMAGE( GLubyte );
 
1040
      break;
 
1041
   default:
 
1042
      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
 
1043
   }
 
1044
}