コード例 #1
0
        /// <summary>
        /// Gets file extension of supported surface formats.
        /// Doesn't include preceding dot.
        /// </summary>
        /// <param name="format">Format to get file extension for.</param>
        /// <returns>File extension without dot.</returns>
        static string GetExtensionOfFormat(ImageEngineFormat format)
        {
            string formatString = format.ToString().ToLowerInvariant();

            if (formatString.Contains('_'))
            {
                formatString = "dds";
            }

            return(formatString);
        }
コード例 #2
0
        public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable)
        {
            ImageEngineImage image = await Task.Run(() => new ImageEngineImage(filename));

            int width  = image.Width;
            int height = image.Height;

            DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue;
            DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue;

            sizeX?.SetPropertyValue(width);
            sizeY?.SetPropertyValue(height);

            DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue;

            mipTailBaseIdx?.SetPropertyValue((int)Math.Log(width > height ? width : height, 2));

            DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue;
            DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue;

            filePath?.SetPropertyValue(filename);
            fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss"));

            DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue;

            ImageEngineFormat imageFormat = image.Format.InternalFormat;

            if (!imageFormat.ToString().Contains("DDS"))
            {
                throw new Exception($"Image is not in a DDS format.  It is actually {imageFormat}.");
            }

            if (pfFormat != null)
            {
                string formatStr = imageFormat.ToString().Replace("DDS", "PF");

                if (formatStr.Contains("ARGB"))
                {
                    formatStr = "PF_A8R8G8B8";
                }
                else if (formatStr.Contains("G8"))
                {
                    formatStr = "PF_G8";
                }

                DomainNameTableEntry formatTableEntry = nameTable.SingleOrDefault(nt => nt.Name.String == formatStr) ?? nameTable.AddDomainNameTableEntry(formatStr);

                pfFormat.SetPropertyValue(formatTableEntry);
            }

            MipMaps.Clear();

            while (true)
            {
                MemoryStream stream = new MemoryStream();

                image.Save(stream, imageFormat, MipHandling.KeepTopOnly);

                await stream.FlushAsync();

                MipMaps.Add(new DomainMipMap
                {
                    ImageData = (await ByteArrayReader.CreateNew(stream.ToArray(), 0x80).Splice()).GetBytes(), // Strip off 128 bytes for the DDS header
                    Width     = image.Width,
                    Height    = image.Height
                });

                if (width == 1 && height == 1)
                {
                    break;
                }

                if (width > 1)
                {
                    width /= 2;
                }
                if (height > 1)
                {
                    height /= 2;
                }

                if (image.Width > 4 && image.Height > 4)
                {
                    image.Resize(0.5, false);
                }
            }
        }
コード例 #3
0
 /// <summary>
 /// Determines if given format supports mipmapping.
 /// </summary>
 /// <param name="format">Image format to check.</param>
 /// <returns></returns>
 static bool IsFormatMippable(ImageEngineFormat format)
 {
     return(format.ToString().Contains("DDS"));
 }
コード例 #4
0
 /// <summary>
 /// Determines if given format supports mipmapping.
 /// </summary>
 /// <param name="format">Image format to check.</param>
 /// <returns></returns>
 public static bool IsFormatMippable(ImageEngineFormat format)
 {
     return format.ToString().Contains("DDS");
 }
コード例 #5
0
        /// <summary>
        /// Gets file extension of supported surface formats.
        /// Doesn't include preceding dot.
        /// </summary>
        /// <param name="format">Format to get file extension for.</param>
        /// <returns>File extension without dot.</returns>
        public static string GetExtensionOfFormat(ImageEngineFormat format)
        {
            string formatString = format.ToString().ToLowerInvariant();
            if (formatString.Contains('_'))
                formatString = "dds";

            return formatString;
        }
コード例 #6
0
ファイル: Misc.cs プロジェクト: solarisstar/ME3Explorer
 public static string StringifyFormat(ImageEngineFormat format)
 {
     return(format.ToString().Replace("DDS_", "").Replace("_3Dc", ""));
 }
コード例 #7
0
ファイル: Misc.cs プロジェクト: ME3Explorer/ME3Explorer
 public static string StringifyFormat(ImageEngineFormat format)
 {
     return format.ToString().Replace("DDS_", "").Replace("_3Dc","");
 }
コード例 #8
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;
        }