public static byte[] DecompressImage(int width, int height, byte[] data, DXTFlags flags) { var rgba = new byte[width * height * 4]; // initialise the block input var sourceBlock_pos = 0; var bytesPerBlock = (flags & DXTFlags.DXT1) != 0 ? 8 : 16; var targetRGBA = new byte[4 * 16]; // loop over blocks for (var y = 0; y < height; y += 4) { for (var x = 0; x < width; x += 4) { // decompress the block var 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 (var py = 0; py < 4; py++) { for (var px = 0; px < 4; px++) { var sx = x + px; var sy = y + py; if (sx < width && sy < height) { var 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); }
public static byte[] DecompressImage(int width, int height, byte[] data, DXTFlags flags) { byte[] rgba = new byte[width * height * 4]; // initialise the block input int sourceBlock_pos = 0; int bytesPerBlock = (flags & DXTFlags.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, DXTFlags flags) { // get the block locations int colorBlockIndex = blockIndex; if ((flags & (DXTFlags.DXT3 | DXTFlags.DXT5)) != 0) { colorBlockIndex += 8; } // decompress color DecompressColor(rgba, block, colorBlockIndex, (flags & DXTFlags.DXT1) != 0); // decompress alpha separately if necessary if ((flags & DXTFlags.DXT3) != 0) { DecompressAlphaDxt3(rgba, block, blockIndex); } else if ((flags & DXTFlags.DXT5) != 0) { DecompressAlphaDxt5(rgba, block, blockIndex); } }
public static Rgba32[] DecompressImage(int width, int height, ReadOnlySpan <byte> data, DXTFlags flags) { Rgba32[] rgba = new Rgba32[width * height]; // initialise the block input int sourceBlock_pos = 0; int bytesPerBlock = (flags & DXTFlags.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 = (width * sy + sx); rgba[targetPixel + 0] = new Rgba32(targetRGBA[targetRGBA_pos + 0], targetRGBA[targetRGBA_pos + 1], targetRGBA[targetRGBA_pos + 2], 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, DXTFlags flags) { // get the block locations int colorBlockIndex = blockIndex; if ((flags & (DXTFlags.DXT3 | DXTFlags.DXT5)) != 0) colorBlockIndex += 8; // decompress color DecompressColor(rgba, block, colorBlockIndex, (flags & DXTFlags.DXT1) != 0); // decompress alpha separately if necessary if ((flags & DXTFlags.DXT3) != 0) DecompressAlphaDxt3(rgba, block, blockIndex); else if ((flags & DXTFlags.DXT5) != 0) DecompressAlphaDxt5(rgba, block, blockIndex); }