9 #include "s2tc_compressor.h"
11 void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata,
12 GLint i, GLint j, GLvoid *texel)
14 // fetches a single texel (i,j) into pixdata (RGB)
15 GLubyte *t = (GLubyte *) texel;
16 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
17 unsigned int c = blksrc[0] + 256*blksrc[1];
18 unsigned int c1 = blksrc[2] + 256*blksrc[3];
19 int b = (blksrc[4 + (j % 4)] >> (2 * (i % 4))) & 0x03;
23 case 1: c = c1; break;
24 case 3: if(c1 > c) { c = 0; break; }
25 default: if((i^j) & 1) c = c1; break;
27 t[0] = ((c >> 11) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
28 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
29 t[2] = ((c ) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
33 void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata,
34 GLint i, GLint j, GLvoid *texel)
36 // fetches a single texel (i,j) into pixdata (RGBA)
37 GLubyte *t = (GLubyte *) texel;
38 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8);
39 unsigned int c = blksrc[0] + 256*blksrc[1];
40 unsigned int c1 = blksrc[2] + 256*blksrc[3];
41 int b = (blksrc[4 + (j % 4)] >> (2 * (i % 4))) & 0x03;
44 case 0: t[3] = 255; break;
45 case 1: c = c1; t[3] = 255; break;
46 case 3: if(c1 > c) { c = 0; t[3] = 0; break; }
47 default: if((i^j) & 1) c = c1; t[3] = 255; break;
49 t[0] = ((c >> 11) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
50 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
51 t[2] = ((c ) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
54 void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata,
55 GLint i, GLint j, GLvoid *texel)
57 // fetches a single texel (i,j) into pixdata (RGBA)
58 GLubyte *t = (GLubyte *) texel;
59 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
60 unsigned int c = blksrc[8] + 256*blksrc[9];
61 unsigned int c1 = blksrc[10] + 256*blksrc[11];
62 int b = (blksrc[12 + (j % 4)] >> (2 * (i % 4))) & 0x03;
66 case 1: c = c1; break;
67 default: if((i^j) & 1) c = c1; break;
69 t[0] = ((c >> 11) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
70 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
71 t[2] = ((c ) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
72 int a = (blksrc[(j % 4) * 2 + (i % 4) / 2] >> (4 * (i % 4) % 2)) & 0x0F;
76 void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata,
77 GLint i, GLint j, GLvoid *texel)
79 // fetches a single texel (i,j) into pixdata (RGBA)
80 GLubyte *t = (GLubyte *) texel;
81 const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16);
82 unsigned int c = blksrc[8] + 256*blksrc[9];
83 unsigned int c1 = blksrc[10] + 256*blksrc[11];
84 int b = (blksrc[12 + (j % 4)] >> (2 * (i % 4))) & 0x03;
88 case 1: c = c1; break;
89 default: if((i^j) & 1) c = c1; break;
91 t[0] = ((c >> 11) & 0x1F); t[0] = (t[0] << 3) | (t[0] >> 2);
92 t[1] = ((c >> 5) & 0x3F); t[1] = (t[1] << 2) | (t[1] >> 4);
93 t[2] = ((c ) & 0x1F); t[2] = (t[2] << 3) | (t[2] >> 2);
95 unsigned int a = blksrc[0];
96 unsigned int a1 = blksrc[1];
97 int abit = ((j % 4) * 4 + (i % 4)) * 3;
99 if(blksrc[(abit / 8) + 2] & (1 << (abit % 8)))
102 if(blksrc[(abit / 8) + 2] & (1 << (abit % 8)))
105 if(blksrc[(abit / 8) + 2] & (1 << (abit % 8)))
110 case 1: a = a1; break;
111 case 6: a = 0; break;
112 case 7: a = 255; break;
113 default: if((i^j) & 1) a = a1; break;
118 void tx_compress_dxtn(GLint srccomps, GLint width, GLint height,
119 const GLubyte *srcPixData, GLenum destformat,
120 GLubyte *dest, GLint dstRowStride)
122 // compresses width*height pixels (RGB or RGBA depending on srccomps) at srcPixData (packed) to destformat (dest, dstRowStride)
124 GLubyte *blkaddr = dest;
125 GLint numxpixels, numypixels;
128 unsigned char *rgba = (unsigned char *) malloc(width * height * 4);
129 unsigned char *srcaddr;
132 switch (destformat) {
133 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
134 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
136 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 1);
138 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
140 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 4);
142 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
144 rgb565_image(rgba, srcPixData, width, height, srccomps, 0, 8);
148 fprintf(stderr, "libdxtn: Bad dstFormat %d in tx_compress_dxtn\n", destformat);
152 ColorDistMode cd = WAVG;
154 RefinementMode refine = REFINE_ALWAYS;
156 const char *v = getenv("S2TC_COLORDIST_MODE");
159 if(!strcasecmp(v, "RGB"))
161 else if(!strcasecmp(v, "YUV"))
163 else if(!strcasecmp(v, "SRGB"))
165 else if(!strcasecmp(v, "SRGB_MIXED"))
167 else if(!strcasecmp(v, "LAB"))
169 else if(!strcasecmp(v, "AVG"))
171 else if(!strcasecmp(v, "WAVG"))
173 else if(!strcasecmp(v, "NORMALMAP"))
176 fprintf(stderr, "Invalid color dist mode: %s\n", v);
180 const char *v = getenv("S2TC_RANDOM_COLORS");
185 const char *v = getenv("S2TC_REFINE_COLORS");
188 if(!strcasecmp(v, "NEVER"))
189 refine = REFINE_NEVER;
190 else if(!strcasecmp(v, "ALWAYS"))
191 refine = REFINE_ALWAYS;
192 else if(!strcasecmp(v, "CHECK"))
193 refine = REFINE_CHECK;
195 fprintf(stderr, "Invalid refinement mode: %s\n", v);
199 s2tc_encode_block_func_t encode_block = s2tc_encode_block_func(dxt, cd, nrandom, refine);
200 switch (destformat) {
201 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
202 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
203 /* hmm we used to get called without dstRowStride... */
204 dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0;
205 /* fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n",
206 width, height, dstRowStride); */
207 for (j = 0; j < height; j += 4) {
208 if (height > j + 3) numypixels = 4;
209 else numypixels = height - j;
210 srcaddr = rgba + j * width * 4;
211 for (i = 0; i < width; i += 4) {
212 if (width > i + 3) numxpixels = 4;
213 else numxpixels = width - i;
214 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, nrandom);
215 srcaddr += 4 * numxpixels;
218 blkaddr += dstRowDiff;
221 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
222 dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
223 /* fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n",
224 width, height, dstRowStride); */
225 for (j = 0; j < height; j += 4) {
226 if (height > j + 3) numypixels = 4;
227 else numypixels = height - j;
228 srcaddr = rgba + j * width * 4;
229 for (i = 0; i < width; i += 4) {
230 if (width > i + 3) numxpixels = 4;
231 else numxpixels = width - i;
232 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, nrandom);
233 srcaddr += 4 * numxpixels;
236 blkaddr += dstRowDiff;
239 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
240 dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0;
241 /* fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n",
242 width, height, dstRowStride); */
243 for (j = 0; j < height; j += 4) {
244 if (height > j + 3) numypixels = 4;
245 else numypixels = height - j;
246 srcaddr = rgba + j * width * 4;
247 for (i = 0; i < width; i += 4) {
248 if (width > i + 3) numxpixels = 4;
249 else numxpixels = width - i;
250 encode_block(blkaddr, srcaddr, width, numxpixels, numypixels, nrandom);
251 srcaddr += 4 * numxpixels;
254 blkaddr += dstRowDiff;