[SHELL32] SHChangeNotify: Use tree for CDirectoryList (#6784)
[reactos.git] / dll / directx / wine / d3dx9_36 / txc_fetch_dxtn.c
1 #ifdef __REACTOS__
2 #include "precomp.h"
3 #else
4 /*
5 * libtxc_dxtn
6 * Version: 1.0
7 *
8 * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
9 *
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:
16 *
17 * The above copyright notice and this permission notice shall be included
18 * in all copies or substantial portions of the Software.
19 *
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.
26 */
27
28 #include <stdio.h>
29 #include "txc_dxtn.h"
30 #endif /* __REACTOS__ */
31
32 #define EXP5TO8R(packedcol) \
33 ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7))
34
35 #define EXP6TO8G(packedcol) \
36 ((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x3))
37
38 #define EXP5TO8B(packedcol) \
39 ((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x7))
40
41 #define EXP4TO8(col) \
42 ((col) | ((col) << 4))
43
44 /* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */
45
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);
56
57 rgba[ACOMP] = CHAN_MAX;
58 switch (code) {
59 case 0:
60 rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color0) );
61 rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color0) );
62 rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color0) );
63 break;
64 case 1:
65 rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color1) );
66 rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color1) );
67 rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color1) );
68 break;
69 case 2:
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) );
74 }
75 else {
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) );
79 }
80 break;
81 case 3:
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) );
86 }
87 else {
88 rgba[RCOMP] = 0;
89 rgba[GCOMP] = 0;
90 rgba[BCOMP] = 0;
91 if (dxt_type == 1) rgba[ACOMP] = UBYTE_TO_CHAN(0);
92 }
93 break;
94 default:
95 /* CANNOT happen (I hope) */
96 break;
97 }
98 }
99
100
101 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
102 GLint i, GLint j, GLvoid *texel)
103 {
104 /* Extract the (i,j) pixel from pixdata and return it
105 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
106 */
107
108 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
109 dxt135_decode_imageblock(blksrc, (i&3), (j&3), 0, texel);
110 }
111
112
113 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
114 GLint i, GLint j, GLvoid *texel)
115 {
116 /* Extract the (i,j) pixel from pixdata and return it
117 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
118 */
119
120 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
121 dxt135_decode_imageblock(blksrc, (i&3), (j&3), 1, texel);
122 }
123
124 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
125 GLint i, GLint j, GLvoid *texel) {
126
127 /* Extract the (i,j) pixel from pixdata and return it
128 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
129 */
130
131 GLchan *rgba = (GLchan *) texel;
132 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
133 #if 0
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);
139
140 dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
141 if (bit_pos < 32)
142 rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8((alpha_low >> bit_pos) & 15)) );
143 else
144 rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8((alpha_high >> (bit_pos - 32)) & 15)) );
145 #endif
146 #if 1
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)) );
151 #endif
152
153 }
154
155 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
156 GLint i, GLint j, GLvoid *texel) {
157
158 /* Extract the (i,j) pixel from pixdata and return it
159 * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
160 */
161
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];
166 #if 0
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);
171 GLubyte code;
172
173 if (bit_pos < 30)
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);
177 else
178 code = (GLubyte) ((bits_high >> (bit_pos - 32)) & 7);
179 #endif
180 #if 1
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;
187 #endif
188 dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
189 #if 0
190 if (alpha0 > alpha1) {
191 switch (code) {
192 case 0:
193 rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
194 break;
195 case 1:
196 rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
197 break;
198 case 2:
199 case 3:
200 case 4:
201 case 5:
202 case 6:
203 case 7:
204 rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
205 break;
206 }
207 }
208 else {
209 switch (code) {
210 case 0:
211 rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
212 break;
213 case 1:
214 rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
215 break;
216 case 2:
217 case 3:
218 case 4:
219 case 5:
220 rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
221 break;
222 case 6:
223 rgba[ACOMP] = 0;
224 break;
225 case 7:
226 rgba[ACOMP] = CHAN_MAX;
227 break;
228 }
229 }
230 #endif
231 /* not sure. Which version is faster? */
232 #if 1
233 /* TODO test this */
234 if (code == 0)
235 rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
236 else if (code == 1)
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) );
240 else if (code < 6)
241 rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
242 else if (code == 6)
243 rgba[ACOMP] = 0;
244 else
245 rgba[ACOMP] = CHAN_MAX;
246 #endif
247 }