private void DecompressDXT3() { Colour8888[] colours = new Colour8888[4]; uint bitmask, offset; int i, j, k, x, y, z, Select; ushort word, colour0, colour1; byte[] alpha; //temp; MemoryStream mem = new MemoryStream(this.compdata.Length); mem.Write(this.compdata, 0, this.compdata.Length); mem.Seek(0, SeekOrigin.Begin); BinaryReader r = new BinaryReader(mem); for (z=0; z<this.depth; z++) { for (y=0; y<this.height; y+=4) { for (x=0; x<this.width; x+=4) { alpha = r.ReadBytes(8); colour0 = r.ReadUInt16(); colour1 = r.ReadUInt16(); this.ReadColour(colour0, ref colours[0]); this.ReadColour(colour1, ref colours[1]); bitmask = r.ReadUInt32(); colours[2].b = (byte)((2 * colours[0].b + colours[1].b + 1) / 3); colours[2].g = (byte)((2 * colours[0].g + colours[1].g + 1) / 3); colours[2].r = (byte)((2 * colours[0].r + colours[1].r + 1) / 3); colours[3].b = (byte)((colours[0].b + 2 * colours[1].b + 1) / 3); colours[3].g = (byte)((colours[0].g + 2 * colours[1].g + 1) / 3); colours[3].r = (byte)((colours[0].r + 2 * colours[1].r + 1) / 3); for (j = 0, k = 0; j < 4; j++) { for (i = 0; i < 4; k++, i++) { Select = (int)((bitmask & (0x03 << k*2)) >> k*2); if (((x + i) < this.width) && ((y + j) < this.height)) { offset = (uint)(z * this.sizeofplane + (y + j) * this.bps + (x + i) * this.bpp); this.rawidata[offset] = (byte)colours[Select].r; this.rawidata[offset + 1] = (byte)colours[Select].g; this.rawidata[offset + 2] = (byte)colours[Select].b; } } } for (j = 0; j < 4; j++) { word = (ushort)(alpha[2*j] + 256*alpha[2*j+1]); for (i = 0; i < 4; i++) { if (((x + i) < this.width) && ((y + j) < this.height)) { offset = (uint)(z * this.sizeofplane + (y + j) * this.bps + (x + i) * this.bpp + 3); this.rawidata[offset] = (byte)(word & 0x0F); this.rawidata[offset] = (byte)(this.rawidata[offset] | (this.rawidata[offset] << 4)); } word >>= 4; } } } } } }
private void ReadColour(ushort Data, ref Colour8888 op) { byte r, g, b; b = (byte)(Data & 0x1f); g = (byte)((Data & 0x7E0) >> 5); r = (byte)((Data & 0xF800) >> 11); op.r = (byte)(r * 255 / 31); op.g = (byte)(g * 255 / 63); op.b = (byte)(b * 255 / 31); }
private void DecompressDXT1() { // DXT1 decompressor Colour8888[] colours = new Colour8888[4]; ushort colour0, colour1; uint bitmask, offset; int i, j, k, x, y, z, Select; MemoryStream mem = new MemoryStream(this.compdata.Length); mem.Write(this.compdata, 0, this.compdata.Length); mem.Seek(0, SeekOrigin.Begin); BinaryReader r = new BinaryReader(mem); colours[0].a = 255; colours[1].a = 255; colours[2].a = 255; for (z=0; z<this.depth; z++) { for (y=0; y<this.height; y+=4) { for (x=0; x<this.width; x+=4) { colour0 = r.ReadUInt16(); colour1 = r.ReadUInt16(); this.ReadColour(colour0, ref colours[0]); this.ReadColour(colour1, ref colours[1]); bitmask = r.ReadUInt32(); if (colour0 > colour1) { // Four-color block: derive the other two colors. // 00 = color_0, 01 = color_1, 10 = color_2, 11 = color_3 // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours[2].b = (byte)((2 * colours[0].b + colours[1].b + 1) / 3); colours[2].g = (byte)((2 * colours[0].g + colours[1].g + 1) / 3); colours[2].r = (byte)((2 * colours[0].r + colours[1].r + 1) / 3); colours[3].b = (byte)((colours[0].b + 2 * colours[1].b + 1) / 3); colours[3].g = (byte)((colours[0].g + 2 * colours[1].g + 1) / 3); colours[3].r = (byte)((colours[0].r + 2 * colours[1].r + 1) / 3); colours[3].a = 0xFF; } else { // Three-color block: derive the other color. // 00 = color_0, 01 = color_1, 10 = color_2, // 11 = transparent. // These 2-bit codes correspond to the 2-bit fields // stored in the 64-bit block. colours[2].b = (byte)((colours[0].b + colours[1].b) / 2); colours[2].g = (byte)((colours[0].g + colours[1].g) / 2); colours[2].r = (byte)((colours[0].r + colours[1].r) / 2); colours[3].b = 0; colours[3].g = 0; colours[3].r = 0; colours[3].a = 0; } for (j = 0, k = 0; j < 4; j++) { for (i = 0; i < 4; i++, k++) { Select = (int)((bitmask & (0x03 << k*2)) >> k*2); if (((x + i) < this.width) && ((y + j) < this.height)) { offset = (uint)(z * this.sizeofplane + (y + j) * this.bps + (x + i) * this.bpp); this.rawidata[offset] = (byte)colours[Select].r; this.rawidata[offset + 1] = (byte)colours[Select].g; this.rawidata[offset + 2] = (byte)colours[Select].b; this.rawidata[offset + 3] = (byte)colours[Select].a; } } } } } } }