public static byte[] DecompressImage(int width, int height, byte[] data, DXT_Flags flags) { byte[] rgba = new byte[width * height * 4]; // initialise the block input int sourceBlock_pos = 0; int bytesPerBlock = (flags & DXT_Flags.DXT1) != 0 ? 8 : 16; byte[] targetRGBA = new byte[4 * 16]; // loop over blocks for (int y = 0; y < height; y += 4) { for (int x = 0; x < width; x += 4) { // decompress the block int targetRGBA_pos = 0; if (data.Length == sourceBlock_pos) { continue; } Decompress(targetRGBA, data, sourceBlock_pos, flags); // Write the decompressed pixels to the correct image locations for (int py = 0; py < 4; py++) { for (int px = 0; px < 4; px++) { int sx = x + px; int sy = y + py; if (sx < width && sy < height) { int targetPixel = 4 * (width * sy + sx); rgba[targetPixel + 0] = targetRGBA[targetRGBA_pos + 0]; rgba[targetPixel + 1] = targetRGBA[targetRGBA_pos + 1]; rgba[targetPixel + 2] = targetRGBA[targetRGBA_pos + 2]; rgba[targetPixel + 3] = targetRGBA[targetRGBA_pos + 3]; targetRGBA_pos += 4; } else { // Ignore that pixel targetRGBA_pos += 4; } } } sourceBlock_pos += bytesPerBlock; } } return(rgba); }
private static void Decompress(byte[] rgba, byte[] block, int blockIndex, DXT_Flags flags) { // get the block locations int colorBlockIndex = blockIndex; if ((flags & (DXT_Flags.DXT3 | DXT_Flags.DXT5)) != 0) { colorBlockIndex += 8; } // decompress color DecompressColor(rgba, block, colorBlockIndex, (flags & DXT_Flags.DXT1) != 0); // decompress alpha separately if necessary if ((flags & DXT_Flags.DXT3) != 0) { DecompressAlphaDxt3(rgba, block, blockIndex); } else if ((flags & DXT_Flags.DXT5) != 0) { DecompressAlphaDxt5(rgba, block, blockIndex); } }