1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.5.1
4  *
5  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6  * Copyright (c) 2008 VMware, Inc.
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 
26 
27 /**
28  * \file texcompress.c
29  * Helper functions for texture compression.
30  */
31 
32 
33 #include "glheader.h"
34 #include "imports.h"
35 #include "colormac.h"
36 #include "formats.h"
37 #include "mfeatures.h"
38 #include "mtypes.h"
39 #include "texcompress.h"
40 #include "texcompress_fxt1.h"
41 #include "texcompress_rgtc.h"
42 #include "texcompress_s3tc.h"
43 #include "texcompress_etc.h"
44 #include "swrast/s_context.h"
45 
46 
47 /**
48  * Get the GL base format of a specified GL compressed texture format
49  *
50  * From page 232 of the OpenGL 3.3 (Compatiblity Profile) spec:
51  *
52  *     "Compressed Internal Format      Base Internal Format    Type
53  *     ---------------------------     --------------------    ---------
54  *     COMPRESSED_ALPHA                ALPHA                   Generic
55  *     COMPRESSED_LUMINANCE            LUMINANCE               Generic
56  *     COMPRESSED_LUMINANCE_ALPHA      LUMINANCE_ALPHA         Generic
57  *     COMPRESSED_INTENSITY            INTENSITY               Generic
58  *     COMPRESSED_RED                  RED                     Generic
59  *     COMPRESSED_RG                   RG                      Generic
60  *     COMPRESSED_RGB                  RGB                     Generic
61  *     COMPRESSED_RGBA                 RGBA                    Generic
62  *     COMPRESSED_SRGB                 RGB                     Generic
63  *     COMPRESSED_SRGB_ALPHA           RGBA                    Generic
64  *     COMPRESSED_SLUMINANCE           LUMINANCE               Generic
65  *     COMPRESSED_SLUMINANCE_ALPHA     LUMINANCE_ALPHA         Generic
66  *     COMPRESSED_RED_RGTC1            RED                     Specific
67  *     COMPRESSED_SIGNED_RED_RGTC1     RED                     Specific
68  *     COMPRESSED_RG_RGTC2             RG                      Specific
69  *     COMPRESSED_SIGNED_RG_RGTC2      RG                      Specific"
70  *
71  * \return
72  * The base format of \c format if \c format is a compressed format (either
73  * generic or specific.  Otherwise 0 is returned.
74  */
75 GLenum
_mesa_gl_compressed_format_base_format(GLenum format)76 _mesa_gl_compressed_format_base_format(GLenum format)
77 {
78    switch (format) {
79    case GL_COMPRESSED_RED:
80    case GL_COMPRESSED_RED_RGTC1:
81    case GL_COMPRESSED_SIGNED_RED_RGTC1:
82       return GL_RED;
83 
84    case GL_COMPRESSED_RG:
85    case GL_COMPRESSED_RG_RGTC2:
86    case GL_COMPRESSED_SIGNED_RG_RGTC2:
87       return GL_RG;
88 
89    case GL_COMPRESSED_RGB:
90    case GL_COMPRESSED_SRGB:
91    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
92    case GL_COMPRESSED_RGB_FXT1_3DFX:
93    case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
94    case GL_ETC1_RGB8_OES:
95       return GL_RGB;
96 
97    case GL_COMPRESSED_RGBA:
98    case GL_COMPRESSED_SRGB_ALPHA:
99    case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
100    case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
101    case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
102    case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
103    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
104    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
105    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
106    case GL_COMPRESSED_RGBA_FXT1_3DFX:
107    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
108    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
109    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
110       return GL_RGBA;
111 
112    case GL_COMPRESSED_ALPHA:
113       return GL_ALPHA;
114 
115    case GL_COMPRESSED_LUMINANCE:
116    case GL_COMPRESSED_SLUMINANCE:
117    case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
118    case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
119       return GL_LUMINANCE;
120 
121    case GL_COMPRESSED_LUMINANCE_ALPHA:
122    case GL_COMPRESSED_SLUMINANCE_ALPHA:
123    case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
124    case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
125    case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
126       return GL_LUMINANCE_ALPHA;
127 
128    case GL_COMPRESSED_INTENSITY:
129       return GL_INTENSITY;
130 
131    default:
132       return 0;
133    }
134 }
135 
136 /**
137  * Return list of (and count of) all specific texture compression
138  * formats that are supported.
139  *
140  * Some formats are \b not returned by this function.  The
141  * \c GL_COMPRESSED_TEXTURE_FORMATS query only returns formats that are
142  * "suitable for general-purpose usage."  All texture compression extensions
143  * have taken this to mean either linear RGB or linear RGBA.
144  *
145  * The GL_ARB_texture_compress_rgtc spec says:
146  *
147  *    "19) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
148  *        GL_COMPRESSED_TEXTURE_FORMATS queries return the RGTC formats?
149  *
150  *        RESOLVED:  No.
151  *
152  *        The OpenGL 2.1 specification says "The only values returned
153  *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
154  *        corresponding to formats suitable for general-purpose usage.
155  *        The renderer will not enumerate formats with restrictions that
156  *        need to be specifically understood prior to use."
157  *
158  *        Compressed textures with just red or red-green components are
159  *        not general-purpose so should not be returned by these queries
160  *        because they have restrictions.
161  *
162  *        Applications that seek to use the RGTC formats should do so
163  *        by looking for this extension's name in the string returned by
164  *        glGetString(GL_EXTENSIONS) rather than
165  *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
166  *        GL_COMPRESSED_TEXTURE_FORMATS return."
167  *
168  * There is nearly identical wording in the GL_EXT_texture_compression_rgtc
169  * spec.
170  *
171  * The GL_EXT_texture_rRGB spec says:
172  *
173  *    "22) Should the new COMPRESSED_SRGB_* formats be listed in an
174  *        implementation's GL_COMPRESSED_TEXTURE_FORMATS list?
175  *
176  *        RESOLVED:  No.  Section 3.8.1 says formats listed by
177  *        GL_COMPRESSED_TEXTURE_FORMATS are "suitable for general-purpose
178  *        usage."  The non-linear distribution of red, green, and
179  *        blue for these sRGB compressed formats makes them not really
180  *        general-purpose."
181  *
182  * The GL_EXT_texture_compression_latc spec says:
183  *
184  *    "16) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
185  *        GL_COMPRESSED_TEXTURE_FORMATS queries return the LATC formats?
186  *
187  *        RESOLVED:  No.
188  *
189  *        The OpenGL 2.1 specification says "The only values returned
190  *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
191  *        corresponding to formats suitable for general-purpose usage.
192  *        The renderer will not enumerate formats with restrictions that
193  *        need to be specifically understood prior to use."
194  *
195  *        Historically, OpenGL implementation have advertised the RGB and
196  *        RGBA versions of the S3TC extensions compressed format tokens
197  *        through this mechanism.
198  *
199  *        The specification is not sufficiently clear about what "suitable
200  *        for general-purpose usage" means.  Historically that seems to mean
201  *        unsigned RGB or unsigned RGBA.  The DXT1 format supporting alpha
202  *        (GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) is not exposed in the list (at
203  *        least for NVIDIA drivers) because the alpha is always 1.0 expect
204  *        when it is 0.0 when RGB is required to be black.  NVIDIA's even
205  *        limits itself to true linear RGB or RGBA formats, specifically
206  *        not including EXT_texture_sRGB's sRGB S3TC compressed formats.
207  *
208  *        Adding luminance and luminance-alpha texture formats (and
209  *        certainly signed versions of luminance and luminance-alpha
210  *        formats!) invites potential comptaibility problems with old
211  *        applications using this mechanism since old applications are
212  *        unlikely to expect non-RGB or non-RGBA formats to be advertised
213  *        through this mechanism.  However no specific misinteractions
214  *        with old applications is known.
215  *
216  *        Applications that seek to use the LATC formats should do so
217  *        by looking for this extension's name in the string returned by
218  *        glGetString(GL_EXTENSIONS) rather than
219  *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
220  *        GL_COMPRESSED_TEXTURE_FORMATS return."
221  *
222  * There is no formal spec for GL_ATI_texture_compression_3dc.  Since the
223  * formats added by this extension are luminance-alpha formats, it is
224  * reasonable to expect them to follow the same rules as
225  * GL_EXT_texture_compression_latc.  At the very least, Catalyst 11.6 does not
226  * expose the 3dc formats through this mechanism.
227  *
228  * \param ctx  the GL context
229  * \param formats  the resulting format list (may be NULL).
230  *
231  * \return number of formats.
232  */
233 GLuint
_mesa_get_compressed_formats(struct gl_context * ctx,GLint * formats)234 _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats)
235 {
236    GLuint n = 0;
237    if (ctx->Extensions.TDFX_texture_compression_FXT1) {
238       if (formats) {
239          formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX;
240          formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX;
241       }
242       else {
243          n += 2;
244       }
245    }
246 
247    if (ctx->Extensions.EXT_texture_compression_s3tc) {
248       if (formats) {
249          formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
250          formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
251          formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
252       }
253       else {
254          n += 3;
255       }
256    }
257    if (ctx->Extensions.S3_s3tc) {
258       if (formats) {
259          formats[n++] = GL_RGB_S3TC;
260          formats[n++] = GL_RGB4_S3TC;
261          formats[n++] = GL_RGBA_S3TC;
262          formats[n++] = GL_RGBA4_S3TC;
263       }
264       else {
265          n += 4;
266       }
267    }
268 
269    if (ctx->Extensions.OES_compressed_ETC1_RGB8_texture) {
270       if (formats) {
271          formats[n++] = GL_ETC1_RGB8_OES;
272       }
273       else {
274          n += 1;
275       }
276    }
277 
278 #if FEATURE_ES1
279    if (ctx->API == API_OPENGLES) {
280       if (formats) {
281 	 formats[n++] = GL_PALETTE4_RGB8_OES;
282 	 formats[n++] = GL_PALETTE4_RGBA8_OES;
283 	 formats[n++] = GL_PALETTE4_R5_G6_B5_OES;
284 	 formats[n++] = GL_PALETTE4_RGBA4_OES;
285 	 formats[n++] = GL_PALETTE4_RGB5_A1_OES;
286 	 formats[n++] = GL_PALETTE8_RGB8_OES;
287 	 formats[n++] = GL_PALETTE8_RGBA8_OES;
288 	 formats[n++] = GL_PALETTE8_R5_G6_B5_OES;
289 	 formats[n++] = GL_PALETTE8_RGBA4_OES;
290 	 formats[n++] = GL_PALETTE8_RGB5_A1_OES;
291       }
292       else {
293 	 n += 10;
294       }
295    }
296 #endif
297 
298    return n;
299 }
300 
301 
302 /**
303  * Convert a compressed MESA_FORMAT_x to a GLenum.
304  */
305 gl_format
_mesa_glenum_to_compressed_format(GLenum format)306 _mesa_glenum_to_compressed_format(GLenum format)
307 {
308    switch (format) {
309    case GL_COMPRESSED_RGB_FXT1_3DFX:
310       return MESA_FORMAT_RGB_FXT1;
311    case GL_COMPRESSED_RGBA_FXT1_3DFX:
312       return MESA_FORMAT_RGBA_FXT1;
313 
314    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
315    case GL_RGB_S3TC:
316       return MESA_FORMAT_RGB_DXT1;
317    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
318    case GL_RGB4_S3TC:
319       return MESA_FORMAT_RGBA_DXT1;
320    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
321    case GL_RGBA_S3TC:
322       return MESA_FORMAT_RGBA_DXT3;
323    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
324    case GL_RGBA4_S3TC:
325       return MESA_FORMAT_RGBA_DXT5;
326 
327    case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
328       return MESA_FORMAT_SRGB_DXT1;
329    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
330       return MESA_FORMAT_SRGBA_DXT1;
331    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
332       return MESA_FORMAT_SRGBA_DXT3;
333    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
334       return MESA_FORMAT_SRGBA_DXT5;
335 
336    case GL_COMPRESSED_RED_RGTC1:
337       return MESA_FORMAT_RED_RGTC1;
338    case GL_COMPRESSED_SIGNED_RED_RGTC1:
339       return MESA_FORMAT_SIGNED_RED_RGTC1;
340    case GL_COMPRESSED_RG_RGTC2:
341       return MESA_FORMAT_RG_RGTC2;
342    case GL_COMPRESSED_SIGNED_RG_RGTC2:
343       return MESA_FORMAT_SIGNED_RG_RGTC2;
344 
345    case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
346       return MESA_FORMAT_L_LATC1;
347    case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
348       return MESA_FORMAT_SIGNED_L_LATC1;
349    case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
350    case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
351       return MESA_FORMAT_LA_LATC2;
352    case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
353       return MESA_FORMAT_SIGNED_LA_LATC2;
354 
355    case GL_ETC1_RGB8_OES:
356       return MESA_FORMAT_ETC1_RGB8;
357 
358    default:
359       return MESA_FORMAT_NONE;
360    }
361 }
362 
363 
364 /**
365  * Given a compressed MESA_FORMAT_x value, return the corresponding
366  * GLenum for that format.
367  * This is needed for glGetTexLevelParameter(GL_TEXTURE_INTERNAL_FORMAT)
368  * which must return the specific texture format used when the user might
369  * have originally specified a generic compressed format in their
370  * glTexImage2D() call.
371  * For non-compressed textures, we always return the user-specified
372  * internal format unchanged.
373  */
374 GLenum
_mesa_compressed_format_to_glenum(struct gl_context * ctx,gl_format mesaFormat)375 _mesa_compressed_format_to_glenum(struct gl_context *ctx, gl_format mesaFormat)
376 {
377    switch (mesaFormat) {
378 #if FEATURE_texture_fxt1
379    case MESA_FORMAT_RGB_FXT1:
380       return GL_COMPRESSED_RGB_FXT1_3DFX;
381    case MESA_FORMAT_RGBA_FXT1:
382       return GL_COMPRESSED_RGBA_FXT1_3DFX;
383 #endif
384 #if FEATURE_texture_s3tc
385    case MESA_FORMAT_RGB_DXT1:
386       return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
387    case MESA_FORMAT_RGBA_DXT1:
388       return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
389    case MESA_FORMAT_RGBA_DXT3:
390       return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
391    case MESA_FORMAT_RGBA_DXT5:
392       return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
393 #if FEATURE_EXT_texture_sRGB
394    case MESA_FORMAT_SRGB_DXT1:
395       return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
396    case MESA_FORMAT_SRGBA_DXT1:
397       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
398    case MESA_FORMAT_SRGBA_DXT3:
399       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
400    case MESA_FORMAT_SRGBA_DXT5:
401       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
402 #endif
403 #endif
404 
405    case MESA_FORMAT_RED_RGTC1:
406       return GL_COMPRESSED_RED_RGTC1;
407    case MESA_FORMAT_SIGNED_RED_RGTC1:
408       return GL_COMPRESSED_SIGNED_RED_RGTC1;
409    case MESA_FORMAT_RG_RGTC2:
410       return GL_COMPRESSED_RG_RGTC2;
411    case MESA_FORMAT_SIGNED_RG_RGTC2:
412       return GL_COMPRESSED_SIGNED_RG_RGTC2;
413 
414    case MESA_FORMAT_L_LATC1:
415       return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
416    case MESA_FORMAT_SIGNED_L_LATC1:
417       return GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT;
418    case MESA_FORMAT_LA_LATC2:
419       return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
420    case MESA_FORMAT_SIGNED_LA_LATC2:
421       return GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT;
422 
423    case MESA_FORMAT_ETC1_RGB8:
424       return GL_ETC1_RGB8_OES;
425 
426    default:
427       _mesa_problem(ctx, "Unexpected mesa texture format in"
428                     " _mesa_compressed_format_to_glenum()");
429       return 0;
430    }
431 }
432 
433 
434 /*
435  * Return the address of the pixel at (col, row, img) in a
436  * compressed texture image.
437  * \param col, row, img - image position (3D), should be a multiple of the
438  *                        format's block size.
439  * \param format - compressed image format
440  * \param width - image width (stride) in pixels
441  * \param image - the image address
442  * \return address of pixel at (row, col, img)
443  */
444 GLubyte *
_mesa_compressed_image_address(GLint col,GLint row,GLint img,gl_format mesaFormat,GLsizei width,const GLubyte * image)445 _mesa_compressed_image_address(GLint col, GLint row, GLint img,
446                                gl_format mesaFormat,
447                                GLsizei width, const GLubyte *image)
448 {
449    /* XXX only 2D images implemented, not 3D */
450    const GLuint blockSize = _mesa_get_format_bytes(mesaFormat);
451    GLuint bw, bh;
452    GLint offset;
453 
454    _mesa_get_format_block_size(mesaFormat, &bw, &bh);
455 
456    ASSERT(col % bw == 0);
457    ASSERT(row % bh == 0);
458 
459    offset = ((width + bw - 1) / bw) * (row / bh) + col / bw;
460    offset *= blockSize;
461 
462    return (GLubyte *) image + offset;
463 }
464 
465 
466 /**
467  * Decompress a compressed texture image, returning a GL_RGBA/GL_FLOAT image.
468  * \param srcRowStride  stride in bytes between rows of blocks in the
469  *                      compressed source image.
470  */
471 void
_mesa_decompress_image(gl_format format,GLuint width,GLuint height,const GLubyte * src,GLint srcRowStride,GLfloat * dest)472 _mesa_decompress_image(gl_format format, GLuint width, GLuint height,
473                        const GLubyte *src, GLint srcRowStride,
474                        GLfloat *dest)
475 {
476    void (*fetch)(const struct swrast_texture_image *texImage,
477                  GLint i, GLint j, GLint k, GLfloat *texel);
478    struct swrast_texture_image texImage;  /* dummy teximage */
479    GLuint i, j;
480    GLuint bytes, bw, bh;
481 
482    bytes = _mesa_get_format_bytes(format);
483    _mesa_get_format_block_size(format, &bw, &bh);
484 
485    /* setup dummy texture image info */
486    memset(&texImage, 0, sizeof(texImage));
487    texImage.Map = (void *) src;
488 
489    /* XXX This line is a bit of a hack to adapt to the row stride
490     * convention used by the texture decompression functions.
491     */
492    texImage.RowStride = srcRowStride * bh / bytes;
493 
494    switch (format) {
495    /* DXT formats */
496    case MESA_FORMAT_RGB_DXT1:
497       fetch = _mesa_fetch_texel_rgb_dxt1;
498       break;
499    case MESA_FORMAT_RGBA_DXT1:
500       fetch = _mesa_fetch_texel_rgba_dxt1;
501       break;
502    case MESA_FORMAT_RGBA_DXT3:
503       fetch = _mesa_fetch_texel_rgba_dxt3;
504       break;
505    case MESA_FORMAT_RGBA_DXT5:
506       fetch = _mesa_fetch_texel_rgba_dxt5;
507       break;
508 
509    /* FXT1 formats */
510    case MESA_FORMAT_RGB_FXT1:
511       fetch = _mesa_fetch_texel_2d_f_rgb_fxt1;
512       break;
513    case MESA_FORMAT_RGBA_FXT1:
514       fetch = _mesa_fetch_texel_2d_f_rgba_fxt1;
515       break;
516 
517    /* Red/RG formats */
518    case MESA_FORMAT_RED_RGTC1:
519       fetch = _mesa_fetch_texel_red_rgtc1;
520       break;
521    case MESA_FORMAT_SIGNED_RED_RGTC1:
522       fetch = _mesa_fetch_texel_signed_red_rgtc1;
523       break;
524    case MESA_FORMAT_RG_RGTC2:
525       fetch = _mesa_fetch_texel_rg_rgtc2;
526       break;
527    case MESA_FORMAT_SIGNED_RG_RGTC2:
528       fetch = _mesa_fetch_texel_signed_rg_rgtc2;
529       break;
530 
531    /* L/LA formats */
532    case MESA_FORMAT_L_LATC1:
533       fetch = _mesa_fetch_texel_l_latc1;
534       break;
535    case MESA_FORMAT_SIGNED_L_LATC1:
536       fetch = _mesa_fetch_texel_signed_l_latc1;
537       break;
538    case MESA_FORMAT_LA_LATC2:
539       fetch = _mesa_fetch_texel_la_latc2;
540       break;
541    case MESA_FORMAT_SIGNED_LA_LATC2:
542       fetch = _mesa_fetch_texel_signed_la_latc2;
543       break;
544 
545    /* ETC1 formats */
546    case MESA_FORMAT_ETC1_RGB8:
547       fetch = _mesa_fetch_texel_2d_f_etc1_rgb8;
548       break;
549 
550    default:
551       _mesa_problem(NULL, "Unexpected format in _mesa_decompress_image()");
552       return;
553    }
554 
555    for (j = 0; j < height; j++) {
556       for (i = 0; i < width; i++) {
557          fetch(&texImage, i, j, 0, dest);
558          dest += 4;
559       }
560    }
561 }
562