CSharpImageLibrary.Headers.DDS_Header.WriteToArray C# (CSharp) Метод

WriteToArray() публичный Метод

Writes header to destination array starting at index.
public WriteToArray ( byte destination, int index ) : void
destination byte Array to write header to.
index int Index in destination to start writing at.
Результат void
        public void WriteToArray(byte[] destination, int index)
        {
            List<byte> headerData = new List<byte>(150);

            // KFreon: Write magic number ("DDS")
            headerData.AddRange(BitConverter.GetBytes(0x20534444));

            // KFreon: Write all header fields regardless of filled or not
            headerData.AddRange(BitConverter.GetBytes(dwSize));
            headerData.AddRange(BitConverter.GetBytes((int)dwFlags));
            headerData.AddRange(BitConverter.GetBytes(Height));
            headerData.AddRange(BitConverter.GetBytes(Width));
            headerData.AddRange(BitConverter.GetBytes(dwPitchOrLinearSize));
            headerData.AddRange(BitConverter.GetBytes(dwDepth));
            headerData.AddRange(BitConverter.GetBytes(dwMipMapCount));

            // KFreon: Write reserved1
            for (int i = 0; i < 11; i++)
                headerData.AddRange(BitConverter.GetBytes((int)0));

            // KFreon: Write PIXELFORMAT
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwSize));
            headerData.AddRange(BitConverter.GetBytes((int)ddspf.dwFlags));
            headerData.AddRange(BitConverter.GetBytes((int)ddspf.dwFourCC));
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwRGBBitCount));
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwRBitMask));
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwGBitMask));
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwBBitMask));
            headerData.AddRange(BitConverter.GetBytes(ddspf.dwABitMask));

            headerData.AddRange(BitConverter.GetBytes((int)dwCaps));
            headerData.AddRange(BitConverter.GetBytes(dwCaps2));
            headerData.AddRange(BitConverter.GetBytes(dwCaps3));
            headerData.AddRange(BitConverter.GetBytes(dwCaps4));
            headerData.AddRange(BitConverter.GetBytes(dwReserved2));

            headerData.CopyTo(destination, index);
        }

Usage Example

Пример #1
0
        internal static byte[] Save(List<MipMap> mipMaps, ImageEngineFormat saveFormat, AlphaSettings alphaSetting, List<uint> customMasks = null)
        {
            // Set compressor for Block Compressed textures
            Action<byte[], int, int, byte[], int, AlphaSettings> compressor = null;

            bool needCheckSize = saveFormat.ToString().Contains("DXT") || saveFormat.ToString().Contains("ATI");

            switch (saveFormat)
            {
                case ImageEngineFormat.DDS_ATI1:
                    compressor = DDS_Encoders.CompressBC4Block;
                    break;
                case ImageEngineFormat.DDS_ATI2_3Dc:
                    compressor = DDS_Encoders.CompressBC5Block;
                    break;
                case ImageEngineFormat.DDS_DX10:
                    Debugger.Break();
                    break; // TODO: NOT SUPPORTED YET. DX10
                case ImageEngineFormat.DDS_DXT1:
                    compressor = DDS_Encoders.CompressBC1Block;
                    break;
                case ImageEngineFormat.DDS_DXT2:
                case ImageEngineFormat.DDS_DXT3:
                    compressor = DDS_Encoders.CompressBC2Block;
                    break;
                case ImageEngineFormat.DDS_DXT4:
                case ImageEngineFormat.DDS_DXT5:
                    compressor = DDS_Encoders.CompressBC3Block;
                    break;
            }

            int height = mipMaps[0].Height;
            int width = mipMaps[0].Width;

            if (needCheckSize && !CheckSize_DXT(width, height))
                throw new InvalidOperationException($"DXT compression formats require dimensions to be multiples of 4. Got: {width}x{height}.");

            int fullSize = GetCompressedSizeOfImage(mipMaps.Count, saveFormat, width, height);
            // +1 to get the full size, not just the offset of the last mip.
            //int fullSize = GetMipOffset(mipMaps.Count + 1, saveFormat, mipMaps[0].Width, mipMaps[0].Height);

            byte[] destination = new byte[fullSize];

            // Create header and write to destination
            DDS_Header header = new DDS_Header(mipMaps.Count, height, width, saveFormat, customMasks);
            header.WriteToArray(destination, 0);

            int blockSize = ImageFormats.GetBlockSize(saveFormat);

            if (ImageFormats.IsBlockCompressed(saveFormat))
            {
                int mipOffset = 128;
                foreach (MipMap mipmap in mipMaps)
                    mipOffset = WriteCompressedMipMap(destination, mipOffset, mipmap, blockSize, compressor, alphaSetting);
            }
            else
            {
                // UNCOMPRESSED
                var action = new Action<int>(mipIndex =>
                {
                    if (alphaSetting == AlphaSettings.RemoveAlphaChannel)
                    {
                        // Remove alpha by setting AMask = 0
                        var ddspf = header.ddspf;
                        ddspf.dwABitMask = 0;
                        header.ddspf = ddspf;
                    }

                    // Get MipOffset
                    int offset = GetMipOffset(mipIndex, saveFormat, width, height);

                    WriteUncompressedMipMap(destination, offset, mipMaps[mipIndex], saveFormat, header.ddspf);
                });

                if (ImageEngine.EnableThreading)
                    Parallel.For(0, mipMaps.Count, new ParallelOptions { MaxDegreeOfParallelism = ImageEngine.NumThreads }, action);
                else
                    for (int i = 0; i < mipMaps.Count; i++)
                        action(i);
            }

            return destination;
        }