Skip to content

Instantly share code, notes, and snippets.

@flowtsohg
Created April 25, 2014 23:09
Show Gist options
  • Save flowtsohg/11306221 to your computer and use it in GitHub Desktop.
Save flowtsohg/11306221 to your computer and use it in GitHub Desktop.
// 4 bit alpha
function setRgba8888Dxt3(dst, i, int565, a) {
dst[i] = Math.floor(((int565 >> 11) & 31) / 31 * 255);
dst[i + 1] = Math.floor(((int565 >> 5) & 63) / 63 * 255);
dst[i + 2] = Math.floor((int565 & 31) / 31 * 255);
dst[i + 3] = Math.floor((a / 15) * 255);
}
// 8 bit alpha
function setRgba8888Dxt5(dst, i, int565, a) {
dst[i] = Math.floor(((int565 >> 11) & 31) / 31 * 255);
dst[i + 1] = Math.floor(((int565 >> 5) & 63) / 63 * 255);
dst[i + 2] = Math.floor((int565 & 31) / 31 * 255);
dst[i + 3] = Math.floor(a);
}
function dxt1ToRgb565(src, width, height) {
var c = new Uint16Array(4);
var dst = new Uint16Array(width * height);
var m;
var dstI;
var i ;
var r0, g0, b0, r1, g1, b1;
var blockWidth = width / 4;
var blockHeight = height / 4;
for (var blockY = 0; blockY < blockHeight; blockY++) {
for (var blockX = 0; blockX < blockWidth; blockX++) {
i = 4 * (blockY * blockWidth + blockX);
c[0] = src[i];
c[1] = src[i + 1];
r0 = c[0] & 0x1f;
g0 = c[0] & 0x7e0;
b0 = c[0] & 0xf800;
r1 = c[1] & 0x1f;
g1 = c[1] & 0x7e0;
b1 = c[1] & 0xf800;
if (c[0] > c[1]) {
c[2] = ((5 * r0 + 3 * r1) >> 3) | (((5 * g0 + 3 * g1) >> 3) & 0x7e0) | (((5 * b0 + 3 * b1) >> 3) & 0xf800);
c[3] = ((5 * r1 + 3 * r0) >> 3) | (((5 * g1 + 3 * g0) >> 3) & 0x7e0) | (((5 * b1 + 3 * b0) >> 3) & 0xf800);
} else {
c[2] = (c[0] + c[1]) >> 1;
c[3] = 0;
}
m = src[i + 2];
dstI = (blockY * 4) * width + blockX * 4;
dst[dstI] = c[m & 0x3];
dst[dstI + 1] = c[(m >> 2) & 0x3];
dst[dstI + 2] = c[(m >> 4) & 0x3];
dst[dstI + 3] = c[(m >> 6) & 0x3];
dstI += width;
dst[dstI] = c[(m >> 8) & 0x3];
dst[dstI + 1] = c[(m >> 10) & 0x3];
dst[dstI + 2] = c[(m >> 12) & 0x3];
dst[dstI + 3] = c[(m >> 14)];
m = src[i + 3];
dstI += width;
dst[dstI] = c[m & 0x3];
dst[dstI + 1] = c[(m >> 2) & 0x3];
dst[dstI + 2] = c[(m >> 4) & 0x3];
dst[dstI + 3] = c[(m >> 6) & 0x3];
dstI += width;
dst[dstI] = c[(m >> 8) & 0x3];
dst[dstI + 1] = c[(m >> 10) & 0x3];
dst[dstI + 2] = c[(m >> 12) & 0x3];
dst[dstI + 3] = c[(m >> 14)];
}
}
return dst;
}
function dxt3ToRgba8888(src, width, height) {
var c = new Uint16Array(4);
var dst = new Uint8Array(width * height * 4);
var m;
var a;
var dstI;
var i ;
var r0, g0, b0, r1, g1, b1;
var blockWidth = width / 4;
var blockHeight = height / 4;
for (var blockY = 0; blockY < blockHeight; blockY++) {
for (var blockX = 0; blockX < blockWidth; blockX++) {
i = 8 * (blockY * blockWidth + blockX);
c[0] = src[i + 4];
c[1] = src[i + 5];
r0 = c[0] & 0x1f;
g0 = c[0] & 0x7e0;
b0 = c[0] & 0xf800;
r1 = c[1] & 0x1f;
g1 = c[1] & 0x7e0;
b1 = c[1] & 0xf800;
c[2] = ((5 * r0 + 3 * r1) >> 3) | (((5 * g0 + 3 * g1) >> 3) & 0x7e0) | (((5 * b0 + 3 * b1) >> 3) & 0xf800);
c[3] = ((5 * r1 + 3 * r0) >> 3) | (((5 * g1 + 3 * g0) >> 3) & 0x7e0) | (((5 * b1 + 3 * b0) >> 3) & 0xf800);
m = src[i + 6];
a = src[i];
dstI = (blockY * 16) * width + blockX * 16;
setRgba8888Dxt3(dst, dstI, c[bits & 0x3], a & 0xf);
setRgba8888Dxt3(dst, dstI + 4, c[(bits >> 2) & 0x3], (a >> 4) & 0xf);
setRgba8888Dxt3(dst, dstI + 8, c[(bits >> 4) & 0x3], (a >> 8) & 0xf);
setRgba8888Dxt3(dst, dstI + 12, c[(bits >> 6) & 0x3], (a >> 12) & 0xf);
dstI += width * 4;
a = src[i + 1];
setRgba8888Dxt3(dst, dstI, c[(bits >> 8) & 0x3], a & 0xf);
setRgba8888Dxt3(dst, dstI + 4, c[(bits >> 10) & 0x3], (a >> 4) & 0xf);
setRgba8888Dxt3(dst, dstI + 8, c[(bits >> 12) & 0x3], (a >> 8) & 0xf);
setRgba8888Dxt3(dst, dstI + 12, c[bits >> 14], (a >> 12) & 0xf);
m = src[i + 7];
a = src[i + 2];
dstI += width * 4;
setRgba8888Dxt3(dst, dstI, c[bits & 0x3], a & 0xf);
setRgba8888Dxt3(dst, dstI + 4, c[(bits >> 2) & 0x3], (a >> 4) & 0xf);
setRgba8888Dxt3(dst, dstI + 8, c[(bits >> 4) & 0x3], (a >> 8) & 0xf);
setRgba8888Dxt3(dst, dstI + 12, c[(bits >> 6) & 0x3], (a >> 12) & 0xf);
dstI += width * 4;
a = src[i + 3];
setRgba8888Dxt3(dst, dstI, c[(bits >> 8) & 0x3], a & 0xf);
setRgba8888Dxt3(dst, dstI + 4, c[(bits >> 10) & 0x3], (a >> 4) & 0xf);
setRgba8888Dxt3(dst, dstI + 8, c[(bits >> 12) & 0x3], (a >> 8) & 0xf);
setRgba8888Dxt3(dst, dstI + 12, c[bits >> 14], (a >> 12) & 0xf);
}
}
return dst;
}
function dxt5ToRgba8888(src, width, height) {
var c = new Uint16Array(4);
var a = new Uint8Array(8);
var alphaBits;
var dst = new Uint8Array(width * height * 4);
var m;
var a;
var dstI;
var i ;
var r0, g0, b0, r1, g1, b1;
var blockWidth = width / 4;
var blockHeight = height / 4;
for (var blockY = 0; blockY < blockHeight; blockY++) {
for (var blockX = 0; blockX < blockWidth; blockX++) {
i = 8 * (blockY * blockWidth + blockX);
c[0] = src[i + 4];
c[1] = src[i + 5];
r0 = c[0] & 0x1f;
g0 = c[0] & 0x7e0;
b0 = c[0] & 0xf800;
r1 = c[1] & 0x1f;
g1 = c[1] & 0x7e0;
b1 = c[1] & 0xf800;
c[2] = ((5 * r0 + 3 * r1) >> 3) | (((5 * g0 + 3 * g1) >> 3) & 0x7e0) | (((5 * b0 + 3 * b1) >> 3) & 0xf800);
c[3] = ((5 * r1 + 3 * r0) >> 3) | (((5 * g1 + 3 * g0) >> 3) & 0x7e0) | (((5 * b1 + 3 * b0) >> 3) & 0xf800);
alphaBits = src[i + 1] + 65536 * (src[i + 2] + 65536 * src[i + 3]);
a[0] = src[i] & 0xff;
a[1] = src[i] >> 8;
if (a[0] > a[1]) {
a[2] = (6 * a[0] + a[1]) / 7;
a[3] = (5 * a[0] + 2 * a[1]) / 7;
a[4] = (4 * a[0] + 3 * a[1]) / 7;
a[5] = (3 * a[0] + 4 * a[1]) / 7;
a[6] = (2 * a[0] + 5 * a[1]) / 7;
a[7] = (a[0] + 6 * a[1]) / 7;
} else {
a[2] = (4 * a[0] + a[1]) / 5;
a[3] = (3 * a[0] + 2 * a[1]) / 5;
a[4] = (2 * a[0] + 3 * a[1]) / 5;
a[5] = (a[0] + 4 * a[1]) / 5;
a[6] = 0;
a[7] = 1;
}
m = src[i + 6];
dstI = (blockY * 16) * width + blockX * 16;
setRgba8888Dxt5(dst, dstI, c[m & 0x3], a[alphaBits & 0x7]);
setRgba8888Dxt5(dst, dstI + 4, c[(m >> 2) & 0x3], a[(alphaBits >> 3) & 0x7]);
setRgba8888Dxt5(dst, dstI + 8, c[(m >> 4) & 0x3], a[(alphaBits >> 6) & 0x7]);
setRgba8888Dxt5(dst, dstI + 12, c[(m >> 6) & 0x3], a[(alphaBits >> 9) & 0x7]);
dstI += width * 4;
setRgba8888Dxt5(dst, dstI, c[(m >> 8) & 0x3], a[(alphaBits >> 12) & 0x7]);
setRgba8888Dxt5(dst, dstI + 4, c[(m >> 10) & 0x3], a[(alphaBits >> 15) & 0x7]);
setRgba8888Dxt5(dst, dstI + 8, c[(m >> 12) & 0x3], a[(alphaBits >> 18) & 0x7]);
setRgba8888Dxt5(dst, dstI + 12, c[m >> 14], a[(alphaBits >> 21) & 0x7]);
m = src[i + 7];
dstI += width * 4;
setRgba8888Dxt5(dst, dstI, c[m & 0x3], a[(alphaBits >> 24) & 0x7]);
setRgba8888Dxt5(dst, dstI + 4, c[(m >> 2) & 0x3], a[(alphaBits >> 27) & 0x7]);
setRgba8888Dxt5(dst, dstI + 8, c[(m >> 4) & 0x3], a[(alphaBits >> 30) & 0x7]);
setRgba8888Dxt5(dst, dstI + 12, c[(m >> 6) & 0x3],a[(alphaBits >> 33) & 0x7]);
dstI += width * 4;
setRgba8888Dxt5(dst, dstI, c[(m >> 8) & 0x3], a[(alphaBits >> 36) & 0x7]);
setRgba8888Dxt5(dst, dstI + 4, c[(m >> 10) & 0x3], a[(alphaBits >> 39) & 0x7]);
setRgba8888Dxt5(dst, dstI + 8, c[(m >> 12) & 0x3], a[(alphaBits >> 42) & 0x7]);
setRgba8888Dxt5(dst, dstI + 12, c[m >> 14], a[(alphaBits >> 45) & 0x7]);
}
}
return dst;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment