Example #1
0
        private static List<ConstAnimationFrame> GetFrameInfo(CommandLineArgs cmdLine, NpkReader npk, NpkPath imgPath)
        {
            List<ConstAnimationFrame> frameInfo = new List<ConstAnimationFrame>();
            List<FrameInfo> frames = npk.Frames[imgPath].ToList();

            if (cmdLine.UseAllFrames)
            {
                for (int frameIndex = 0; frameIndex < frames.Count; frameIndex++)
                {
                    frameInfo.Add(new AnimationFrame() { DelayInMs = cmdLine.FrameDelayInMs, Image = new ImageIdentifier(imgPath, frameIndex) }.AsConst());
                }
            }
            else
            {
                foreach (int frameIndex in cmdLine.FrameIndexes)
                {
                    if (frameIndex >= frames.Count)
                    {
                        Console.Error.WriteLine("{0} in {1} has {2} frames in it, so frame index {3} is not valid.", imgPath, cmdLine.NpkPath, frames.Count, frameIndex);
                        Environment.Exit(1);
                    }
                    frameInfo.Add(new AnimationFrame() { DelayInMs = cmdLine.FrameDelayInMs, Image = new ImageIdentifier(imgPath, frameIndex) }.AsConst());
                }
            }

            return frameInfo;
        }
Example #2
0
 static NpkDirContents GetNpkContents(string npkFilePath)
 {
     using (NpkReader npk = new NpkReader(npkFilePath))
     {
         return new NpkDirContents(Path.GetFileName(npkFilePath), npk.Frames);
     }
 }
Example #3
0
        private static NpkPath GetImgPath(CommandLineArgs cmdLine, NpkReader npk)
        {
            if (cmdLine.ImgPath != null)
            {
                NpkPath imgPath = new NpkPath(cmdLine.ImgPath);
                IList<NpkPath> imgPathComponents = imgPath.GetPathComponents();
                if (imgPathComponents.Count >= 1 && !imgPathComponents[0].Path.Equals("sprite", StringComparison.OrdinalIgnoreCase))
                {
                    // add sprite/ prefix if present
                    imgPath = NpkPath.Combine("sprite", imgPath);
                }

                if (!npk.Images.ContainsKey(imgPath))
                {
                    Console.Error.WriteLine("There is no img file with path {0} in NPK file {1}", cmdLine.ImgPath, cmdLine.NpkPath);
                    Environment.Exit(1);
                }

                return imgPath;
            }
            else
            {
                List<NpkPath> matchingPaths = new List<NpkPath>();

                // Only the .img name was given. Look for it.
                foreach (NpkPath path in npk.Images.Keys)
                {
                    if (path.GetFileName().Path.Equals(cmdLine.ImgName, StringComparison.OrdinalIgnoreCase))
                    {
                        matchingPaths.Add(path);
                    }
                }

                if (matchingPaths.Count == 1)
                {
                    return matchingPaths[0];
                }
                else if (matchingPaths.Count == 0)
                {
                    Console.Error.WriteLine("There is no img file called {0} in NPK file {1}", cmdLine.ImgName, cmdLine.NpkPath);
                    Environment.Exit(1);
                    return null; // not reached
                }
                else
                {
                    Console.Error.WriteLine("There are multiple img files matching the name {0} in NPK file {1}: {2}", cmdLine.ImgName, cmdLine.NpkPath, string.Join(", ", matchingPaths));
                    Environment.Exit(1);
                    return null; // not reached
                }
            }
        }
Example #4
0
        public void Dispose()
        {
            if (_reader != null)
            {
                _reader.Dispose();
                _reader = null;
            }
            if (_npkStream != null)
            {
                _npkStream.Dispose();
                _npkStream = null;
            }

            _openFilePath = null;
            _disposed     = true;
        }
Example #5
0
        /// <summary>
        /// If opening fails, the state is the same as it was before the open.
        /// </summary>
        /// <param name="path"></param>
        public void Open(string path)
        {
            ThrowIfDisposed();

            // Open new file first to get any errors out of the way, then switch to it
            NpkReader  newReader = null;
            FileStream newStream = null;

            try
            {
                newReader = new NpkReader(path);
                newStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            catch (Exception)
            {
                if (newStream != null)
                {
                    newStream.Dispose();
                    newReader.Dispose();
                }

                throw;
            }

            NpkReader  oldReader = _reader;
            FileStream oldStream = _npkStream;

            _reader       = newReader;
            _npkStream    = newStream;
            _openFilePath = path;

            if (oldStream != null)
            {
                oldStream.Dispose();
            }
            if (oldReader != null)
            {
                oldReader.Dispose();
            }
        }
Example #6
0
        static void Main(string[] args)
        {
            using (NpkReader npk = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_character_fighter_equipment_avatar_cap.NPK"))
            {
                npk.PreLoadAllSpriteFrameMetadata();
                List<NpkPath> imgs = npk.Frames.Where(kvp => kvp.Value.Any(f => f.CompressedLength == 84)).Select(kvp => kvp.Key).ToList();
                foreach (NpkPath img in imgs)
                {
                    IReadOnlyList<FrameInfo> frames = npk.Frames[img];
                    for (int i = 0; i < frames.Count; i++)
                    {
                        if (frames[i].CompressedLength == 84 && !frames[i].IsCompressed)
                        {
                            Console.WriteLine(string.Format("{0} {1}", img, i));
                        }
                    }
                }
            }

            Environment.Exit(0);

            foreach (string path in Directory.GetFiles(@"C:\Neople\DFO\ImagePacks2", "*.NPK"))
            {
                Console.WriteLine(path);
                using (NpkReader npk = new NpkReader(path))
                {
                    npk.PreLoadAllSpriteFrameMetadata();
                    foreach (NpkPath npkPath in npk.Frames.Keys)
                    {
                        var x = npk.Frames[npkPath];
                        for(int i = 0; i < x.Count; i++)
                        {
                            FrameInfo frame = x[i];
                            if (!frame.IsCompressed && frame.LinkFrame == null)
                            {
                                string pixelFormatString = frame.PixelFormat.ToString();
                                int actualLength = frame.Width * frame.Height * 2;
                                if (frame.PixelFormat == PixelDataFormat.EightEightEightEight)
                                {
                                    actualLength *= 2;
                                }
                                if (frame.CompressedLength != actualLength)
                                {
                                    Console.WriteLine("Pixel Format: {0,22}, Compressed Length: {1,9}, Actual Length: {2,9} {3} {4}", pixelFormatString, frame.CompressedLength, actualLength, npkPath, i);
                                }
                            }
                        }
                    }
                }
            }

            Environment.Exit(0);

            using (NpkReader npkReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_monster_impossible_bakal.NPK"))
            using (NpkReader coolReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_character_swordman_effect_sayaex.NPK"))
            {
                DFO.Common.Images.Image image = npkReader.GetImage("monster/impossible_bakal/ashcore.img", 0);
                //Image image2 = npkReader.GetImage("worldmap/act1/elvengard.img", 1);
                using (Bitmap bitmap = new Bitmap(image.Attributes.Width, image.Attributes.Height))
                {
                    BitmapData raw = bitmap.LockBits(new Rectangle(0, 0, image.Attributes.Width, image.Attributes.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    unsafe
                    {
                        byte* ptr = (byte*)raw.Scan0;
                        // RGBA -> BGRA (pixels in the bitmap have endianness)
                        int width = image.Attributes.Width;
                        int height = image.Attributes.Height;
                        int stride = raw.Stride;
                        for (int x = 0; x < width; x++)
                        {
                            for (int y = 0; y < height; y++)
                            {
                                ptr[y * stride + x * 4 + 0] = image.PixelData[y * width * 4 + x * 4 + 2];
                                ptr[y * stride + x * 4 + 1] = image.PixelData[y * width * 4 + x * 4 + 1];
                                ptr[y * stride + x * 4 + 2] = image.PixelData[y * width * 4 + x * 4 + 0];
                                ptr[y * stride + x * 4 + 3] = image.PixelData[y * width * 4 + x * 4 + 3];
                            }
                        }
                    }
                    bitmap.UnlockBits(raw);
                    bitmap.Save(@"output.png", System.Drawing.Imaging.ImageFormat.Png);

                    RawAnimation animationData = new RawAnimation();
                    animationData.Loop = true;
                    animationData.Frames = new List<ConstAnimationFrame>()
                    {
                        new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 0) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 1) }.AsConst()
                    };

                    RawAnimation cool = new RawAnimation();
                    cool.Loop = true;
                    cool.Frames = new List<ConstAnimationFrame>()
                    {
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 0) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 1) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 2) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 3) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 4) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 5) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 6) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 7) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 8) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 9) }.AsConst(),
                    };

                    using (GifMaker giffer = new GifMaker(npkReader, disposeImageSource: false))
                    using (GifMaker coolGiffer = new GifMaker(coolReader, disposeImageSource: false))
                    using (FileStream gifOutputStream = new FileStream("output.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                    using (FileStream coolGifOutputStream = new FileStream("cool.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                    {
                        giffer.Create(animationData.AsConst(), gifOutputStream);
                        coolGiffer.Create(cool.AsConst(), coolGifOutputStream);
                    }
                }

                Console.WriteLine("Success!");
            }
        }
Example #7
0
        static void Main(string[] args)
        {
            foreach (string path in Directory.GetFiles(@"C:\Neople\DFO\ImagePacks2", "*.NPK"))
            {
                using (NpkReader npk = new NpkReader(path))
                {
                    if (npk.Images.Keys.Any(img => img.Path.EndsWith("bufficon.img")))
                    {
                        Console.WriteLine(path);
                        Environment.Exit(0);
                    }

                    Console.WriteLine("Read {0}", path);
                }
            }

            Console.WriteLine("Not found!");
            Environment.Exit(0);

            using (NpkReader npkReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_monster_impossible_bakal.NPK"))
            using (NpkReader coolReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_character_swordman_effect_sayaex.NPK"))
            {
                DFO.Common.Images.Image image = npkReader.GetImage("monster/impossible_bakal/ashcore.img", 0);
                //Image image2 = npkReader.GetImage("worldmap/act1/elvengard.img", 1);
                using (Bitmap bitmap = new Bitmap(image.Attributes.Width, image.Attributes.Height))
                {
                    BitmapData raw = bitmap.LockBits(new Rectangle(0, 0, image.Attributes.Width, image.Attributes.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
                    unsafe
                    {
                        byte* ptr = (byte*)raw.Scan0;
                        // RGBA -> BGRA (pixels in the bitmap have endianness)
                        int width = image.Attributes.Width;
                        int height = image.Attributes.Height;
                        int stride = raw.Stride;
                        for (int x = 0; x < width; x++)
                        {
                            for (int y = 0; y < height; y++)
                            {
                                ptr[y * stride + x * 4 + 0] = image.PixelData[y * width * 4 + x * 4 + 2];
                                ptr[y * stride + x * 4 + 1] = image.PixelData[y * width * 4 + x * 4 + 1];
                                ptr[y * stride + x * 4 + 2] = image.PixelData[y * width * 4 + x * 4 + 0];
                                ptr[y * stride + x * 4 + 3] = image.PixelData[y * width * 4 + x * 4 + 3];
                            }
                        }
                    }
                    bitmap.UnlockBits(raw);
                    bitmap.Save(@"output.png", System.Drawing.Imaging.ImageFormat.Png);

                    RawAnimation animationData = new RawAnimation();
                    animationData.Loop = true;
                    animationData.Frames = new List<ConstAnimationFrame>()
                    {
                        new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 0) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 1) }.AsConst()
                    };

                    RawAnimation cool = new RawAnimation();
                    cool.Loop = true;
                    cool.Frames = new List<ConstAnimationFrame>()
                    {
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 0) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 1) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 2) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 3) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 4) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 5) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 6) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 7) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 8) }.AsConst(),
                        new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 9) }.AsConst(),
                    };

                    using (GifMaker giffer = new GifMaker(npkReader, disposeImageSource: false))
                    using (GifMaker coolGiffer = new GifMaker(coolReader, disposeImageSource: false))
                    using (FileStream gifOutputStream = new FileStream("output.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                    using (FileStream coolGifOutputStream = new FileStream("cool.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                    {
                        giffer.Create(animationData.AsConst(), gifOutputStream);
                        coolGiffer.Create(cool.AsConst(), coolGifOutputStream);
                    }
                }

                Console.WriteLine("Success!");
            }
        }
Example #8
0
        private static NpkReader LoadNpk(string path)
        {
            NpkReader npk = null;
            try
            {
                npk = new NpkReader(path);
            }
            catch (FileNotFoundException)
            {
                Console.Error.WriteLine("NPK file {0} not found.", path);
                Environment.Exit(1);
            }
            catch (UnauthorizedAccessException)
            {
                Console.Error.WriteLine("You do not have permission to read NPK file {0}", path);
                Environment.Exit(1);
            }
            catch (NpkException ex)
            {
                Console.Error.WriteLine("There was an error while loading the NPK file. The file format may have changed. Here is some information that may help debug the issue: {0}\n\n{1}", Utils.GetExceptionMessageWithInnerExceptions(ex), ex.StackTrace);
                Environment.Exit(1);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("There was an error while loading the NPK file: {0}", ex.Message);
                Environment.Exit(1);
            }

            return npk;
        }
        public void Open(string npkPath)
        {
            if (!CanOpen)
            {
                return;
            }

            // TODO: async?
            try
            {
                NpkReader oldNpk = _npk;
                _npk = new NpkReader(npkPath);
                if (oldNpk != null)
                {
                    oldNpk.Dispose();
                }
            }
            catch (Exception ex)
            {
                // Display error
                // Handle NpkExcption separately?
                // Better way of displaying than modal?
                MessageBox.Show(string.Format("Error opening NPK file: {0}", ex.Message));
                return;
            }

            InnerFileList.Clear();
            FrameList.Clear();
            foreach (NpkPath imgPath in _npk.Images.Keys)
            {
                string imgName = imgPath.GetPathComponents().LastOrDefault();
                if (imgName == null) continue; // TODO: Log this, something would have to be strange
                InnerFileList.Add(new InnerNpkFile(name: imgName, path: imgPath.Path));
            }

            // Select first .img
            if (InnerFileList.Count > 0)
            {
                InnerFileList.MoveCurrentToFirst();
            }
        }
Example #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="imgPath"></param>
        /// <param name="frameIndex"></param>
        /// <param name="newFrameMetadata">If this indicates a link frame, <paramref name="newFramePixels"/> is ignored. The IsCompressed flag is honored, compressing the image if it is set. The CompressedLength field is not used.</param>
        /// <param name="newFramePixels">Readable stream consisting solely of the pixel data, in the format indicated by the metadata.</param>
        public void EditFrame(NpkPath imgPath, int frameIndex, FrameInfo newFrameMetadata, Stream newFramePixels)
        {
            ThrowIfDisposed();
            ThrowIfNoFileOpen();

            if (!_reader.Frames.ContainsKey(imgPath))
            {
                throw new ArgumentException("{0} is not in the NPK.".F(imgPath));
            }

            if (frameIndex >= _reader.Frames[imgPath].Count)
            {
                throw new ArgumentException("{0} does not have a frame {1}.".F(imgPath, frameIndex));
            }

            NpkFileTableEntry         entryOfImgEditing     = _reader.Files.Where(f => f.Name.Equals(imgPath)).First();
            IReadOnlyList <FrameInfo> frameListOfImgEditing = _reader.Frames[imgPath];
            FrameInfo frameMetadataOfFrameEditing           = frameListOfImgEditing[frameIndex];

            // Render the new frame in memory

            // pixelData is null if it's a link frame
            // pixelData length may be bigger than the actual pixel data. Use newPixelDataLength instead of newPixelData.Length
            int newPixelDataLength;

            byte[] newPixelData       = GetPixelData(newFrameMetadata, newFramePixels, out newPixelDataLength);
            byte[] frameMetadataBytes = GetFrameMetadataBytes(newFrameMetadata, newPixelDataLength);

            string tempNpkPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() + ".NPK");

            using (FileStream tempFileStream = File.OpenWrite(tempNpkPath))
            {
                WriteEditedNPK(tempFileStream, imgPath, entryOfImgEditing, frameIndex, frameListOfImgEditing, frameMetadataOfFrameEditing, newFrameMetadata, newPixelData, newPixelDataLength, frameMetadataBytes);
            }

            // temp file now has the new NPK!
            // close _reader
            // close _npkStream
            // delete original file
            // move temp file

            // TODO: "refresh" it
            _reader.Dispose();
            _npkStream.Dispose();

            // TODO: Error handling
            File.Delete(_openFilePath);

            File.Move(tempNpkPath, _openFilePath);

            // reopen
            try
            {
                _reader = new NpkReader(_openFilePath);
            }
            catch (Exception)
            {
                _openFilePath = null;
                _reader       = null;
                _npkStream    = null;
                throw;
            }

            try
            {
                _npkStream = new FileStream(_openFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            catch (Exception)
            {
                _openFilePath = null;
                _reader.Dispose();
                _reader    = null;
                _npkStream = null;
                throw;
            }
        }
 public LazyFramesReadOnlyDictionary(NpkReader npk)
 {
     npk.ThrowIfNull("npk");
     m_npk = npk;
 }