Exemple #1
0
        public void WriteTo(BinaryWriter writer, ITex tex)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }
            if (tex == null)
            {
                throw new ArgumentNullException(nameof(tex));
            }

            if (tex.Magic1 != "TEXV0005")
            {
                throw new UnknownMagicException(nameof(TexWriter), nameof(tex.Magic1), tex.Magic1);
            }

            if (tex.Magic2 != "TEXI0001")
            {
                throw new UnknownMagicException(nameof(TexWriter), nameof(tex.Magic2), tex.Magic2);
            }

            writer.WriteNString(tex.Magic1);
            writer.WriteNString(tex.Magic2);

            _texHeaderWriter.WriteTo(writer, tex.Header);
            _texImageContainerWriter.WriteTo(writer, tex.ImagesContainer);

            if (tex.IsGif)
            {
                _texFrameInfoContainerWriter.WriteTo(writer, tex.FrameInfoContainer);
            }
        }
Exemple #2
0
        private void ConvertToImageAndSave(ITex tex, string name)
        {
            var resultImage = _texToImageConverter.ConvertToImage(tex);

            var path = $"{TestHelper.BasePath}\\{OutputDirectoryName}\\{name}.{resultImage.Format.GetFileExtension()}";

            File.WriteAllBytes(path, resultImage.Bytes);
        }
Exemple #3
0
        private static ImageResult ConvertToGif(ITex tex)
        {
            var frameFormat = tex.FirstImage.FirstMipmap.Format;

            if (!frameFormat.IsRawFormat())
            {
                throw new InvalidOperationException(
                          "Only raw mipmap formats are supported right now while converting gif");
            }

            var image = ImageFromRawFormat(frameFormat, null,
                                           tex.FrameInfoContainer.GifWidth,
                                           tex.FrameInfoContainer.GifHeight);

            var sequenceImages = new Image[tex.ImagesContainer.Images.Count];

            for (var i = 0; i < sequenceImages.Length; i++)
            {
                var mipmap = tex.ImagesContainer.Images[i].FirstMipmap;
                sequenceImages[i] = ImageFromRawFormat(frameFormat, mipmap.Bytes, mipmap.Width, mipmap.Height);
            }

            foreach (var frameInfo in tex.FrameInfoContainer.Frames)
            {
                var frame = sequenceImages[frameInfo.ImageId].Clone(
                    context => context.Crop(new Rectangle(
                                                (int)frameInfo.X,
                                                (int)frameInfo.Y,
                                                (int)frameInfo.Width,
                                                (int)frameInfo.Height)
                                            )
                    );

                var metadata = frame.Frames.RootFrame.Metadata.GetFormatMetadata(GifFormat.Instance);
                metadata.FrameDelay = (int)Math.Round(frameInfo.Frametime * 100.0f);

                image.Frames.AddFrame(frame.Frames[0]);
            }

            // Remove first black frame
            image.Frames.RemoveFrame(0);

            using (var memoryStream = new MemoryStream())
            {
                image.SaveAsGif(memoryStream, new GifEncoder {
                    ColorTableMode = GifColorTableMode.Local
                });

                return(new ImageResult
                {
                    Bytes = memoryStream.ToArray(),
                    Format = MipmapFormat.ImageGIF
                });
            }
        }
 internal void SaveTable(string path, ITex data, DataGrid grid)
 {
     using (var textTab = new StreamWriter(path))
     {
         foreach (var item in grid.Items)
         {
             var obj = (ITex)item;
             textTab.WriteLine(obj.toTabular());
         }
     }
 }
        public string GenerateFullInfo(ITex tex)
        {
            //short helper class to ignore some properties from serialization

            var settings = new JsonSerializerSettings
            {
                TypeNameHandling = TypeNameHandling.Auto,
                Formatting       = Formatting.Indented,
                ContractResolver = _ignorePropertiesResolver
            };

            return(JsonConvert.SerializeObject(tex, typeof(Tex), settings));
        }
Exemple #6
0
        private static void ConvertToImageAndSave(ITex tex, string path, bool overwrite)
        {
            var format     = _texToImageConverter.GetConvertedFormat(tex);
            var outputPath = $"{path}.{format.GetFileExtension()}";

            if (!overwrite && File.Exists(outputPath))
            {
                return;
            }

            var resultImage = _texToImageConverter.ConvertToImage(tex);

            File.WriteAllBytes(outputPath, resultImage.Bytes);
        }
Exemple #7
0
        public ImageResult ConvertToImage(ITex tex)
        {
            if (tex == null)
            {
                throw new ArgumentNullException(nameof(tex));
            }

            if (tex.IsGif)
            {
                return(ConvertToGif(tex));
            }

            var sourceMipmap = tex.FirstImage.FirstMipmap;
            var format       = sourceMipmap.Format;

            if (format.IsCompressed())
            {
                throw new InvalidOperationException("Raw mipmap format must be uncompressed");
            }

            if (format.IsRawFormat())
            {
                var image = ImageFromRawFormat(format, sourceMipmap.Bytes, sourceMipmap.Width, sourceMipmap.Height);

                if (sourceMipmap.Width != tex.Header.ImageWidth ||
                    sourceMipmap.Height != tex.Header.ImageHeight)
                {
                    image.Mutate(x => x.Crop(tex.Header.ImageWidth, tex.Header.ImageHeight));
                }

                using (var memoryStream = new MemoryStream())
                {
                    image.SaveAsPng(memoryStream);

                    return(new ImageResult
                    {
                        Bytes = memoryStream.ToArray(),
                        Format = MipmapFormat.ImagePNG
                    });
                }
            }

            return(new ImageResult
            {
                Bytes = sourceMipmap.Bytes,
                Format = format
            });
        }
Exemple #8
0
        private static void PackFile()
        {
            Directory.CreateDirectory(_options.OutputDirectory);

            var inputFileInfo = new FileInfo(_options.Input);

            ITex tex = _imageToTexConverter.LoadFileToTex(inputFileInfo);

            var outputFilePath = Path.Combine(_options.OutputDirectory, Path.GetFileNameWithoutExtension(inputFileInfo.Name));

            using (var stream = File.OpenWrite($"{outputFilePath}.tex"))
                using (var writer = new BinaryWriter(stream))
                {
                    _texWriter.WriteTo(writer, tex);
                }
        }
Exemple #9
0
        public MipmapFormat GetConvertedFormat(ITex tex)
        {
            if (tex == null)
            {
                throw new ArgumentNullException(nameof(tex));
            }

            if (tex.IsGif)
            {
                return(MipmapFormat.ImageGIF);
            }

            var format = tex.FirstImage.FirstMipmap.Format;

            if (format.IsCompressed())
            {
                throw new InvalidOperationException("Raw mipmap format must be uncompressed");
            }

            return(format.IsRawFormat() ? MipmapFormat.ImagePNG : format);
        }
Exemple #10
0
        public string GenerateInfo(ITex tex)
        {
            if (tex == null)
            {
                throw new ArgumentNullException(nameof(tex));
            }

            var json = new JObject
            {
                ["bleedtransparentcolors"] = true,
                ["clampuvs"]        = tex.HasFlag(TexFlags.ClampUVs),
                ["format"]          = tex.Header.Format.ToString().ToLower(),
                ["nomip"]           = (tex.FirstImage.Mipmaps.Count == 1).ToString().ToLower(),
                ["nointerpolation"] = tex.HasFlag(TexFlags.NoInterpolation).ToString().ToLower(),
                ["nonpoweroftwo"]   = (!NumberIsPowerOfTwo(tex.Header.ImageWidth) ||
                                       !NumberIsPowerOfTwo(tex.Header.ImageHeight)).ToString().ToLower()
            };

            if (tex.IsGif)
            {
                if (tex.FrameInfoContainer == null)
                {
                    throw new InvalidOperationException("TEX is animated but doesn't have frame info container");
                }

                json["spritesheetsequences"] = new JArray
                {
                    new JObject
                    {
                        ["duration"] = 1, // not sure what this value is used for
                        ["frames"]   = tex.FrameInfoContainer.Frames.Count,
                        ["width"]    = tex.FrameInfoContainer.GifWidth,
                        ["height"]   = tex.FrameInfoContainer.GifHeight
                    }
                };
            }

            return(JsonConvert.SerializeObject(json, Formatting.Indented));
        }
Exemple #11
0
        private static void ConvertToImageAndSave(ITex tex, string path, bool overwrite)
        {
            var format = _texToImageConverter.GetConvertedFormat(tex);


            int i = 0;

            foreach (var image in tex.ImagesContainer.Images)
            {
                int j = 0;
                foreach (var mipmap in image.Mipmaps)
                {
                    var outputPath = $"{path}-im{i}-mipmap{j}.{format.GetFileExtension()}";
                    if (i == 0 && j == 0)
                    {
                        outputPath = $"{path}.{format.GetFileExtension()}";
                    }

                    if (!overwrite && File.Exists(outputPath))
                    {
                        return;
                    }

                    var resultImage = _texToImageConverter.ConvertToImage(tex, mipmap);

                    File.WriteAllBytes(outputPath, resultImage.Bytes);

                    if (!_options.ExtractAllImages)
                    {
                        return;
                    }
                    j++;
                }
                i++;
            }
        }
Exemple #12
0
        public static CTex *ConvertToCTex(
            this NativeEnvironment e,
            ITex tex)
        {
            // tex
            var ctex = e.AllocateStruct <CTex>();

            ctex->magic1 = e.ToCString(tex.Magic1);
            ctex->magic2 = e.ToCString(tex.Magic2);

            // header
            var header = tex.Header;

            ctex->header.format         = header.Format;
            ctex->header.flags          = header.Flags;
            ctex->header.texture_width  = header.TextureWidth;
            ctex->header.texture_height = header.TextureHeight;
            ctex->header.image_width    = header.ImageWidth;
            ctex->header.image_height   = header.ImageHeight;
            ctex->header.unk_int0       = header.UnkInt0;

            // images container
            var imgContainer = tex.ImagesContainer;
            var images       = imgContainer.Images;

            ctex->images_container.magic             = e.ToCString(imgContainer.Magic);
            ctex->images_container.image_format      = imgContainer.ImageFormat;
            ctex->images_container.image_count       = images.Count;
            ctex->images_container.images_length     = images.Count;
            ctex->images_container.container_version = imgContainer.ImageContainerVersion;

            if (images.Count == 0)
            {
                ctex->images_container.images = null;
            }
            else
            {
                var cimages = e.AllocateStructArray <CTexImage>(images.Count);
                ctex->images_container.images = cimages;

                for (var i = 0; i < images.Count; i++)
                {
                    ConvertCTexImage(e, images[i], &cimages[i]);
                }
            }

            // frame info container
            var frameContainer = tex.FrameInfoContainer;

            if (frameContainer == null)
            {
                ctex->frameinfo_container = null;
                return(ctex);
            }

            var frames = frameContainer.Frames;

            ctex->frameinfo_container                = e.AllocateStruct <CTexFrameInfoContainer>();
            ctex->frameinfo_container->magic         = e.ToCString(frameContainer.Magic);
            ctex->frameinfo_container->frame_count   = frames.Count;
            ctex->frameinfo_container->frames_length = frames.Count;
            ctex->frameinfo_container->gif_width     = frameContainer.GifWidth;
            ctex->frameinfo_container->gif_height    = frameContainer.GifHeight;

            if (frames.Count == 0)
            {
                ctex->frameinfo_container->frames = null;
                return(ctex);
            }

            var cframes = e.AllocateStructArray <CTexFrameInfo>(frames.Count);

            ctex->frameinfo_container->frames = cframes;

            for (var i = 0; i < frames.Count; i++)
            {
                ConvertCTexFrameInfo(e, frames[i], &cframes[i]);
            }

            return(ctex);
        }
Exemple #13
0
        public ITex LoadFileToTex(FileInfo filePath)
        {
            switch (filePath.Extension)
            {
            case ".tex-full-json":
            {
                var settings = new JsonSerializerSettings {
                    TypeNameHandling = TypeNameHandling.Auto
                };
                ITex tex = JsonConvert.DeserializeObject <Tex>(File.ReadAllText(filePath.FullName), settings);
                return(tex);
            }

            default:
            {
                Image  image = Image.FromFile(filePath.FullName);
                byte[] imageBytes;

                using (var ms = new MemoryStream())
                {
                    image.Save(ms, image.RawFormat);
                    imageBytes = ms.ToArray();
                }

                // var fullJsonInfo = Newtonsoft.Json.JsonConvert.SerializeObject(image);
                // File.WriteAllText($"{filePath}.test-json", fullJsonInfo);

                // var bytes = image.SavePixelData();

                var tex = new Tex {
                };

                tex.Magic1 = "TEXV0005";
                tex.Magic2 = "TEXI0001";

                tex.Header = new TexHeader
                {
                    Format        = (TexFormat)0,
                    Flags         = (TexFlags)2,
                    TextureWidth  = image.Width,
                    TextureHeight = image.Height,
                    ImageWidth    = image.Width,
                    ImageHeight   = image.Height,
                    UnkInt0       = 4278190080
                };
                tex.ImagesContainer       = new TexImageContainer {
                };
                tex.ImagesContainer.Magic = "TEXB0003";

                switch (tex.ImagesContainer.Magic)
                {
                case "TEXB0001":
                case "TEXB0002":
                    break;

                case "TEXB0003":
                    tex.ImagesContainer.ImageFormat = FreeImageFormat.FIF_PNG;
                    break;

                default:
                    throw new UnknownMagicException(nameof(TexImageContainerReader), tex.ImagesContainer.Magic);
                }

                tex.ImagesContainer.ImageContainerVersion = (TexImageContainerVersion)Convert.ToInt32(tex.ImagesContainer.Magic.Substring(4));

                // var mipmapCount = 1;

                // if (mipmapCount > Constants.MaximumMipmapCount)
                //     throw new UnsafeTexException(
                //         $"Mipmap count exceeds limit: {mipmapCount}/{Constants.MaximumMipmapCount}");

                // var readFunction = PickMipmapReader(container.ImageContainerVersion);
                var format   = TexMipmapFormatGetter.GetFormatForTex(tex.ImagesContainer.ImageFormat, tex.Header.Format);
                var teximage = new TexImage();

                // var mipmap = readFunction(reader);
                // mipmap.Format = format;

                // if (DecompressMipmapBytes)
                //     _texMipmapDecompressor.DecompressMipmap(mipmap);

                var mipmap = new TexMipmap {
                };

                mipmap.Format = MipmapFormat.ImagePNG;

                mipmap.Width  = image.Width;
                mipmap.Height = image.Height;

                mipmap.Bytes = imageBytes;

                teximage.Mipmaps.Add(mipmap);

                tex.ImagesContainer.Images.Add(teximage);

                return(tex);
            }
            }
        }
Exemple #14
0
        private static ImageResult ConvertToGif(ITex tex)
        {
            var frameFormat = tex.FirstImage.FirstMipmap.Format;

            if (!frameFormat.IsRawFormat())
            {
                throw new InvalidOperationException(
                          "Only raw mipmap formats are supported right now while converting gif");
            }

            var image = ImageFromRawFormat(frameFormat, null,
                                           tex.FrameInfoContainer.GifWidth,
                                           tex.FrameInfoContainer.GifHeight);

            var sequenceImages = new Image[tex.ImagesContainer.Images.Count];

            for (var i = 0; i < sequenceImages.Length; i++)
            {
                var mipmap = tex.ImagesContainer.Images[i].FirstMipmap;
                sequenceImages[i] = ImageFromRawFormat(frameFormat, mipmap.Bytes, mipmap.Width, mipmap.Height);
            }

            foreach (var frameInfo in tex.FrameInfoContainer.Frames)
            {
                // Frames can be turned to fit into the map so we need to compute cropping coordinates first
                // We're keeping width and height signed for the rotation angle calculation
                var width  = frameInfo.Width != 0 ? frameInfo.Width : frameInfo.HeightX;
                var height = frameInfo.Height != 0 ? frameInfo.Height : frameInfo.WidthY;
                var x      = Math.Min(frameInfo.X, frameInfo.X + width);
                var y      = Math.Min(frameInfo.Y, frameInfo.Y + height);

                // This formula gives us the angle for which we need to turn the frame,
                // assuming that either Width or HeightX is 0 (same with Height and WidthY)
                var rotationAngle = -(Math.Atan2(Math.Sign(height), Math.Sign(width)) - Math.PI / 4);

                var frame = sequenceImages[frameInfo.ImageId].Clone(
                    context => context.Crop(new Rectangle(
                                                (int)x,
                                                (int)y,
                                                (int)Math.Abs(width),
                                                (int)Math.Abs(height))
                                            ).Rotate((float)Math.Round(rotationAngle * 180 / Math.PI)));

                var metadata = frame.Frames.RootFrame.Metadata.GetFormatMetadata(GifFormat.Instance);
                metadata.FrameDelay = (int)Math.Round(frameInfo.Frametime * 100.0f);

                image.Frames.AddFrame(frame.Frames[0]);
            }

            // Remove first black frame
            image.Frames.RemoveFrame(0);

            using (var memoryStream = new MemoryStream())
            {
                image.SaveAsGif(memoryStream, new GifEncoder {
                    ColorTableMode = GifColorTableMode.Local
                });

                return(new ImageResult
                {
                    Bytes = memoryStream.ToArray(),
                    Format = MipmapFormat.ImageGIF
                });
            }
        }