⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texcompress_fxt1.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 4 页
字号:
            input[k + l * 4 + 12][i] = *lines[l]++;         }      }   }   /* block layout:    * 00, 01, 02, 03, 08, 09, 0a, 0b    * 10, 11, 12, 13, 18, 19, 1a, 1b    * 04, 05, 06, 07, 0c, 0d, 0e, 0f    * 14, 15, 16, 17, 1c, 1d, 1e, 1f    */   /* [dBorca]    * stupidity flows forth from this    */   l = N_TEXELS;   trualpha = 0;   if (comps == 4) {      /* skip all transparent black texels */      l = 0;      for (k = 0; k < N_TEXELS; k++) {         /* test all components against 0 */         if (!ISTBLACK(input[k])) {            /* texel is not transparent black */            COPY_4UBV(reord[l], input[k]);            if (reord[l][ACOMP] < (255 - ALPHA_TS)) {               /* non-opaque texel */               trualpha = !0;            }            l++;         }      }   }#if 0   if (trualpha) {      fxt1_quantize_ALPHA0(cc, input, reord, l);   } else if (l == 0) {      cc[0] = cc[1] = cc[2] = -1;      cc[3] = 0;   } else if (l < N_TEXELS) {      fxt1_quantize_HI(cc, input, reord, l);   } else {      fxt1_quantize_CHROMA(cc, input);   }   (void)fxt1_quantize_ALPHA1;   (void)fxt1_quantize_MIXED1;   (void)fxt1_quantize_MIXED0;#else   if (trualpha) {      fxt1_quantize_ALPHA1(cc, input);   } else if (l == 0) {      cc[0] = cc[1] = cc[2] = ~0u;      cc[3] = 0;   } else if (l < N_TEXELS) {      fxt1_quantize_MIXED1(cc, input);   } else {      fxt1_quantize_MIXED0(cc, input);   }   (void)fxt1_quantize_ALPHA0;   (void)fxt1_quantize_HI;   (void)fxt1_quantize_CHROMA;#endif}static voidfxt1_encode (GLuint width, GLuint height, GLint comps,             const void *source, GLint srcRowStride,             void *dest, GLint destRowStride){   GLuint x, y;   const GLubyte *data;   GLuint *encoded = (GLuint *)dest;   void *newSource = NULL;   assert(comps == 3 || comps == 4);   /* Replicate image if width is not M8 or height is not M4 */   if ((width & 7) | (height & 3)) {      GLint newWidth = (width + 7) & ~7;      GLint newHeight = (height + 3) & ~3;      newSource = _mesa_malloc(comps * newWidth * newHeight * sizeof(GLchan));      if (!newSource) {         GET_CURRENT_CONTEXT(ctx);         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression");         goto cleanUp;      }      _mesa_upscale_teximage2d(width, height, newWidth, newHeight,                               comps, (const GLchan *) source,                               srcRowStride, (GLchan *) newSource);      source = newSource;      width = newWidth;      height = newHeight;      srcRowStride = comps * newWidth;   }   /* convert from 16/32-bit channels to GLubyte if needed */   if (CHAN_TYPE != GL_UNSIGNED_BYTE) {      const GLuint n = width * height * comps;      const GLchan *src = (const GLchan *) source;      GLubyte *dest = (GLubyte *) _mesa_malloc(n * sizeof(GLubyte));      GLuint i;      if (!dest) {         GET_CURRENT_CONTEXT(ctx);         _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture compression");         goto cleanUp;      }      for (i = 0; i < n; i++) {         dest[i] = CHAN_TO_UBYTE(src[i]);      }      if (newSource != NULL) {         _mesa_free(newSource);      }      newSource = dest;  /* we'll free this buffer before returning */      source = dest;  /* the new, GLubyte incoming image */   }   data = (const GLubyte *) source;   destRowStride = (destRowStride - width * 2) / 4;   for (y = 0; y < height; y += 4) {      GLuint offs = 0 + (y + 0) * srcRowStride;      for (x = 0; x < width; x += 8) {         const GLubyte *lines[4];         lines[0] = &data[offs];         lines[1] = lines[0] + srcRowStride;         lines[2] = lines[1] + srcRowStride;         lines[3] = lines[2] + srcRowStride;         offs += 8 * comps;         fxt1_quantize(encoded, lines, comps);         /* 128 bits per 8x4 block */         encoded += 4;      }      encoded += destRowStride;   } cleanUp:   if (newSource != NULL) {      _mesa_free(newSource);   }}/***************************************************************************\ * FXT1 decoder * * The decoder is based on GL_3DFX_texture_compression_FXT1 * specification and serves as a concept for the encoder.\***************************************************************************//* lookup table for scaling 5 bit colors up to 8 bits */static const GLubyte _rgb_scale_5[] = {   0,   8,   16,  25,  33,  41,  49,  58,   66,  74,  82,  90,  99,  107, 115, 123,   132, 140, 148, 156, 165, 173, 181, 189,   197, 206, 214, 222, 230, 239, 247, 255};/* lookup table for scaling 6 bit colors up to 8 bits */static const GLubyte _rgb_scale_6[] = {   0,   4,   8,   12,  16,  20,  24,  28,   32,  36,  40,  45,  49,  53,  57,  61,   65,  69,  73,  77,  81,  85,  89,  93,   97,  101, 105, 109, 113, 117, 121, 125,   130, 134, 138, 142, 146, 150, 154, 158,   162, 166, 170, 174, 178, 182, 186, 190,   194, 198, 202, 206, 210, 215, 219, 223,   227, 231, 235, 239, 243, 247, 251, 255};#define CC_SEL(cc, which) (((GLuint *)(cc))[(which) / 32] >> ((which) & 31))#define UP5(c) _rgb_scale_5[(c) & 31]#define UP6(c, b) _rgb_scale_6[(((c) & 31) << 1) | ((b) & 1)]#define LERP(n, t, c0, c1) (((n) - (t)) * (c0) + (t) * (c1) + (n) / 2) / (n)static voidfxt1_decode_1HI (const GLubyte *code, GLint t, GLchan *rgba){   const GLuint *cc;   t *= 3;   cc = (const GLuint *)(code + t / 8);   t = (cc[0] >> (t & 7)) & 7;   if (t == 7) {      rgba[RCOMP] = rgba[GCOMP] = rgba[BCOMP] = rgba[ACOMP] = 0;   } else {      GLubyte r, g, b;      cc = (const GLuint *)(code + 12);      if (t == 0) {         b = UP5(CC_SEL(cc, 0));         g = UP5(CC_SEL(cc, 5));         r = UP5(CC_SEL(cc, 10));      } else if (t == 6) {         b = UP5(CC_SEL(cc, 15));         g = UP5(CC_SEL(cc, 20));         r = UP5(CC_SEL(cc, 25));      } else {         b = LERP(6, t, UP5(CC_SEL(cc, 0)), UP5(CC_SEL(cc, 15)));         g = LERP(6, t, UP5(CC_SEL(cc, 5)), UP5(CC_SEL(cc, 20)));         r = LERP(6, t, UP5(CC_SEL(cc, 10)), UP5(CC_SEL(cc, 25)));      }      rgba[RCOMP] = UBYTE_TO_CHAN(r);      rgba[GCOMP] = UBYTE_TO_CHAN(g);      rgba[BCOMP] = UBYTE_TO_CHAN(b);      rgba[ACOMP] = CHAN_MAX;   }}static voidfxt1_decode_1CHROMA (const GLubyte *code, GLint t, GLchan *rgba){   const GLuint *cc;   GLuint kk;   cc = (const GLuint *)code;   if (t & 16) {      cc++;      t &= 15;   }   t = (cc[0] >> (t * 2)) & 3;   t *= 15;   cc = (const GLuint *)(code + 8 + t / 8);   kk = cc[0] >> (t & 7);   rgba[BCOMP] = UBYTE_TO_CHAN( UP5(kk) );   rgba[GCOMP] = UBYTE_TO_CHAN( UP5(kk >> 5) );   rgba[RCOMP] = UBYTE_TO_CHAN( UP5(kk >> 10) );   rgba[ACOMP] = CHAN_MAX;}static voidfxt1_decode_1MIXED (const GLubyte *code, GLint t, GLchan *rgba){   const GLuint *cc;   GLuint col[2][3];   GLint glsb, selb;   cc = (const GLuint *)code;   if (t & 16) {      t &= 15;      t = (cc[1] >> (t * 2)) & 3;      /* col 2 */      col[0][BCOMP] = (*(const GLuint *)(code + 11)) >> 6;      col[0][GCOMP] = CC_SEL(cc, 99);      col[0][RCOMP] = CC_SEL(cc, 104);      /* col 3 */      col[1][BCOMP] = CC_SEL(cc, 109);      col[1][GCOMP] = CC_SEL(cc, 114);      col[1][RCOMP] = CC_SEL(cc, 119);      glsb = CC_SEL(cc, 126);      selb = CC_SEL(cc, 33);   } else {      t = (cc[0] >> (t * 2)) & 3;      /* col 0 */      col[0][BCOMP] = CC_SEL(cc, 64);      col[0][GCOMP] = CC_SEL(cc, 69);      col[0][RCOMP] = CC_SEL(cc, 74);      /* col 1 */      col[1][BCOMP] = CC_SEL(cc, 79);      col[1][GCOMP] = CC_SEL(cc, 84);      col[1][RCOMP] = CC_SEL(cc, 89);      glsb = CC_SEL(cc, 125);      selb = CC_SEL(cc, 1);   }   if (CC_SEL(cc, 124) & 1) {      /* alpha[0] == 1 */      if (t == 3) {         /* zero */         rgba[RCOMP] = rgba[BCOMP] = rgba[GCOMP] = rgba[ACOMP] = 0;      } else {         GLubyte r, g, b;         if (t == 0) {            b = UP5(col[0][BCOMP]);            g = UP5(col[0][GCOMP]);            r = UP5(col[0][RCOMP]);         } else if (t == 2) {            b = UP5(col[1][BCOMP]);            g = UP6(col[1][GCOMP], glsb);            r = UP5(col[1][RCOMP]);         } else {            b = (UP5(col[0][BCOMP]) + UP5(col[1][BCOMP])) / 2;            g = (UP5(col[0][GCOMP]) + UP6(col[1][GCOMP], glsb)) / 2;            r = (UP5(col[0][RCOMP]) + UP5(col[1][RCOMP])) / 2;         }         rgba[RCOMP] = UBYTE_TO_CHAN(r);         rgba[GCOMP] = UBYTE_TO_CHAN(g);         rgba[BCOMP] = UBYTE_TO_CHAN(b);         rgba[ACOMP] = CHAN_MAX;      }   } else {      /* alpha[0] == 0 */      GLubyte r, g, b;      if (t == 0) {         b = UP5(col[0][BCOMP]);         g = UP6(col[0][GCOMP], glsb ^ selb);         r = UP5(col[0][RCOMP]);      } else if (t == 3) {         b = UP5(col[1][BCOMP]);         g = UP6(col[1][GCOMP], glsb);         r = UP5(col[1][RCOMP]);      } else {         b = LERP(3, t, UP5(col[0][BCOMP]), UP5(col[1][BCOMP]));         g = LERP(3, t, UP6(col[0][GCOMP], glsb ^ selb),                        UP6(col[1][GCOMP], glsb));         r = LERP(3, t, UP5(col[0][RCOMP]), UP5(col[1][RCOMP]));      }      rgba[RCOMP] = UBYTE_TO_CHAN(r);      rgba[GCOMP] = UBYTE_TO_CHAN(g);      rgba[BCOMP] = UBYTE_TO_CHAN(b);      rgba[ACOMP] = CHAN_MAX;   }}static voidfxt1_decode_1ALPHA (const GLubyte *code, GLint t, GLchan *rgba){   const GLuint *cc;   GLubyte r, g, b, a;   cc = (const GLuint *)code;   if (CC_SEL(cc, 124) & 1) {      /* lerp == 1 */      GLuint col0[4];      if (t & 16) {         t &= 15;         t = (cc[1] >> (t * 2)) & 3;         /* col 2 */         col0[BCOMP] = (*(const GLuint *)(code + 11)) >> 6;         col0[GCOMP] = CC_SEL(cc, 99);         col0[RCOMP] = CC_SEL(cc, 104);         col0[ACOMP] = CC_SEL(cc, 119);      } else {         t = (cc[0] >> (t * 2)) & 3;         /* col 0 */         col0[BCOMP] = CC_SEL(cc, 64);         col0[GCOMP] = CC_SEL(cc, 69);         col0[RCOMP] = CC_SEL(cc, 74);         col0[ACOMP] = CC_SEL(cc, 109);      }      if (t == 0) {         b = UP5(col0[BCOMP]);         g = UP5(col0[GCOMP]);         r = UP5(col0[RCOMP]);         a = UP5(col0[ACOMP]);      } else if (t == 3) {         b = UP5(CC_SEL(cc, 79));         g = UP5(CC_SEL(cc, 84));         r = UP5(CC_SEL(cc, 89));         a = UP5(CC_SEL(cc, 114));      } else {         b = LERP(3, t, UP5(col0[BCOMP]), UP5(CC_SEL(cc, 79)));         g = LERP(3, t, UP5(col0[GCOMP]), UP5(CC_SEL(cc, 84)));         r = LERP(3, t, UP5(col0[RCOMP]), UP5(CC_SEL(cc, 89)));         a = LERP(3, t, UP5(col0[ACOMP]), UP5(CC_SEL(cc, 114)));      }   } else {      /* lerp == 0 */      if (t & 16) {         cc++;         t &= 15;      }      t = (cc[0] >> (t * 2)) & 3;      if (t == 3) {         /* zero */         r = g = b = a = 0;      } else {         GLuint kk;         cc = (const GLuint *)code;         a = UP5(cc[3] >> (t * 5 + 13));         t *= 15;         cc = (const GLuint *)(code + 8 + t / 8);         kk = cc[0] >> (t & 7);         b = UP5(kk);         g = UP5(kk >> 5);         r = UP5(kk >> 10);      }   }   rgba[RCOMP] = UBYTE_TO_CHAN(r);   rgba[GCOMP] = UBYTE_TO_CHAN(g);   rgba[BCOMP] = UBYTE_TO_CHAN(b);   rgba[ACOMP] = UBYTE_TO_CHAN(a);}voidfxt1_decode_1 (const void *texture, GLint stride, /* in pixels */               GLint i, GLint j, GLchan *rgba){   static void (*decode_1[]) (const GLubyte *, GLint, GLchan *) = {      fxt1_decode_1HI,     /* cc-high   = "00?" */      fxt1_decode_1HI,     /* cc-high   = "00?" */      fxt1_decode_1CHROMA, /* cc-chroma = "010" */      fxt1_decode_1ALPHA,  /* alpha     = "011" */      fxt1_decode_1MIXED,  /* mixed     = "1??" */      fxt1_decode_1MIXED,  /* mixed     = "1??" */      fxt1_decode_1MIXED,  /* mixed     = "1??" */      fxt1_decode_1MIXED   /* mixed     = "1??" */   };   const GLubyte *code = (const GLubyte *)texture +                         ((j / 4) * (stride / 8) + (i / 8)) * 16;   GLint mode = CC_SEL(code, 125);   GLint t = i & 7;   if (t & 4) {      t += 12;   }   t += (j & 3) * 4;   decode_1[mode](code, t, rgba);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -