1 /**************************************************************************
3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
6 **************************************************************************/
10 * Code to convert compressed/paletted texture images to ordinary images.
11 * See the GL_OES_compressed_paletted_texture spec at
12 * http://khronos.org/registry/gles/extensions/OES/OES_compressed_paletted_texture.txt
14 * XXX this makes it impossible to add hardware support...
19 #include "GLES/glext.h"
21 #include "main/compiler.h" /* for ASSERT */
24 void GL_APIENTRY
_es_CompressedTexImage2DARB(GLenum target
, GLint level
, GLenum internalFormat
, GLsizei width
, GLsizei height
, GLint border
, GLsizei imageSize
, const GLvoid
*data
);
26 void GL_APIENTRY
_mesa_GetIntegerv(GLenum pname
, GLint
*params
);
27 void GL_APIENTRY
_mesa_PixelStorei(GLenum pname
, GLint param
);
28 void GL_APIENTRY
_mesa_TexImage2D(GLenum target
, GLint level
, GLint internalFormat
, GLsizei width
, GLsizei height
, GLint border
, GLenum format
, GLenum type
, const GLvoid
*pixels
);
29 void GL_APIENTRY
_mesa_CompressedTexImage2DARB(GLenum target
, GLint level
, GLenum internalFormat
, GLsizei width
, GLsizei height
, GLint border
, GLsizei imageSize
, const GLvoid
*data
);
31 void *_mesa_get_current_context(void);
32 void _mesa_error(void *ctx
, GLenum error
, const char *fmtString
, ... );
35 static const struct cpal_format_info
{
42 { GL_PALETTE4_RGB8_OES
, GL_RGB
, GL_UNSIGNED_BYTE
, 16, 3 },
43 { GL_PALETTE4_RGBA8_OES
, GL_RGBA
, GL_UNSIGNED_BYTE
, 16, 4 },
44 { GL_PALETTE4_R5_G6_B5_OES
, GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
, 16, 2 },
45 { GL_PALETTE4_RGBA4_OES
, GL_RGBA
, GL_UNSIGNED_SHORT_4_4_4_4
, 16, 2 },
46 { GL_PALETTE4_RGB5_A1_OES
, GL_RGBA
, GL_UNSIGNED_SHORT_5_5_5_1
, 16, 2 },
47 { GL_PALETTE8_RGB8_OES
, GL_RGB
, GL_UNSIGNED_BYTE
, 256, 3 },
48 { GL_PALETTE8_RGBA8_OES
, GL_RGBA
, GL_UNSIGNED_BYTE
, 256, 4 },
49 { GL_PALETTE8_R5_G6_B5_OES
, GL_RGB
, GL_UNSIGNED_SHORT_5_6_5
, 256, 2 },
50 { GL_PALETTE8_RGBA4_OES
, GL_RGBA
, GL_UNSIGNED_SHORT_4_4_4_4
, 256, 2 },
51 { GL_PALETTE8_RGB5_A1_OES
, GL_RGBA
, GL_UNSIGNED_SHORT_5_5_5_1
, 256, 2 }
56 * Get a color/entry from the palette.
59 get_palette_entry(const struct cpal_format_info
*info
, const GLubyte
*palette
,
60 GLuint index
, GLubyte
*pixel
)
62 memcpy(pixel
, palette
+ info
->size
* index
, info
->size
);
68 * Convert paletted texture to color texture.
71 paletted_to_color(const struct cpal_format_info
*info
, const GLubyte
*palette
,
72 const void *indices
, GLuint num_pixels
, GLubyte
*image
)
77 if (info
->palette_size
== 16) {
78 /* 4 bits per index */
79 const GLubyte
*ind
= (const GLubyte
*) indices
;
81 /* two pixels per iteration */
82 remain
= num_pixels
% 2;
83 for (i
= 0; i
< num_pixels
/ 2; i
++) {
84 pix
+= get_palette_entry(info
, palette
, (ind
[i
] >> 4) & 0xf, pix
);
85 pix
+= get_palette_entry(info
, palette
, ind
[i
] & 0xf, pix
);
88 get_palette_entry(info
, palette
, (ind
[i
] >> 4) & 0xf, pix
);
92 /* 8 bits per index */
93 const GLubyte
*ind
= (const GLubyte
*) indices
;
94 for (i
= 0; i
< num_pixels
; i
++)
95 pix
+= get_palette_entry(info
, palette
, ind
[i
], pix
);
100 static const struct cpal_format_info
*
101 cpal_get_info(GLint level
, GLenum internalFormat
,
102 GLsizei width
, GLsizei height
, GLsizei imageSize
)
104 const struct cpal_format_info
*info
;
105 GLint lvl
, num_levels
;
106 GLsizei w
, h
, expect_size
;
108 info
= &formats
[internalFormat
- GL_PALETTE4_RGB8_OES
];
109 ASSERT(info
->cpal_format
== internalFormat
);
112 _mesa_error(_mesa_get_current_context(), GL_INVALID_VALUE
,
113 "glCompressedTexImage2D(level=%d)", level
);
117 num_levels
= -level
+ 1;
118 expect_size
= info
->palette_size
* info
->size
;
119 for (lvl
= 0; lvl
< num_levels
; lvl
++) {
127 if (info
->palette_size
== 16)
128 expect_size
+= (w
* h
+ 1) / 2;
130 expect_size
+= w
* h
;
132 if (expect_size
> imageSize
) {
133 _mesa_error(_mesa_get_current_context(), GL_INVALID_VALUE
,
134 "glCompressedTexImage2D(imageSize=%d)", imageSize
);
141 * Convert a call to glCompressedTexImage2D() where internalFormat is a
142 * compressed palette format into a regular GLubyte/RGBA glTexImage2D() call.
145 cpal_compressed_teximage2d(GLenum target
, GLint level
, GLenum internalFormat
,
146 GLsizei width
, GLsizei height
, GLsizei imageSize
,
149 const struct cpal_format_info
*info
;
150 GLint lvl
, num_levels
;
151 const GLubyte
*indices
;
152 GLint saved_align
, align
;
154 info
= cpal_get_info(level
, internalFormat
, width
, height
, imageSize
);
158 info
= &formats
[internalFormat
- GL_PALETTE4_RGB8_OES
];
159 ASSERT(info
->cpal_format
== internalFormat
);
160 num_levels
= -level
+ 1;
162 /* first image follows the palette */
163 indices
= (const GLubyte
*) palette
+ info
->palette_size
* info
->size
;
165 _mesa_GetIntegerv(GL_UNPACK_ALIGNMENT
, &saved_align
);
168 for (lvl
= 0; lvl
< num_levels
; lvl
++) {
171 GLubyte
*image
= NULL
;
180 if (w
* info
->size
% align
) {
181 _mesa_PixelStorei(GL_UNPACK_ALIGNMENT
, 1);
185 /* allocate and fill dest image buffer */
187 image
= (GLubyte
*) malloc(num_texels
* info
->size
);
188 paletted_to_color(info
, palette
, indices
, num_texels
, image
);
191 _mesa_TexImage2D(target
, lvl
, info
->format
, w
, h
, 0,
192 info
->format
, info
->type
, image
);
196 /* advance index pointer to point to next src mipmap */
197 if (info
->palette_size
== 16)
198 indices
+= (num_texels
+ 1) / 2;
200 indices
+= num_texels
;
203 if (saved_align
!= align
)
204 _mesa_PixelStorei(GL_UNPACK_ALIGNMENT
, saved_align
);
209 _es_CompressedTexImage2DARB(GLenum target
, GLint level
, GLenum internalFormat
,
210 GLsizei width
, GLsizei height
, GLint border
,
211 GLsizei imageSize
, const GLvoid
*data
)
213 switch (internalFormat
) {
214 case GL_PALETTE4_RGB8_OES
:
215 case GL_PALETTE4_RGBA8_OES
:
216 case GL_PALETTE4_R5_G6_B5_OES
:
217 case GL_PALETTE4_RGBA4_OES
:
218 case GL_PALETTE4_RGB5_A1_OES
:
219 case GL_PALETTE8_RGB8_OES
:
220 case GL_PALETTE8_RGBA8_OES
:
221 case GL_PALETTE8_R5_G6_B5_OES
:
222 case GL_PALETTE8_RGBA4_OES
:
223 case GL_PALETTE8_RGB5_A1_OES
:
224 cpal_compressed_teximage2d(target
, level
, internalFormat
,
225 width
, height
, imageSize
, data
);
228 _mesa_CompressedTexImage2DARB(target
, level
, internalFormat
,
229 width
, height
, border
, imageSize
, data
);