8 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
10 * Permission is hereby granted, free of charge, to any person obtaining a
11 * copy of this software and associated documentation files (the "Software"),
12 * to deal in the Software without restriction, including without limitation
13 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 * and/or sell copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following conditions:
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 #endif /* __REACTOS__ */
32 #define EXP5TO8R(packedcol) \
33 ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7))
35 #define EXP6TO8G(packedcol) \
36 ((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x3))
38 #define EXP5TO8B(packedcol) \
39 ((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x7))
41 #define EXP4TO8(col) \
42 ((col) | ((col) << 4))
44 /* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */
46 static void dxt135_decode_imageblock ( const GLubyte
*img_block_src
,
47 GLint i
, GLint j
, GLuint dxt_type
, GLvoid
*texel
) {
48 GLchan
*rgba
= (GLchan
*) texel
;
49 const GLushort color0
= img_block_src
[0] | (img_block_src
[1] << 8);
50 const GLushort color1
= img_block_src
[2] | (img_block_src
[3] << 8);
51 const GLuint bits
= img_block_src
[4] | (img_block_src
[5] << 8) |
52 (img_block_src
[6] << 16) | (img_block_src
[7] << 24);
53 /* What about big/little endian? */
54 GLubyte bit_pos
= 2 * (j
* 4 + i
) ;
55 GLubyte code
= (GLubyte
) ((bits
>> bit_pos
) & 3);
57 rgba
[ACOMP
] = CHAN_MAX
;
60 rgba
[RCOMP
] = UBYTE_TO_CHAN( EXP5TO8R(color0
) );
61 rgba
[GCOMP
] = UBYTE_TO_CHAN( EXP6TO8G(color0
) );
62 rgba
[BCOMP
] = UBYTE_TO_CHAN( EXP5TO8B(color0
) );
65 rgba
[RCOMP
] = UBYTE_TO_CHAN( EXP5TO8R(color1
) );
66 rgba
[GCOMP
] = UBYTE_TO_CHAN( EXP6TO8G(color1
) );
67 rgba
[BCOMP
] = UBYTE_TO_CHAN( EXP5TO8B(color1
) );
70 if ((dxt_type
> 1) || (color0
> color1
)) {
71 rgba
[RCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8R(color0
) * 2 + EXP5TO8R(color1
)) / 3) );
72 rgba
[GCOMP
] = UBYTE_TO_CHAN( ((EXP6TO8G(color0
) * 2 + EXP6TO8G(color1
)) / 3) );
73 rgba
[BCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8B(color0
) * 2 + EXP5TO8B(color1
)) / 3) );
76 rgba
[RCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8R(color0
) + EXP5TO8R(color1
)) / 2) );
77 rgba
[GCOMP
] = UBYTE_TO_CHAN( ((EXP6TO8G(color0
) + EXP6TO8G(color1
)) / 2) );
78 rgba
[BCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8B(color0
) + EXP5TO8B(color1
)) / 2) );
82 if ((dxt_type
> 1) || (color0
> color1
)) {
83 rgba
[RCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8R(color0
) + EXP5TO8R(color1
) * 2) / 3) );
84 rgba
[GCOMP
] = UBYTE_TO_CHAN( ((EXP6TO8G(color0
) + EXP6TO8G(color1
) * 2) / 3) );
85 rgba
[BCOMP
] = UBYTE_TO_CHAN( ((EXP5TO8B(color0
) + EXP5TO8B(color1
) * 2) / 3) );
91 if (dxt_type
== 1) rgba
[ACOMP
] = UBYTE_TO_CHAN(0);
95 /* CANNOT happen (I hope) */
101 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride
, const GLubyte
*pixdata
,
102 GLint i
, GLint j
, GLvoid
*texel
)
104 /* Extract the (i,j) pixel from pixdata and return it
105 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
108 const GLubyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 8);
109 dxt135_decode_imageblock(blksrc
, (i
&3), (j
&3), 0, texel
);
113 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride
, const GLubyte
*pixdata
,
114 GLint i
, GLint j
, GLvoid
*texel
)
116 /* Extract the (i,j) pixel from pixdata and return it
117 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
120 const GLubyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 8);
121 dxt135_decode_imageblock(blksrc
, (i
&3), (j
&3), 1, texel
);
124 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride
, const GLubyte
*pixdata
,
125 GLint i
, GLint j
, GLvoid
*texel
) {
127 /* Extract the (i,j) pixel from pixdata and return it
128 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
131 GLchan
*rgba
= (GLchan
*) texel
;
132 const GLubyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 16);
134 /* Simple 32bit version. */
135 /* that's pretty brain-dead for a single pixel, isn't it? */
136 const GLubyte bit_pos
= 4 * ((j
&3) * 4 + (i
&3));
137 const GLuint alpha_low
= blksrc
[0] | (blksrc
[1] << 8) | (blksrc
[2] << 16) | (blksrc
[3] << 24);
138 const GLuint alpha_high
= blksrc
[4] | (blksrc
[5] << 8) | (blksrc
[6] << 16) | (blksrc
[7] << 24);
140 dxt135_decode_imageblock(blksrc
+ 8, (i
&3), (j
&3), 2, texel
);
142 rgba
[ACOMP
] = UBYTE_TO_CHAN( (GLubyte
)(EXP4TO8((alpha_low
>> bit_pos
) & 15)) );
144 rgba
[ACOMP
] = UBYTE_TO_CHAN( (GLubyte
)(EXP4TO8((alpha_high
>> (bit_pos
- 32)) & 15)) );
147 /* TODO test this! */
148 const GLubyte anibble
= (blksrc
[((j
&3) * 4 + (i
&3)) / 2] >> (4 * (i
&1))) & 0xf;
149 dxt135_decode_imageblock(blksrc
+ 8, (i
&3), (j
&3), 2, texel
);
150 rgba
[ACOMP
] = UBYTE_TO_CHAN( (GLubyte
)(EXP4TO8(anibble
)) );
155 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride
, const GLubyte
*pixdata
,
156 GLint i
, GLint j
, GLvoid
*texel
) {
158 /* Extract the (i,j) pixel from pixdata and return it
159 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
162 GLchan
*rgba
= (GLchan
*) texel
;
163 const GLubyte
*blksrc
= (pixdata
+ ((srcRowStride
+ 3) / 4 * (j
/ 4) + (i
/ 4)) * 16);
164 const GLubyte alpha0
= blksrc
[0];
165 const GLubyte alpha1
= blksrc
[1];
167 const GLubyte bit_pos
= 3 * ((j
&3) * 4 + (i
&3));
168 /* simple 32bit version */
169 const GLuint bits_low
= blksrc
[2] | (blksrc
[3] << 8) | (blksrc
[4] << 16) | (blksrc
[5] << 24);
170 const GLuint bits_high
= blksrc
[6] | (blksrc
[7] << 8);
174 code
= (GLubyte
) ((bits_low
>> bit_pos
) & 7);
175 else if (bit_pos
== 30)
176 code
= (GLubyte
) ((bits_low
>> 30) & 3) | ((bits_high
<< 2) & 4);
178 code
= (GLubyte
) ((bits_high
>> (bit_pos
- 32)) & 7);
181 /* TODO test this! */
182 const GLubyte bit_pos
= ((j
&3) * 4 + (i
&3)) * 3;
183 const GLubyte acodelow
= blksrc
[2 + bit_pos
/ 8];
184 const GLubyte acodehigh
= blksrc
[3 + bit_pos
/ 8];
185 const GLubyte code
= (acodelow
>> (bit_pos
& 0x7) |
186 (acodehigh
<< (8 - (bit_pos
& 0x7)))) & 0x7;
188 dxt135_decode_imageblock(blksrc
+ 8, (i
&3), (j
&3), 2, texel
);
190 if (alpha0
> alpha1
) {
193 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha0
);
196 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha1
);
204 rgba
[ACOMP
] = UBYTE_TO_CHAN( ((alpha0
* (8 - code
) + (alpha1
* (code
- 1))) / 7) );
211 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha0
);
214 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha1
);
220 rgba
[ACOMP
] = UBYTE_TO_CHAN( ((alpha0
* (6 - code
) + (alpha1
* (code
- 1))) / 5) );
226 rgba
[ACOMP
] = CHAN_MAX
;
231 /* not sure. Which version is faster? */
235 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha0
);
237 rgba
[ACOMP
] = UBYTE_TO_CHAN( alpha1
);
238 else if (alpha0
> alpha1
)
239 rgba
[ACOMP
] = UBYTE_TO_CHAN( ((alpha0
* (8 - code
) + (alpha1
* (code
- 1))) / 7) );
241 rgba
[ACOMP
] = UBYTE_TO_CHAN( ((alpha0
* (6 - code
) + (alpha1
* (code
- 1))) / 5) );
245 rgba
[ACOMP
] = CHAN_MAX
;