1 #include "libtxc_dxtn.h"
4 #include "s2tc_compressor.h"
6 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
7 GLint i, GLint j, GLvoid *texel)
9 // fetches a single texel (i,j) into pixdata (RGB)
10 GLubyte *t = (GLubyte *) texel;
11 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
12 unsigned int c = blksrc[0] + 256*blksrc[1];
13 unsigned int c1 = blksrc[2] + 256*blksrc[3];
14 int b = (blksrc[4 + (j % 4)] >> (2 * (i % 4))) & 0x03;
18 case 1: c = c1; break;
19 case 3: if(c1 > c) { c = 0; break; }
20 default: if(rand() & 1) c = c1; break;
22 t[2] = ((c >> 11) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
23 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
24 t[0] = ((c ) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
27 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
28 GLint i, GLint j, GLvoid *texel)
30 // fetches a single texel (i,j) into pixdata (RGBA)
31 GLubyte *t = (GLubyte *) texel;
32 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
33 unsigned int c = blksrc[0] + 256*blksrc[1];
34 unsigned int c1 = blksrc[2] + 256*blksrc[3];
35 int b = (blksrc[4 + (j % 4)] >> (2 * (i % 4))) & 0x03;
38 case 0: t[3] = 255; break;
39 case 1: c = c1; t[3] = 255; break;
40 case 3: if(c1 > c) { c = 0; t[3] = 0; break; }
41 default: if(rand() & 1) c = c1; t[3] = 255; break;
43 t[2] = ((c >> 11) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
44 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
45 t[0] = ((c ) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
48 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
49 GLint i, GLint j, GLvoid *texel)
51 // fetches a single texel (i,j) into pixdata (RGBA)
52 GLubyte *t = (GLubyte *) texel;
53 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
54 unsigned int c = blksrc[8] + 256*blksrc[9];
55 unsigned int c1 = blksrc[10] + 256*blksrc[11];
56 int b = (blksrc[12 + (j % 4)] >> (2 * (i % 4))) & 0x03;
60 case 1: c = c1; break;
61 default: if(rand() & 1) c = c1; break;
63 t[2] = ((c >> 11) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
64 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
65 t[0] = ((c ) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
66 int a = (blksrc[(j % 4) * 2 + (i % 4) / 2] >> (4 * (i % 4) % 2)) & 0x0F;
70 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
71 GLint i, GLint j, GLvoid *texel)
73 // fetches a single texel (i,j) into pixdata (RGBA)
74 GLubyte *t = (GLubyte *) texel;
75 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
76 unsigned int c = blksrc[8] + 256*blksrc[9];
77 unsigned int c1 = blksrc[10] + 256*blksrc[11];
78 int b = (blksrc[12 + (j % 4)] >> (2 * (i % 4))) & 0x03;
82 case 1: c = c1; break;
83 default: if(rand() & 1) c = c1; break;
85 t[2] = ((c >> 11) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
86 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
87 t[0] = ((c ) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
89 unsigned int a = blksrc[0];
90 unsigned int a1 = blksrc[1];
91 int abit = ((j % 4) * 4 + (i % 4)) * 3;
93 if(blksrc[(abit / 8)] & (1 << (abit % 8)))
96 if(blksrc[(abit / 8)] & (1 << (abit % 8)))
99 if(blksrc[(abit / 8)] & (1 << (abit % 8)))
104 case 1: a = a1; break;
105 case 6: a = 0; break;
106 case 7: a = 255; break;
107 default: if(rand() & 1) a = a1; break;
112 void tx_compress_dxtn(GLint srccomps, GLint width, GLint height,
113 const GLubyte *srcPixData, GLenum destFormat,
114 GLubyte *dest, GLint dstRowStride)
116 // compresses width*height pixels (RGB or RGBA depending on srccomps) at srcPixData (packed) to destformat (dest, dstRowStride)
118 GLubyte *blkaddr = dest;
119 GLint numxpixels, numypixels;
122 unsigned char *rgba = (unsigned char *) malloc(width * height * 4);
123 unsigned char *srcaddr;
125 switch (destFormat) {
126 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
127 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
128 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 1);
130 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
131 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 4);
133 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
134 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 8);
138 fprintf(stderr, "libdxtn: Bad dstFormat %d in tx_compress_dxtn\n", destFormat);
142 s2tc_encode_block_func_t encode_block;
143 switch (destFormat) {
144 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
145 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
146 /* hmm we used to get called without dstRowStride... */
147 dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0;
148 /* fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n",
149 width, height, dstRowStride); */
150 encode_block = s2tc_encode_block_func(DXT1, WAVG, -1);
151 for (j = 0; j < height; j += 4) {
152 if (height > j + 3) numypixels = 4;
153 else numypixels = height - j;
154 srcaddr = rgba + j * width * 4;
155 for (i = 0; i < width; i += 4) {
156 if (width > i + 3) numxpixels = 4;
157 else numxpixels = width - i;
158 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, -1);
159 srcaddr += 4 * numxpixels;
162 blkaddr += dstRowDiff;
165 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
166 dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
167 /* fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n",
168 width, height, dstRowStride); */
169 encode_block = s2tc_encode_block_func(DXT3, WAVG, -1);
170 for (j = 0; j < height; j += 4) {
171 if (height > j + 3) numypixels = 4;
172 else numypixels = height - j;
173 srcaddr = rgba + j * width * 4;
174 for (i = 0; i < width; i += 4) {
175 if (width > i + 3) numxpixels = 4;
176 else numxpixels = width - i;
177 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, -1);
178 srcaddr += 4 * numxpixels;
181 blkaddr += dstRowDiff;
184 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
185 dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
186 /* fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n",
187 width, height, dstRowStride); */
188 encode_block = s2tc_encode_block_func(DXT5, WAVG, -1);
189 for (j = 0; j < height; j += 4) {
190 if (height > j + 3) numypixels = 4;
191 else numypixels = height - j;
192 srcaddr = rgba + j * width * 4;
193 for (i = 0; i < width; i += 4) {
194 if (width > i + 3) numxpixels = 4;
195 else numxpixels = width - i;
196 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, -1);
197 srcaddr += 4 * numxpixels;
200 blkaddr += dstRowDiff;