示例#1
0
        protected override void ExecuteCommandsLogic(CmdsExecutionData data)
        {
            var contentFile = data.ContainerFile.GetContentFileByPath(data.ContentPath);

            if (contentFile.FileType != ContentFileType.Image)
            {
                throw new CmdExecutionFailedException(
                          String.Format("Invalid targetContentPath: \"{0}\". It doesn't target an image content file.", data.ContentPath),
                          DefaultExecutionErrorMsg);
            }

            TgvImage oldTgv = BytesToTgv(contentFile.Content);
            TgvImage newtgv = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps);

            ImageComposerService.ReplaceImageTile(
                oldTgv,
                newtgv,
                (uint)Command.TileSize.Value,
                (uint)Command.Column.Value,
                (uint)Command.Row.Value);

            var newContet = TgvToBytes(oldTgv, !Command.UseMipMaps);

            contentFile.LoadCustomContent(newContet);
        }
        protected TgvImage BytesToTgv(byte[] rawTgv, bool readMipMaps = true)
        {
            ITgvBinReader rawReader = new TgvBinReader();
            TgvImage      oldTgv    = rawReader.Read(rawTgv, readMipMaps);

            return(oldTgv);
        }
示例#3
0
        protected override void ExecuteCommandsLogic(CmdsExecutionData data)
        {
            var contentFile = data.ContainerFile.GetContentFileByPath(data.ContentPath);

            //To nie będzie potrzebne tutaj jeśli nie bedzie trzeba ładować i wykorzystywać starego obrazka.
            if (contentFile.FileType != ContentFileType.Image)
            {
                throw new CmdExecutionFailedException(
                          String.Format("Invalid targetContentPath: \"{0}\". It doesn't target an image content file.", data.ContentPath),
                          DefaultExecutionErrorMsg);
            }

            //Ładowanie starego obrazka nie będzie potrzebne jeśli bedzie pewnośc ze recznie wygenerowana checkusma jest ok.
            //Ale co z info o kompresji? Trudno żeby użytkownik je znał poprawnie...
            TgvImage oldTgv = BytesToTgv(contentFile.Content, false);
            TgvImage newtgv = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps);

            //newtgv.SourceChecksum = newtgv.ComputeContentChecksum();
            //newtgv.IsCompressed = Command.UseCompression;
            newtgv.SourceChecksum = oldTgv.SourceChecksum;
            newtgv.IsCompressed   = oldTgv.IsCompressed;

            var newContent = TgvToBytes(newtgv, !Command.UseMipMaps);

            contentFile.LoadCustomContent(newContent);
        }
示例#4
0
        protected TgvImage BytesToTgv(byte[] rawTgv)
        {
            ITgvBinReader rawReader = new TgvBinReader();
            TgvImage      oldTgv    = rawReader.Read(rawTgv);

            return(oldTgv);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="source"></param>
        /// <param name="tileSize"></param>
        /// <param name="column"></param>
        /// <param name="row"></param>
        public void ReplaceImageTile(TgvImage destination, TgvImage source, uint tileSize, uint column, uint row)
        {
            uint xPos = tileSize * column;
            uint yPos = tileSize * row;

            ReplaceImagePart(destination, source, xPos, yPos);
        }
        protected byte[] TgvToBytes(TgvImage tgv, bool discardMipMaps = true)
        {
            ITgvBinWriter tgvRawWriter = discardMipMaps ?
                                         new TgvBinNoMipMapsWriter() :
                                         new TgvBinWriter();
            var bytes = tgvRawWriter.Write(tgv);

            return(bytes);
        }
        protected TgvImage DDSFileToTgv(String sourceFullPath, bool discardMipMaps = true)
        {
            ITgvFileReader tgvReader = discardMipMaps ?
                                       (ITgvFileReader)(new TgvDDSMoMipMapsReader()) :
                                       (ITgvFileReader)(new TgvDDSReader());
            TgvImage newtgv = tgvReader.Read(sourceFullPath);

            return(newtgv);
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        /// <remarks>
        /// Credits to enohka for this code.
        /// See more at: http://github.com/enohka/moddingSuite
        /// </remarks>
        public virtual TgvImage Read(String filePath)
        {
            var file = new TgvImage();

            byte[] rawDDSData = File.ReadAllBytes(filePath);
            using (var ms = new MemoryStream(rawDDSData))
            {
                var buffer = new byte[4];
                ms.Read(buffer, 0, buffer.Length);

                if (BitConverter.ToUInt32(buffer, 0) != DDSFormat.MagicHeader)
                {
                    throw new ArgumentException("Wrong DDS magic");
                }

                buffer = new byte[Marshal.SizeOf(typeof(DDSFormat.Header))];
                ms.Read(buffer, 0, buffer.Length);

                var header = MiscUtilities.ByteArrayToStructure <DDSFormat.Header>(buffer);
                header.MipMapCount = 1;

                DDSHelper.ConversionFlags conversionFlags;
                var format = DDSHelper.GetDXGIFormat(ref header.PixelFormat, out conversionFlags);

                //read only the main content mipmap
                uint minMipByteLength = DDSMipMapUilities.GetMinimumMipMapSizeForFormat(header.PixelFormat);
                uint mipByteLength    = (uint)DDSMipMapUilities.GetMipMapBytesCount((int)header.Width, (int)header.Height, format);
                mipByteLength = Math.Max(minMipByteLength, mipByteLength);

                buffer = new byte[mipByteLength];
                ms.Read(buffer, 0, buffer.Length);

                var mip = new TgvMipMap();
                mip.Content   = buffer;
                mip.Length    = mipByteLength;
                mip.MipSize   = header.Width * header.Height;
                mip.MipWidth  = header.Width;
                mip.MipHeight = header.Height;

                file.MipMapCount = (ushort)header.MipMapCount;
                file.MipMaps.Add(mip);
                file.Height            = header.Height;
                file.ImageHeight       = header.Height;
                file.Width             = header.Width;
                file.ImageWidth        = header.Width;
                file.Format            = format;
                file.PixelFormatString = TgvUtilities.GetTgvFromPixelFormat(format);
            }

            return(file);
        }
示例#9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public override byte[] Write(TgvImage file)
        {
            TgvImage noMipMapsFile = new TgvImage();

            noMipMapsFile.PixelFormatString = file.PixelFormatString;
            noMipMapsFile.Format            = file.Format;
            noMipMapsFile.Height            = file.Height;
            noMipMapsFile.Width             = file.Width;
            noMipMapsFile.ImageHeight       = file.ImageHeight;
            noMipMapsFile.ImageWidth        = file.ImageWidth;
            noMipMapsFile.IsCompressed      = file.IsCompressed;
            noMipMapsFile.SourceChecksum    = file.SourceChecksum;
            noMipMapsFile.Version           = file.Version;
            noMipMapsFile.MipMaps.Add(file.MipMaps.OrderBy(x => x.Length).Last());
            noMipMapsFile.MipMapCount = 1;

            return(base.Write(noMipMapsFile));
        }
        protected override void ExecuteCommandsLogic(CmdsExecutionData data)
        {
            if (!data.ContainerFile.ContainsContentFileWithPath(data.ContentPath))
            {
                TgvImage image = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps);
                //Trzeba mieć na to oko, czy nie powoduje problemów, bo przy replace była używana checksuma starego obrazka.
                image.SourceChecksum = !String.IsNullOrEmpty(Command.Checksum)
                    ? MiscUtilities.HexByteStringToByteArray(Command.Checksum)
                    : image.ComputeContentChecksum();
                image.IsCompressed = Command.UseCompression;

                var newContentFile = new EdataContentFile();
                newContentFile.Path = data.ContentPath;
                newContentFile.LoadCustomContent(TgvToBytes(image, !Command.UseMipMaps));

                data.ContainerFile.AddContentFile(newContentFile);
            }
            else if (Command.OverwriteIfExist)
            {
                var contentFile = data.ContainerFile.GetContentFileByPath(data.ContentPath);

                //To nie będzie potrzebne tutaj jeśli nie bedzie trzeba ładować i wykorzystywać starego obrazka.
                if (contentFile.FileType != ContentFileType.Image)
                {
                    throw new CmdExecutionFailedException(
                              String.Format("Invalid targetContentPath: \"{0}\". It doesn't target an image content file.", data.ContentPath),
                              DefaultExecutionErrorMsg);
                }

                //Ładowanie starego obrazka nie będzie potrzebne jeśli bedzie pewnośc ze recznie wygenerowana checkusma jest ok.
                //Ok, tu kiedyś było odczytywanie starych danych z starego obrazka, teraz checksuma jest generowana na nowo,
                //żeby uniknac konieczności ładowania tych starych danych, bo nie sa potrzeben przy dodawaniu, a tutaj były by potrzebne
                //i trudno to rozwiązać przy założeniu ze dane są ładowane na zewnątrz.

                //TgvImage oldTgv = BytesToTgv(contentFile.Content);
                TgvImage image = DDSFileToTgv(data.ModificationSourcePath, !Command.UseMipMaps);
                image.SourceChecksum = !String.IsNullOrEmpty(Command.Checksum)
                    ? MiscUtilities.HexByteStringToByteArray(Command.Checksum)
                    : image.ComputeContentChecksum();
                image.IsCompressed = Command.UseCompression;

                contentFile.LoadCustomContent(TgvToBytes(image, !Command.UseMipMaps));
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="target"></param>
        /// <param name="source"></param>
        /// <param name="xPos"></param>
        /// <param name="yPos"></param>
        public void ReplaceImagePart(TgvImage target, TgvImage source, uint xPos, uint yPos)
        {
            //Jeśli chodzi o podmienianie częśći obrazka w mipMapach, warunkiem było by że użytkownik zapewnia obrazek źródłowy posiadający mipMapy
            //W takiej sytuacji trzeba było by obliczać dla którego nr mipmapy obrazka z siatką (lods orygianlny) możliwa była by podmiania z wykorzystaniem
            //mipmap obrazka źródłowego od użytkownika...

            if (target.MipMaps.Count == 0 || source.MipMaps.Count == 0)
            {
                return;
            }

            if (xPos >= target.Width || xPos < 0 ||
                yPos >= target.Height || yPos < 0)
            {
                return;
            }

            var sortedSourceMips  = source.MipMaps.OrderByDescending(x => x.MipSize).ToArray();
            var sortedTargettMips = target.MipMaps.OrderByDescending(x => x.MipSize).ToArray();

            for (int i = 0; (i < sortedSourceMips.Length) && (i < sortedTargettMips.Length); ++i)
            {
                var sourceMip = sortedSourceMips[i];
                var targetMip = sortedTargettMips[i];

                //1. Przeskalować pozycje umieszczenia
                //2. Spr czy pozycje umieszczenia są poprawne
                //3. ocenić kiedy nie można / staję sie niebezpieczne dalsze przepisywnia mipmap przy jednoczesnym znikomym rezultacie.

                uint mipScale      = (uint)Math.Max(1, 2 << (i - 1));//Przenieśc to do jakiego utilies
                uint targetMipXPos = xPos / mipScale;
                uint targetMipYPos = yPos / mipScale;

                if (targetMipXPos >= 0 && targetMipXPos < targetMip.MipWidth &&
                    targetMipYPos >= 0 && targetMipYPos < targetMip.MipHeight)
                {
                    ReplaceMipMapPart(targetMip, sourceMip, targetMipXPos, targetMipYPos);
                }
            }
        }
示例#12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        /// <remarks>
        /// Credits to enohka for this code.
        /// See more at: http://github.com/enohka/moddingSuite
        /// </remarks>
        public virtual byte[] Write(TgvImage file)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                file.PixelFormatString = TgvUtilities.GetTgvFromPixelFormat(file.Format); //"DXT5_SRGB"

                var buffer = BitConverter.GetBytes(VersionMagic);
                stream.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(file.IsCompressed ? 1 : 0);
                stream.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(file.Width);
                stream.Write(buffer, 0, buffer.Length);
                buffer = BitConverter.GetBytes(file.Height);
                stream.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes(file.Width);
                stream.Write(buffer, 0, buffer.Length);
                buffer = BitConverter.GetBytes(file.Height);
                stream.Write(buffer, 0, buffer.Length);

                buffer = BitConverter.GetBytes((short)file.MipMapCount);
                stream.Write(buffer, 0, buffer.Length);

                var fmtLen = (short)file.PixelFormatString.Length;
                buffer = BitConverter.GetBytes(fmtLen);
                stream.Write(buffer, 0, buffer.Length);

                buffer = Encoding.ASCII.GetBytes(file.PixelFormatString);
                stream.Write(buffer, 0, buffer.Length);
                stream.Seek(MathUtilities.RoundToNextDivBy4(fmtLen) - fmtLen, SeekOrigin.Current);

                stream.Write(file.SourceChecksum, 0, file.SourceChecksum.Length);

                var mipOffset = (uint)(stream.Position);

                stream.Seek(8 * file.MipMapCount, SeekOrigin.Current);

                var sortedMipMaps = file.MipMaps.OrderBy(x => x.MipSize).ToList();

                // Create the content and write all MipMaps,
                // since we compress on this part its the first part where we know the size of a MipMap
                foreach (var sortedMipMap in sortedMipMaps)
                {
                    sortedMipMap.Offset = (uint)stream.Position;
                    if (file.IsCompressed)
                    {
                        var zipoMagic = Encoding.ASCII.GetBytes("ZIPO");
                        stream.Write(zipoMagic, 0, zipoMagic.Length);

                        //buffer = BitConverter.GetBytes(mipImgsizes[sortedMipMaps.IndexOf(sortedMipMap)]);
                        //To Ÿle dzia³a. W orygianlnym pliku bajty s¹ w innej kolejnoœci. Pozatym to zak³ada ze potêg¹ jest indeks,
                        //a w przypadku ma³ej liczby bitmap to nie ma sensu
                        uint mipSize = sortedMipMap.MipSize; //GetMipMapSize(file.Width, file.Height, sortedMipMaps.IndexOf(sortedMipMap), sortedMipMaps.Count);
                        buffer = BitConverter.GetBytes(mipSize);
                        stream.Write(buffer, 0, buffer.Length);

                        ICompressor comp = new ZlibCompressor();
                        buffer = comp.Compress(sortedMipMap.Content);
                        stream.Write(buffer, 0, buffer.Length);
                        sortedMipMap.Length = (uint)buffer.Length;
                    }
                    else
                    {
                        stream.Write(sortedMipMap.Content, 0, sortedMipMap.Content.Length);
                        sortedMipMap.Length = (uint)sortedMipMap.Content.Length;
                    }

                    //Wygl¹da na to ¿e mipMapy musza mieæ offset wzglêden pocz¹tku pliku podzielny przez 4.
                    //Trzeba dope³niæ do liczby podzielnej przez 4 przed zapisem nastêpnego
                    //To dope³nienie zak³ada ¿e nag³ówek ma d³ugoœæ podzielna przez 4, tak ¿e pierwsza MipMapa nie jest przesuniêta.

                    //Plik Edata wie o tym poszerzeniu rozmiaru, bo odczytuje d³ugoœæ pliku z rozmiaru contentu.

                    bool multiMipMaps      = file.MipMaps.Count > 1;
                    bool needSupplementTo4 = (stream.Position % 4) != 0;
                    if (multiMipMaps && needSupplementTo4)
                    {
                        int    supplementSize   = (int)(MathUtilities.RoundToNextDivBy4(stream.Position) - stream.Position);
                        byte[] supplementBuffer = new byte[supplementSize];
                        stream.Write(supplementBuffer, 0, supplementBuffer.Length);
                    }
                }

                stream.Seek(mipOffset, SeekOrigin.Begin);

                // Write the offset collection in the header.
                for (int i = 0; i < file.MipMapCount; i++)
                {
                    buffer = BitConverter.GetBytes(sortedMipMaps[i].Offset);
                    stream.Write(buffer, 0, buffer.Length);
                }

                // Write the size collection into the header.
                for (int i = 0; i < file.MipMapCount; i++)
                {
                    buffer = BitConverter.GetBytes(sortedMipMaps[i].Length + 8); //+ 4 magii i + 4 rozmiaru mapy
                    stream.Write(buffer, 0, buffer.Length);
                }

                return(stream.ToArray());
            }
        }
        public virtual TgvImage Read(String filePath)
        {
            var file = new TgvImage();

            byte[] rawDDSData = File.ReadAllBytes(filePath);
            using (var ms = new MemoryStream(rawDDSData))
            {
                var buffer = new byte[4];
                ms.Read(buffer, 0, buffer.Length);

                if (BitConverter.ToUInt32(buffer, 0) != DDSFormat.MagicHeader)
                {
                    throw new ArgumentException("Wrong DDS magic");
                }

                buffer = new byte[Marshal.SizeOf(typeof(DDSFormat.Header))];
                ms.Read(buffer, 0, buffer.Length);

                var header = MiscUtilities.ByteArrayToStructure <DDSFormat.Header>(buffer);

                DDSHelper.ConversionFlags conversionFlags;
                var format = DDSHelper.GetDXGIFormat(ref header.PixelFormat, out conversionFlags);

                if (header.MipMapCount == 0)
                {
                    header.MipMapCount = 1;
                }

                for (int i = 0; i < header.MipMapCount; i++)
                {
                    uint mipScale  = (uint)Math.Max(1, 2 << (i - 1));
                    uint mipWidth  = Math.Max(1, header.Width / mipScale);
                    uint mipHeight = Math.Max(1, header.Height / mipScale);

                    if (mipWidth < MinMipMapWidth || mipHeight < MinMipMapHeight)
                    {
                        break;
                    }

                    uint minMipByteLength = DDSMipMapUilities.GetMinimumMipMapSizeForFormat(header.PixelFormat);
                    uint mipByteLength    = (uint)DDSMipMapUilities.GetMipMapBytesCount((int)mipWidth, (int)mipHeight, format);
                    mipByteLength = Math.Max(minMipByteLength, mipByteLength);

                    buffer = new byte[mipByteLength];
                    ms.Read(buffer, 0, buffer.Length);

                    var mip = new TgvMipMap();
                    mip.Content   = buffer;
                    mip.Length    = mipByteLength;
                    mip.MipSize   = mipWidth * mipHeight;//(int)mipSize; //spr. czy to jest równe size czy width * height;
                    mip.MipWidth  = mipWidth;
                    mip.MipHeight = mipHeight;

                    file.MipMaps.Add(mip);
                }

                file.Height            = header.Height;
                file.ImageHeight       = header.Height;
                file.Width             = header.Width;
                file.ImageWidth        = header.Width;
                file.MipMapCount       = (ushort)file.MipMaps.Count;
                file.Format            = format;
                file.PixelFormatString = TgvUtilities.GetTgvFromPixelFormat(format);
            }

            return(file);
        }
示例#14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="rawTgvData"></param>
        /// <returns></returns>
        /// <remarks>
        /// Credits to enohka for this code.
        /// See more at: http://github.com/enohka/moddingSuite
        /// </remarks>
        public virtual TgvImage Read(byte[] rawTgvData, bool loadMipMaps = true)
        {
            var tgv = new TgvImage();

            using (var ms = new MemoryStream(rawTgvData))
            {
                var buffer = new byte[4];

                ms.Read(buffer, 0, buffer.Length);
                tgv.Version = BitConverter.ToUInt32(buffer, 0);

                ms.Read(buffer, 0, buffer.Length);
                tgv.IsCompressed = BitConverter.ToInt32(buffer, 0) > 0;

                ms.Read(buffer, 0, buffer.Length);
                tgv.Width = BitConverter.ToUInt32(buffer, 0);
                ms.Read(buffer, 0, buffer.Length);
                tgv.Height = BitConverter.ToUInt32(buffer, 0);

                ms.Read(buffer, 0, buffer.Length);
                tgv.ImageHeight = BitConverter.ToUInt32(buffer, 0);
                ms.Read(buffer, 0, buffer.Length);
                tgv.ImageWidth = BitConverter.ToUInt32(buffer, 0);

                buffer = new byte[2];

                ms.Read(buffer, 0, buffer.Length);
                tgv.MipMapCount = BitConverter.ToUInt16(buffer, 0);

                ms.Read(buffer, 0, buffer.Length);
                ushort pixelFormatLen = BitConverter.ToUInt16(buffer, 0);

                buffer = new byte[pixelFormatLen];

                ms.Read(buffer, 0, buffer.Length);
                tgv.PixelFormatString = Encoding.ASCII.GetString(buffer);

                ms.Seek(MathUtilities.RoundToNextDivBy4(pixelFormatLen) - pixelFormatLen, SeekOrigin.Current);

                buffer = new byte[16];
                ms.Read(buffer, 0, buffer.Length);
                tgv.SourceChecksum = (byte[])buffer.Clone();

                //Read MipMaps
                var mipMaps = CreateEmptyMipMaps(tgv.MipMapCount);

                ReadMipMapsOffsets(ms, mipMaps);

                ReadMipMapsLengths(ms, mipMaps);

                if (loadMipMaps)
                {
                    ReadMipMapsContent(ms, mipMaps, tgv.IsCompressed);
                }

                SetMipMapsDimensions(mipMaps, tgv.Width, tgv.Height);

                tgv.MipMaps = mipMaps;
            }

            tgv.Format = TgvUtilities.GetPixelFormatFromTgv(tgv.PixelFormatString);

            return(tgv);
        }