Ejemplo n.º 1
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;
        }
Ejemplo n.º 2
0
        public static DdsFile FromStream(Stream stream)
        {
            DdsFile dds = new DdsFile();

            BinaryReader file = new BinaryReader(stream);

            int magic = file.ReadInt32();

            if (magic != DdsFile.DdsMagic)
            {
                throw new InvalidDataException();
            }

            if (file.ReadInt32() != 124)
            {
                throw new InvalidDataException();
            }

            dds.Options     = (DdsOptions)file.ReadInt32();
            dds.Height      = file.ReadInt32();
            dds.Width       = file.ReadInt32();
            dds.LinearSize  = file.ReadInt32();
            dds.Depth       = file.ReadInt32();
            dds.MipmapCount = file.ReadInt32();

            file.BaseStream.Position += 44;

            if (file.ReadInt32() != 32)
            {
                throw new InvalidDataException();
            }

            dds.PixelFormat.Options      = (DdsPixelFormatOptions)file.ReadInt32();
            dds.PixelFormat.FourCC       = (DdsFourCC)file.ReadInt32();
            dds.PixelFormat.RgbBitCount  = file.ReadInt32();
            dds.PixelFormat.RedBitMask   = file.ReadUInt32();
            dds.PixelFormat.GreenBitMask = file.ReadUInt32();
            dds.PixelFormat.BlueBitMask  = file.ReadUInt32();
            dds.PixelFormat.AlphaBitMask = file.ReadUInt32();

            dds.Caps  = (DdsCaps)file.ReadInt32();
            dds.Caps2 = (DdsAdditionalCaps)file.ReadInt32();

            file.BaseStream.Position += 12;

            if ((dds.PixelFormat.Options & DdsPixelFormatOptions.FourCC) != 0 && dds.PixelFormat.FourCC == DdsFourCC.DX10)
            {
                dds.Format              = (DdsFormat)file.ReadInt32();
                dds.ResourceDimension   = (DdsResourceDimension)file.ReadInt32();
                dds.ResourceMiscOptions = (DdsResourceMiscOptions)file.ReadInt32();
                dds.ArraySize           = file.ReadInt32();

                DdsAlphaMode mode = (DdsAlphaMode)(file.ReadInt32() & 0x7);
                switch (mode)
                {
                case DdsAlphaMode.Straight:
                case DdsAlphaMode.Premultiplied:
                case DdsAlphaMode.Opaque:
                case DdsAlphaMode.Custom:
                    dds.AlphaMode = mode;
                    break;
                }
            }
            else
            {
                dds.Format = DdsHelpers.GetDdsFormat(dds.PixelFormat);

                if ((dds.PixelFormat.Options & DdsPixelFormatOptions.FourCC) != 0)
                {
                    switch (dds.PixelFormat.FourCC)
                    {
                    case DdsFourCC.DXT2:
                    case DdsFourCC.DXT4:
                        dds.AlphaMode = DdsAlphaMode.Premultiplied;
                        break;
                    }
                }
            }

            dds.DataOffset = (int)file.BaseStream.Position;
            dds.Data       = file.ReadBytes((int)file.BaseStream.Length - (int)file.BaseStream.Position);

            return(dds);
        }