1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- #include "dxt.h"
- #include "libc.h"
- #include <stdint.h>
- static uint16_t dxtColorSum(int m1, uint16_t c1, int m2, uint16_t c2, int add, int denom) {
- /*
- const int mask_rb = 0xf81f, mask_g = 0x07e0;
- const uint32_t
- rb1 = c1 & mask_rb, g1 = c1 & mask_g,
- rb2 = c2 & mask_rb, g2 = c2 & mask_g;
- add |= (add << 5) | (add << 11);
- return
- (((m1 * rb1 + m2 * rb2 + add) / denom) & mask_rb) |
- (((m1 * g1 + m2 * g2 + add) / denom) & mask_g);
- */
- const int mask_r = 0xf800, shift_r = 11;
- const int mask_g = 0x07e0, shift_g = 5;
- const int mask_b = 0x001f, shift_b = 0;
- const int r =
- (((c1 & mask_r) >> shift_r) * m1 +
- ((c2 & mask_r) >> shift_r) * m2 + add) / denom;
- const int g =
- (((c1 & mask_g) >> shift_g) * m1 +
- ((c2 & mask_g) >> shift_g) * m2 + add) / denom;
- const int b =
- (((c1 & mask_b) >> shift_b) * m1 +
- ((c2 & mask_b) >> shift_b) * m2 + add) / denom;
- return ((r << shift_r) & mask_r) | ((g << shift_g) & mask_g) | ((b << shift_b) & mask_b);
- }
- void dxtUnpack(struct DXTUnpackContext ctx, int offset) {
- if (ctx.width < 4 || ctx.height < 4 || ctx.width & 3 || ctx.height & 3)
- return;
- const uint16_t transparent = 0;
- const uint8_t *src = (const uint8_t*)ctx.packed;
- for (int y = 0; y < ctx.height; y+=4) {
- uint16_t *dst_4x4 = (uint16_t*)ctx.output + ctx.width * y;
- for (int x = 0; x < ctx.width; x+=4, dst_4x4 += 4, src += offset) {
- uint16_t c[4];
- memcpy(c, src, 2);
- memcpy(c+1, src + 2, 2);
- if (c[0] > c[1]) {
- c[2] = dxtColorSum(2, c[0], 1, c[1], 1, 3);
- c[3] = dxtColorSum(1, c[0], 2, c[1], 1, 3);
- } else {
- c[2] = dxtColorSum(1, c[0], 1, c[1], 0, 2);
- c[3] = transparent;
- }
- uint16_t *pix = dst_4x4;
- for (int r = 0; r < 4; ++r, pix += ctx.width) {
- const uint8_t bitmap = src[4 + r];
- pix[3] = c[(bitmap >> 6) & 3];
- pix[2] = c[(bitmap >> 4) & 3];
- pix[1] = c[(bitmap >> 2) & 3];
- pix[0] = c[(bitmap >> 0) & 3];
- } /* for all rows in 4x4 */
- } /* for x */
- } /* for y */
- }
- void dxt1Unpack(struct DXTUnpackContext ctx) {
- dxtUnpack(ctx, 8);
- }
- void dxt5Unpack(struct DXTUnpackContext ctx) {
- ctx.packed = ((char*)ctx.packed) + 8;
- dxtUnpack(ctx, 16);
- }
|