ReactOS  0.4.15-dev-2947-g59e1b78
txc_fetch_dxtn.c
Go to the documentation of this file.
1 /*
2  * libtxc_dxtn
3  * Version: 1.0
4  *
5  * Copyright (C) 2004 Roland Scheidegger All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include <stdio.h>
26 #include "txc_dxtn.h"
27 
28 #define EXP5TO8R(packedcol) \
29  ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7))
30 
31 #define EXP6TO8G(packedcol) \
32  ((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x3))
33 
34 #define EXP5TO8B(packedcol) \
35  ((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x7))
36 
37 #define EXP4TO8(col) \
38  ((col) | ((col) << 4))
39 
40 /* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */
41 
42 static void dxt135_decode_imageblock ( const GLubyte *img_block_src,
43  GLint i, GLint j, GLuint dxt_type, GLvoid *texel ) {
44  GLchan *rgba = (GLchan *) texel;
45  const GLushort color0 = img_block_src[0] | (img_block_src[1] << 8);
46  const GLushort color1 = img_block_src[2] | (img_block_src[3] << 8);
47  const GLuint bits = img_block_src[4] | (img_block_src[5] << 8) |
48  (img_block_src[6] << 16) | (img_block_src[7] << 24);
49  /* What about big/little endian? */
50  GLubyte bit_pos = 2 * (j * 4 + i) ;
51  GLubyte code = (GLubyte) ((bits >> bit_pos) & 3);
52 
53  rgba[ACOMP] = CHAN_MAX;
54  switch (code) {
55  case 0:
56  rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color0) );
57  rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color0) );
58  rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color0) );
59  break;
60  case 1:
61  rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color1) );
62  rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color1) );
63  rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color1) );
64  break;
65  case 2:
66  if ((dxt_type > 1) || (color0 > color1)) {
67  rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) * 2 + EXP5TO8R(color1)) / 3) );
68  rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) * 2 + EXP6TO8G(color1)) / 3) );
69  rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) * 2 + EXP5TO8B(color1)) / 3) );
70  }
71  else {
72  rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1)) / 2) );
73  rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1)) / 2) );
74  rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1)) / 2) );
75  }
76  break;
77  case 3:
78  if ((dxt_type > 1) || (color0 > color1)) {
79  rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1) * 2) / 3) );
80  rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1) * 2) / 3) );
81  rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1) * 2) / 3) );
82  }
83  else {
84  rgba[RCOMP] = 0;
85  rgba[GCOMP] = 0;
86  rgba[BCOMP] = 0;
87  if (dxt_type == 1) rgba[ACOMP] = UBYTE_TO_CHAN(0);
88  }
89  break;
90  default:
91  /* CANNOT happen (I hope) */
92  break;
93  }
94 }
95 
96 
97 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
98  GLint i, GLint j, GLvoid *texel)
99 {
100  /* Extract the (i,j) pixel from pixdata and return it
101  * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
102  */
103 
104  const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
105  dxt135_decode_imageblock(blksrc, (i&3), (j&3), 0, texel);
106 }
107 
108 
109 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
110  GLint i, GLint j, GLvoid *texel)
111 {
112  /* Extract the (i,j) pixel from pixdata and return it
113  * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
114  */
115 
116  const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
117  dxt135_decode_imageblock(blksrc, (i&3), (j&3), 1, texel);
118 }
119 
120 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
121  GLint i, GLint j, GLvoid *texel) {
122 
123  /* Extract the (i,j) pixel from pixdata and return it
124  * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
125  */
126 
127  GLchan *rgba = (GLchan *) texel;
128  const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
129 #if 0
130  /* Simple 32bit version. */
131 /* that's pretty brain-dead for a single pixel, isn't it? */
132  const GLubyte bit_pos = 4 * ((j&3) * 4 + (i&3));
133  const GLuint alpha_low = blksrc[0] | (blksrc[1] << 8) | (blksrc[2] << 16) | (blksrc[3] << 24);
134  const GLuint alpha_high = blksrc[4] | (blksrc[5] << 8) | (blksrc[6] << 16) | (blksrc[7] << 24);
135 
136  dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
137  if (bit_pos < 32)
138  rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8((alpha_low >> bit_pos) & 15)) );
139  else
140  rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8((alpha_high >> (bit_pos - 32)) & 15)) );
141 #endif
142 #if 1
143 /* TODO test this! */
144  const GLubyte anibble = (blksrc[((j&3) * 4 + (i&3)) / 2] >> (4 * (i&1))) & 0xf;
145  dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
146  rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8(anibble)) );
147 #endif
148 
149 }
150 
151 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
152  GLint i, GLint j, GLvoid *texel) {
153 
154  /* Extract the (i,j) pixel from pixdata and return it
155  * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP].
156  */
157 
158  GLchan *rgba = (GLchan *) texel;
159  const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
160  const GLubyte alpha0 = blksrc[0];
161  const GLubyte alpha1 = blksrc[1];
162 #if 0
163  const GLubyte bit_pos = 3 * ((j&3) * 4 + (i&3));
164  /* simple 32bit version */
165  const GLuint bits_low = blksrc[2] | (blksrc[3] << 8) | (blksrc[4] << 16) | (blksrc[5] << 24);
166  const GLuint bits_high = blksrc[6] | (blksrc[7] << 8);
167  GLubyte code;
168 
169  if (bit_pos < 30)
170  code = (GLubyte) ((bits_low >> bit_pos) & 7);
171  else if (bit_pos == 30)
172  code = (GLubyte) ((bits_low >> 30) & 3) | ((bits_high << 2) & 4);
173  else
174  code = (GLubyte) ((bits_high >> (bit_pos - 32)) & 7);
175 #endif
176 #if 1
177 /* TODO test this! */
178  const GLubyte bit_pos = ((j&3) * 4 + (i&3)) * 3;
179  const GLubyte acodelow = blksrc[2 + bit_pos / 8];
180  const GLubyte acodehigh = blksrc[3 + bit_pos / 8];
181  const GLubyte code = (acodelow >> (bit_pos & 0x7) |
182  (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7;
183 #endif
184  dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel);
185 #if 0
186  if (alpha0 > alpha1) {
187  switch (code) {
188  case 0:
189  rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
190  break;
191  case 1:
192  rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
193  break;
194  case 2:
195  case 3:
196  case 4:
197  case 5:
198  case 6:
199  case 7:
200  rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
201  break;
202  }
203  }
204  else {
205  switch (code) {
206  case 0:
207  rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
208  break;
209  case 1:
210  rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
211  break;
212  case 2:
213  case 3:
214  case 4:
215  case 5:
216  rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
217  break;
218  case 6:
219  rgba[ACOMP] = 0;
220  break;
221  case 7:
222  rgba[ACOMP] = CHAN_MAX;
223  break;
224  }
225  }
226 #endif
227 /* not sure. Which version is faster? */
228 #if 1
229 /* TODO test this */
230  if (code == 0)
231  rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 );
232  else if (code == 1)
233  rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 );
234  else if (alpha0 > alpha1)
235  rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
236  else if (code < 6)
237  rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
238  else if (code == 6)
239  rgba[ACOMP] = 0;
240  else
241  rgba[ACOMP] = CHAN_MAX;
242 #endif
243 }
#define EXP5TO8B(packedcol)
static void dxt135_decode_imageblock(const GLubyte *img_block_src, GLint i, GLint j, GLuint dxt_type, GLvoid *texel)
#define RCOMP
Definition: txc_dxtn.h:33
GLubyte GLchan
Definition: txc_dxtn.h:30
void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel)
unsigned char GLubyte
Definition: gl.h:157
#define BCOMP
Definition: txc_dxtn.h:35
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * bits
Definition: glext.h:10929
#define UBYTE_TO_CHAN(b)
Definition: txc_dxtn.h:31
#define CHAN_MAX
Definition: txc_dxtn.h:32
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define EXP5TO8R(packedcol)
#define ACOMP
Definition: txc_dxtn.h:36
Definition: inflate.c:139
int code
Definition: main.c:75
void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel)
unsigned int GLuint
Definition: gl.h:159
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EXP4TO8(col)
#define EXP6TO8G(packedcol)
void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel)
int GLint
Definition: gl.h:156
void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata, GLint i, GLint j, GLvoid *texel)
static const unsigned char pixdata[]
Definition: surface.c:101
unsigned short GLushort
Definition: gl.h:158
#define GCOMP
Definition: txc_dxtn.h:34