public static DdsFormat MakeSrgb(DdsFormat format) { switch (format) { case DdsFormat.R8G8B8A8UNorm: return(DdsFormat.R8G8B8A8UNormSrgb); case DdsFormat.BC1UNorm: return(DdsFormat.BC1UNormSrgb); case DdsFormat.BC2UNorm: return(DdsFormat.BC2UNormSrgb); case DdsFormat.BC3UNorm: return(DdsFormat.BC3UNormSrgb); case DdsFormat.B8G8R8A8UNorm: return(DdsFormat.B8G8R8A8UNormSrgb); case DdsFormat.B8G8R8X8UNorm: return(DdsFormat.B8G8R8X8UNormSrgb); case DdsFormat.BC7UNorm: return(DdsFormat.BC7UNormSrgb); default: return(format); } }
public static Bitmap ToBitmap(byte[] d, int width, int height, DdsFormat format) { byte[] pixels = new byte[width * height * 4]; if (format == DdsFormat.Dxt1) { DecodeDxt1(pixels, d, width, height); } if (format == DdsFormat.Dxt3) { DecodeDxt3(pixels, d, width, height); } if (format == DdsFormat.Dxt5) { DecodeDxt5(pixels, d, width, height); } Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); BitmapData bmpData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat); Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length); bmp.UnlockBits(bmpData); return(bmp); }
uint[] baseImage; //ARGB uint array #endregion public Dds(DdsFormat ddsFormat, int width, int height, uint[] imageData) { if (imageData.Length != width * height) throw new ArgumentException("Image data must contain width * height elements"); header = new DdsHeader(ddsFormat, width, height); baseImage = (uint[])imageData.Clone(); }
uint aBitMask;//104 public DdsPixelFormat(DdsFormat ddsFormat) { if (!Enum.IsDefined(typeof(DdsFormat), ddsFormat)) throw new ArgumentException(String.Format("Requested DDS format 0x{0:8X} is unsupported", (uint)ddsFormat)); size = 32; flags = 0; fourCC = 0; rgbBitCount = rBitMask = gBitMask = bBitMask = gBitMask = 0; switch (ddsFormat) { case DdsFormat.DXT1: flags |= PFFlags.fourCC; fourCC = PFFourCC.dxt1; break; case DdsFormat.DXT3: flags |= PFFlags.fourCC; fourCC = PFFourCC.dxt3; break; case DdsFormat.DXT5: flags |= PFFlags.fourCC; fourCC = PFFourCC.dxt5; break; case DdsFormat.A8L8: flags |= PFFlags.luminence | PFFlags.alphaPixels; rgbBitCount = 16; aBitMask = 0x0000ff00; rBitMask = 0x000000ff; break; case DdsFormat.A8R8G8B8: flags |= PFFlags.rgb | PFFlags.alphaPixels; rgbBitCount = 32; aBitMask = 0xff000000; rBitMask = 0x00ff0000; gBitMask = 0x0000ff00; bBitMask = 0x000000ff; break; case DdsFormat.X8R8G8B8: flags |= PFFlags.rgb; rgbBitCount = 32; rBitMask = 0x00ff0000; gBitMask = 0x0000ff00; bBitMask = 0x000000ff; break; case DdsFormat.A8B8G8R8: flags |= PFFlags.rgb | PFFlags.alphaPixels; rgbBitCount = 32; aBitMask = 0xff000000; rBitMask = 0x000000ff; gBitMask = 0x0000ff00; bBitMask = 0x00ff0000; break; case DdsFormat.X8B8G8R8: flags |= PFFlags.rgb; rgbBitCount = 32; rBitMask = 0x000000ff; gBitMask = 0x0000ff00; bBitMask = 0x00ff0000; break; case DdsFormat.R8G8B8: flags |= PFFlags.rgb; rgbBitCount = 24; rBitMask = 0x00ff0000; gBitMask = 0x0000ff00; bBitMask = 0x000000ff; break; case DdsFormat.A4R4G4B4: flags |= PFFlags.rgb | PFFlags.alphaPixels; rgbBitCount = 16; aBitMask = 0x0000f000; rBitMask = 0x00000f00; gBitMask = 0x000000f0; bBitMask = 0x0000000f; break; case DdsFormat.A1R5G5B5: flags |= PFFlags.rgb | PFFlags.alphaPixels; rgbBitCount = 16; aBitMask = 0x00008000; rBitMask = 0x00007c00; gBitMask = 0x000003e0; bBitMask = 0x0000001f; break; case DdsFormat.R5G6B5: flags |= PFFlags.rgb; rgbBitCount = 16; rBitMask = 0x0000f800; gBitMask = 0x000007e0; bBitMask = 0x0000001f; break; default: throw new ArgumentOutOfRangeException("Unsupported DDS format."); } }
uint reserved2;//124 #endregion public DdsHeader(DdsFormat ddsFormat, int width, int height) { this.magic = DdsMagic.dds_; this.size = 124; //flags this.height = (uint)height; this.width = (uint)width; //pitchOrLinearSize this.depth = 0; this.numMipMaps = 0; for (int i = 0; i < reserved1.Length; i++) this.reserved1[i] = 0; this.pixelFormat = new DdsPixelFormat(ddsFormat); this.surfaceCaps = DdsSurfaceCaps.texture; this.cubeMapCaps = 0; this.unusedCaps3 = 0; this.unusedCaps4 = 0; this.reserved2 = 0; this.flags = writeFlags | (IsBlockCompressed ? DdsFlags.linearSize : DdsFlags.pitch); this.pitchOrLinearSize = IsBlockCompressed ? LinearSize : Pitch; }
public static int GetBitsPerPixel(DdsFormat format) { switch (format) { case DdsFormat.R32G32B32A32Typeless: case DdsFormat.R32G32B32A32Float: case DdsFormat.R32G32B32A32UInt: case DdsFormat.R32G32B32A32SInt: return(128); case DdsFormat.R32G32B32Typeless: case DdsFormat.R32G32B32Float: case DdsFormat.R32G32B32UInt: case DdsFormat.R32G32B32SInt: return(96); case DdsFormat.R16G16B16A16Typeless: case DdsFormat.R16G16B16A16Float: case DdsFormat.R16G16B16A16UNorm: case DdsFormat.R16G16B16A16UInt: case DdsFormat.R16G16B16A16SNorm: case DdsFormat.R16G16B16A16SInt: case DdsFormat.R32G32Typeless: case DdsFormat.R32G32Float: case DdsFormat.R32G32UInt: case DdsFormat.R32G32SInt: case DdsFormat.R32G8X24Typeless: case DdsFormat.D32FloatS8X24UInt: case DdsFormat.R32FloatX8X24Typeless: case DdsFormat.X32TypelessG8X24UInt: case DdsFormat.Y416: case DdsFormat.Y210: case DdsFormat.Y216: return(64); case DdsFormat.R10G10B10A2Typeless: case DdsFormat.R10G10B10A2UNorm: case DdsFormat.R10G10B10A2UInt: case DdsFormat.R11G11B10Float: case DdsFormat.R8G8B8A8Typeless: case DdsFormat.R8G8B8A8UNorm: case DdsFormat.R8G8B8A8UNormSrgb: case DdsFormat.R8G8B8A8UInt: case DdsFormat.R8G8B8A8SNorm: case DdsFormat.R8G8B8A8SInt: case DdsFormat.R16G16Typeless: case DdsFormat.R16G16Float: case DdsFormat.R16G16UNorm: case DdsFormat.R16G16UInt: case DdsFormat.R16G16SNorm: case DdsFormat.R16G16SInt: case DdsFormat.R32Typeless: case DdsFormat.D32Float: case DdsFormat.R32Float: case DdsFormat.R32UInt: case DdsFormat.R32SInt: case DdsFormat.R24G8Typeless: case DdsFormat.D24UNormS8UInt: case DdsFormat.R24UNormX8Typeless: case DdsFormat.X24TypelessG8UInt: case DdsFormat.R9G9B9E5SharedExp: case DdsFormat.R8G8B8G8UNorm: case DdsFormat.G8R8G8B8UNorm: case DdsFormat.B8G8R8A8UNorm: case DdsFormat.B8G8R8X8UNorm: case DdsFormat.R10G10B10XRBiasA2UNorm: case DdsFormat.B8G8R8A8Typeless: case DdsFormat.B8G8R8A8UNormSrgb: case DdsFormat.B8G8R8X8Typeless: case DdsFormat.B8G8R8X8UNormSrgb: case DdsFormat.AYuv: case DdsFormat.Y410: case DdsFormat.Yuy2: return(32); case DdsFormat.P010: case DdsFormat.P016: return(24); case DdsFormat.R8G8Typeless: case DdsFormat.R8G8UNorm: case DdsFormat.R8G8UInt: case DdsFormat.R8G8SNorm: case DdsFormat.R8G8SInt: case DdsFormat.R16Typeless: case DdsFormat.R16Float: case DdsFormat.D16UNorm: case DdsFormat.R16UNorm: case DdsFormat.R16UInt: case DdsFormat.R16SNorm: case DdsFormat.R16SInt: case DdsFormat.B5G6R5UNorm: case DdsFormat.B5G5R5A1UNorm: case DdsFormat.A8P8: case DdsFormat.B4G4R4A4UNorm: return(16); case DdsFormat.NV12: case DdsFormat.P420Opaque: case DdsFormat.NV11: return(12); case DdsFormat.R8Typeless: case DdsFormat.R8UNorm: case DdsFormat.R8UInt: case DdsFormat.R8SNorm: case DdsFormat.R8SInt: case DdsFormat.A8UNorm: case DdsFormat.AI44: case DdsFormat.IA44: case DdsFormat.P8: return(8); case DdsFormat.R1UNorm: return(1); case DdsFormat.BC1Typeless: case DdsFormat.BC1UNorm: case DdsFormat.BC1UNormSrgb: case DdsFormat.BC4Typeless: case DdsFormat.BC4UNorm: case DdsFormat.BC4SNorm: return(4); case DdsFormat.BC2Typeless: case DdsFormat.BC2UNorm: case DdsFormat.BC2UNormSrgb: case DdsFormat.BC3Typeless: case DdsFormat.BC3UNorm: case DdsFormat.BC3UNormSrgb: case DdsFormat.BC5Typeless: case DdsFormat.BC5UNorm: case DdsFormat.BC5SNorm: case DdsFormat.BC6HalfTypeless: case DdsFormat.BC6HalfUF16: case DdsFormat.BC6HalfSF16: case DdsFormat.BC7Typeless: case DdsFormat.BC7UNorm: case DdsFormat.BC7UNormSrgb: return(8); default: return(0); } }
public static void GetSurfaceInfo(int width, int height, DdsFormat format, out int outNumBytes, out int outRowBytes, out int outNumRows) { bool bc = false; bool packed = false; bool planar = false; int bpe = 0; switch (format) { case DdsFormat.BC1Typeless: case DdsFormat.BC1UNorm: case DdsFormat.BC1UNormSrgb: case DdsFormat.BC4Typeless: case DdsFormat.BC4UNorm: case DdsFormat.BC4SNorm: bc = true; bpe = 8; break; case DdsFormat.BC2Typeless: case DdsFormat.BC2UNorm: case DdsFormat.BC2UNormSrgb: case DdsFormat.BC3Typeless: case DdsFormat.BC3UNorm: case DdsFormat.BC3UNormSrgb: case DdsFormat.BC5Typeless: case DdsFormat.BC5UNorm: case DdsFormat.BC5SNorm: case DdsFormat.BC6HalfTypeless: case DdsFormat.BC6HalfUF16: case DdsFormat.BC6HalfSF16: case DdsFormat.BC7Typeless: case DdsFormat.BC7UNorm: case DdsFormat.BC7UNormSrgb: bc = true; bpe = 16; break; case DdsFormat.R8G8B8G8UNorm: case DdsFormat.G8R8G8B8UNorm: case DdsFormat.Yuy2: packed = true; bpe = 4; break; case DdsFormat.Y210: case DdsFormat.Y216: packed = true; bpe = 8; break; case DdsFormat.NV12: case DdsFormat.P420Opaque: planar = true; bpe = 2; break; case DdsFormat.P010: case DdsFormat.P016: planar = true; bpe = 4; break; } int rowBytes; int numRows; int numBytes; if (bc) { int numBlocksWide = 0; if (width > 0) { numBlocksWide = Math.Max(1, (width + 3) / 4); } int numBlocksHigh = 0; if (height > 0) { numBlocksHigh = Math.Max(1, (height + 3) / 4); } rowBytes = numBlocksWide * bpe; numRows = numBlocksHigh; numBytes = rowBytes * numBlocksHigh; } else if (packed) { rowBytes = ((width + 1) >> 1) * bpe; numRows = height; numBytes = rowBytes * height; } else if (format == DdsFormat.NV11) { rowBytes = ((width + 3) >> 2) * 4; numRows = height * 2; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data numBytes = rowBytes * numRows; } else if (planar) { rowBytes = ((width + 1) >> 1) * bpe; numBytes = (rowBytes * height) + ((rowBytes * height + 1) >> 1); numRows = height + ((height + 1) >> 1); } else { int bpp = DdsHelpers.GetBitsPerPixel(format); rowBytes = (width * bpp + 7) / 8; // round up to nearest byte numRows = height; numBytes = rowBytes * height; } outNumBytes = numBytes; outRowBytes = rowBytes; outNumRows = numRows; }