protected static Color[,] GetDXT1ColourBlock(SubStream data, int offset, bool IsDXT3) { ushort c0v = data.GetUInt16(offset); ushort c1v = data.GetUInt16(offset + 2); Color[] c = new Color[4]; c[0] = Color.FromArgb(0xFF, (c0v >> 8) & 0xF8, (c0v >> 3) & 0xFC, (c0v << 3) & 0xF8); c[1] = Color.FromArgb(0xFF, (c1v >> 8) & 0xF8, (c1v >> 3) & 0xFC, (c1v << 3) & 0xF8); if (c0v > c1v || IsDXT3) { c[2] = Color.FromArgb(0xFF, ((int)c[0].R * 2 + c[1].R + 1) / 3, ((int)c[0].G * 2 + c[1].G + 1) / 3, ((int)c[0].B * 2 + c[1].B + 1) / 3); c[3] = Color.FromArgb(0xFF, ((int)c[1].R * 2 + c[0].R + 1) / 3, ((int)c[1].G * 2 + c[0].G + 1) / 3, ((int)c[1].B * 2 + c[0].B + 1) / 3); } else { c[2] = Color.FromArgb(0xFF, ((int)c[0].R + c[1].R) / 2, ((int)c[0].G + c[1].G) / 2, ((int)c[0].B + c[1].B) / 2); c[3] = Color.FromArgb(0, 0, 0, 0); } ulong lookup = data.GetUInt32(offset + 4); Color[,] output = new Color[4, 4]; for (int i = 0; i < 16; i++) { output[i % 4, i / 4] = c[(lookup >> (i * 2)) & 3]; } return(output); }
protected static Color[,] GetDXT1ColourBlock(SubStream data, int offset, bool IsDXT3) { ushort c0v = data.GetUInt16(offset); ushort c1v = data.GetUInt16(offset + 2); Color[] c = new Color[4]; c[0] = Color.FromArgb(0xFF, (c0v >> 8) & 0xF8, (c0v >> 3) & 0xFC, (c0v << 3) & 0xF8); c[1] = Color.FromArgb(0xFF, (c1v >> 8) & 0xF8, (c1v >> 3) & 0xFC, (c1v << 3) & 0xF8); if (c0v > c1v || IsDXT3) { c[2] = Color.FromArgb(0xFF, ((int)c[0].R * 2 + c[1].R + 1) / 3, ((int)c[0].G * 2 + c[1].G + 1) / 3, ((int)c[0].B * 2 + c[1].B + 1) / 3); c[3] = Color.FromArgb(0xFF, ((int)c[1].R * 2 + c[0].R + 1) / 3, ((int)c[1].G * 2 + c[0].G + 1) / 3, ((int)c[1].B * 2 + c[0].B + 1) / 3); } else { c[2] = Color.FromArgb(0xFF, ((int)c[0].R + c[1].R) / 2, ((int)c[0].G + c[1].G) / 2, ((int)c[0].B + c[1].B) / 2); c[3] = Color.FromArgb(0, 0, 0, 0); } ulong lookup = data.GetUInt32(offset + 4); Color[,] output = new Color[4, 4]; for (int i = 0; i < 16; i++) { output[i % 4, i / 4] = c[(lookup >> (i * 2)) & 3]; } return output; }
protected static Bitmap GetBitmapFromDDS_ARGB16F(SubStream data, int offset, int width, int height, out bool hasalpha, out double intensity) { float[] fdata = new float[width * height * 4]; double maxval = Double.NegativeInfinity; double minval = Double.PositiveInfinity; double maxalpha = Double.NegativeInfinity; double minalpha = Double.PositiveInfinity; double alphaoffset = 0.0; hasalpha = false; for (int i = 0; i < width * height * 4; i+=4) { for (int j = 0; j < 4; j++) { fdata[i + j] = HalfToFloat(data.GetUInt16(offset + (i + j) * 2)); } for (int j = 0; j < 3; j++) { if (fdata[i + j] > maxval) { maxval = fdata[i + j]; } if (fdata[i + j] < minval) { minval = fdata[i + j]; } } if (fdata[i + 3] > maxalpha) { maxalpha = fdata[i + 3]; } if (fdata[i + 3] < minalpha) { minalpha = fdata[i + 3]; } } if (minval < 0 || minalpha < 0) { throw new NotImplementedException("ARGB16F with negative values not supported"); } if (maxval == 0) { maxval = 1.0; } if (maxalpha == 0) { maxalpha = 1.0; //alphaoffset = 1.0; } intensity = maxval; Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); byte[] bmpraw = new byte[width * height * 4]; for (int i = 0; i < width * height * 4; i += 4) { bmpraw[i + 0] = (byte)(fdata[i + 2] * 255 / maxval); bmpraw[i + 1] = (byte)(fdata[i + 1] * 255 / maxval); bmpraw[i + 2] = (byte)(fdata[i + 0] * 255 / maxval); bmpraw[i + 3] = (byte)((fdata[i + 3] + alphaoffset) * 255 / maxalpha); hasalpha |= bmpraw[i + 3] != 255; } BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); for (int y = 0; y < height; y++) { Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4); } bmp.UnlockBits(bmpdata); return bmp; }
protected static Bitmap GetBitmapFromDDS_ARGB16F(SubStream data, int offset, int width, int height, out bool hasalpha, out double intensity) { float[] fdata = new float[width * height * 4]; double maxval = Double.NegativeInfinity; double minval = Double.PositiveInfinity; double maxalpha = Double.NegativeInfinity; double minalpha = Double.PositiveInfinity; double alphaoffset = 0.0; hasalpha = false; for (int i = 0; i < width * height * 4; i += 4) { for (int j = 0; j < 4; j++) { fdata[i + j] = HalfToFloat(data.GetUInt16(offset + (i + j) * 2)); } for (int j = 0; j < 3; j++) { if (fdata[i + j] > maxval) { maxval = fdata[i + j]; } if (fdata[i + j] < minval) { minval = fdata[i + j]; } } if (fdata[i + 3] > maxalpha) { maxalpha = fdata[i + 3]; } if (fdata[i + 3] < minalpha) { minalpha = fdata[i + 3]; } } if (minval < 0 || minalpha < 0) { throw new NotImplementedException("ARGB16F with negative values not supported"); } if (maxval == 0) { maxval = 1.0; } if (maxalpha == 0) { maxalpha = 1.0; //alphaoffset = 1.0; } intensity = maxval; Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb); byte[] bmpraw = new byte[width * height * 4]; for (int i = 0; i < width * height * 4; i += 4) { bmpraw[i + 0] = (byte)(fdata[i + 2] * 255 / maxval); bmpraw[i + 1] = (byte)(fdata[i + 1] * 255 / maxval); bmpraw[i + 2] = (byte)(fdata[i + 0] * 255 / maxval); bmpraw[i + 3] = (byte)((fdata[i + 3] + alphaoffset) * 255 / maxalpha); hasalpha |= bmpraw[i + 3] != 255; } BitmapData bmpdata = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); for (int y = 0; y < height; y++) { Marshal.Copy(bmpraw, y * width * 4, bmpdata.Scan0 + y * bmpdata.Stride, width * 4); } bmp.UnlockBits(bmpdata); return(bmp); }