Esempio n. 1
0
        static Texture[] ToTextureArray(GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData)
        {
            if (gifFrameMetadata == null || imageData == null)
            {
                return(new Texture[0]);
            }

            var frames = new Texture[imageData.Length];
            int width = gifMetadata.width, height = gifMetadata.height;

            for (int i = 0; i < imageData.Length; i++)
            {
                // Create a texture and fill it with pixel data.
                Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false);
                tex.hideFlags  = HideFlags.HideAndDontSave;
                tex.wrapMode   = TextureWrapMode.Clamp;
                tex.filterMode = FilterMode.Bilinear;
                tex.anisoLevel = 0;
                tex.SetPixels32(imageData[i]);
                tex.Apply(false, false);

                frames[i] = tex;
            }

            return(frames);
        }
Esempio n. 2
0
        public void Identify_VerifyRepeatCount(string imagePath, uint repeatCount)
        {
            var testFile = TestFile.Create(imagePath);

            using (var stream = new MemoryStream(testFile.Bytes, false))
            {
                var         decoder = new GifDecoder();
                IImageInfo  image   = decoder.Identify(Configuration.Default, stream);
                GifMetadata meta    = image.Metadata.GetGifMetadata();
                Assert.Equal(repeatCount, meta.RepeatCount);
            }
        }
Esempio n. 3
0
        public void Decode_CanDecodeLargeTextComment()
        {
            var options  = new GifDecoder();
            var testFile = TestFile.Create(TestImages.Gif.LargeComment);

            using (Image <Rgba32> image = testFile.CreateRgba32Image(options))
            {
                GifMetadata metadata = image.Metadata.GetGifMetadata();
                Assert.Equal(2, metadata.Comments.Count);
                Assert.Equal(new string('c', 349), metadata.Comments[0]);
                Assert.Equal("ImageSharp", metadata.Comments[1]);
            }
        }
Esempio n. 4
0
        public void Decode_IgnoreMetadataIsTrue_CommentsAreIgnored()
        {
            var options = new GifDecoder
            {
                IgnoreMetadata = true
            };

            var testFile = TestFile.Create(TestImages.Gif.Rings);

            using (Image <Rgba32> image = testFile.CreateRgba32Image(options))
            {
                GifMetadata metadata = image.Metadata.GetGifMetadata();
                Assert.Equal(0, metadata.Comments.Count);
            }
        }
Esempio n. 5
0
        static AnimatedClip ToAnimatedClip(GifMetadata gifMetadata, GifFrameMetadata[] gifFrameMetadata, Color32[][] imageData)
        {
            if (gifFrameMetadata == null)
            {
                return(null);
            }

            int width = gifMetadata.width, height = gifMetadata.height;
            // pre-display delay is in 0.01sec units
            // we're not supporting delay time variance so just take the value of first frame.
            int fps    = (int)(1 / (gifFrameMetadata[0].delayTime * 0.01f));
            var frames = ToTextureArray(gifMetadata, gifFrameMetadata, imageData);

            return(frames != null && frames.Length > 0 ? new AnimatedClip(width, height, fps, frames) : null);
        }
Esempio n. 6
0
        public void Decode_IgnoreMetadataIsFalse_CommentsAreRead()
        {
            var options = new GifDecoder
            {
                IgnoreMetadata = false
            };

            var testFile = TestFile.Create(TestImages.Gif.Rings);

            using (Image <Rgba32> image = testFile.CreateRgba32Image(options))
            {
                GifMetadata metadata = image.Metadata.GetGifMetadata();
                Assert.Equal(1, metadata.Comments.Count);
                Assert.Equal("ImageSharp", metadata.Comments[0]);
            }
        }
Esempio n. 7
0
        public void NonMutatingEncodePreservesPaletteCount()
        {
            using (var inStream = new MemoryStream(TestFile.Create(TestImages.Gif.Leo).Bytes))
                using (var outStream = new MemoryStream())
                {
                    inStream.Position = 0;

                    var               image         = Image.Load <Rgba32>(inStream);
                    GifMetadata       metaData      = image.Metadata.GetGifMetadata();
                    GifFrameMetadata  frameMetadata = image.Frames.RootFrame.Metadata.GetGifMetadata();
                    GifColorTableMode colorMode     = metaData.ColorTableMode;
                    var               encoder       = new GifEncoder
                    {
                        ColorTableMode = colorMode,
                        Quantizer      = new OctreeQuantizer(new QuantizerOptions {
                            MaxColors = frameMetadata.ColorTableLength
                        })
                    };

                    image.Save(outStream, encoder);
                    outStream.Position = 0;

                    outStream.Position = 0;
                    var clone = Image.Load <Rgba32>(outStream);

                    GifMetadata cloneMetadata = clone.Metadata.GetGifMetadata();
                    Assert.Equal(metaData.ColorTableMode, cloneMetadata.ColorTableMode);

                    // Gifiddle and Cyotek GifInfo say this image has 64 colors.
                    Assert.Equal(64, frameMetadata.ColorTableLength);

                    for (int i = 0; i < image.Frames.Count; i++)
                    {
                        GifFrameMetadata ifm  = image.Frames[i].Metadata.GetGifMetadata();
                        GifFrameMetadata cifm = clone.Frames[i].Metadata.GetGifMetadata();

                        Assert.Equal(ifm.ColorTableLength, cifm.ColorTableLength);
                        Assert.Equal(ifm.FrameDelay, cifm.FrameDelay);
                    }

                    image.Dispose();
                    clone.Dispose();
                }
        }
Esempio n. 8
0
        public void CloneIsDeep()
        {
            var meta = new GifMetadata()
            {
                RepeatCount            = 1,
                ColorTableMode         = GifColorTableMode.Global,
                GlobalColorTableLength = 2
            };

            var clone = (GifMetadata)meta.DeepClone();

            clone.RepeatCount            = 2;
            clone.ColorTableMode         = GifColorTableMode.Local;
            clone.GlobalColorTableLength = 1;

            Assert.False(meta.RepeatCount.Equals(clone.RepeatCount));
            Assert.False(meta.ColorTableMode.Equals(clone.ColorTableMode));
            Assert.False(meta.GlobalColorTableLength.Equals(clone.GlobalColorTableLength));
        }
Esempio n. 9
0
        public void Encode_PreservesTextData()
        {
            var decoder  = new GifDecoder();
            var testFile = TestFile.Create(TestImages.Gif.LargeComment);

            using (Image <Rgba32> input = testFile.CreateRgba32Image(decoder))
                using (var memoryStream = new MemoryStream())
                {
                    input.Save(memoryStream, new GifEncoder());
                    memoryStream.Position = 0;

                    using (Image <Rgba32> image = decoder.Decode <Rgba32>(Configuration.Default, memoryStream))
                    {
                        GifMetadata metadata = image.Metadata.GetGifMetadata();
                        Assert.Equal(2, metadata.Comments.Count);
                        Assert.Equal(new string('c', 349), metadata.Comments[0]);
                        Assert.Equal("ImageSharp", metadata.Comments[1]);
                    }
                }
        }
Esempio n. 10
0
        public void Encode_IgnoreMetadataIsFalse_CommentsAreWritten()
        {
            var options = new GifEncoder();

            var testFile = TestFile.Create(TestImages.Gif.Rings);

            using (Image <Rgba32> input = testFile.CreateRgba32Image())
            {
                using (var memStream = new MemoryStream())
                {
                    input.Save(memStream, options);

                    memStream.Position = 0;
                    using (var output = Image.Load <Rgba32>(memStream))
                    {
                        GifMetadata metadata = output.Metadata.GetGifMetadata();
                        Assert.Equal(1, metadata.Comments.Count);
                        Assert.Equal("ImageSharp", metadata.Comments[0]);
                    }
                }
            }
        }
Esempio n. 11
0
        public void CloneIsDeep()
        {
            var meta = new GifMetadata
            {
                RepeatCount            = 1,
                ColorTableMode         = GifColorTableMode.Global,
                GlobalColorTableLength = 2,
                Comments = new List <string> {
                    "Foo"
                }
            };

            var clone = (GifMetadata)meta.DeepClone();

            clone.RepeatCount            = 2;
            clone.ColorTableMode         = GifColorTableMode.Local;
            clone.GlobalColorTableLength = 1;

            Assert.False(meta.RepeatCount.Equals(clone.RepeatCount));
            Assert.False(meta.ColorTableMode.Equals(clone.ColorTableMode));
            Assert.False(meta.GlobalColorTableLength.Equals(clone.GlobalColorTableLength));
            Assert.False(meta.Comments.Equals(clone.Comments));
            Assert.True(meta.Comments.SequenceEqual(clone.Comments));
        }
Esempio n. 12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GifMetadata"/> class.
 /// </summary>
 /// <param name="other">The metadata to create an instance from.</param>
 private GifMetadata(GifMetadata other)
 {
     this.RepeatCount            = other.RepeatCount;
     this.ColorTableMode         = other.ColorTableMode;
     this.GlobalColorTableLength = other.GlobalColorTableLength;
 }
Esempio n. 13
0
        public RomInfo(string decPath, bool parseImages = false)
        {
            byte[] contentBytes = File.ReadAllBytes(decPath);

            ushort headerChecksum   = CalcCrc16Modbus(contentBytes.Slice(0, HeaderChecksumOffset));
            ushort romChecksumValue = BitConverter.ToUInt16(contentBytes.Slice(HeaderChecksumOffset, 2, true).Reverse().ToArray());

            ValidContent = headerChecksum == romChecksumValue;
            if (!ValidContent)
            {
                return;
            }

            GameTitle = new string(contentBytes.Slice(GameTitleOffset, GameTitleSize).AsChars()).TrimEnd('\0');
            GameCode  = new string(contentBytes.Slice(GameCodeOffset, GameCodeSize).AsChars());

            if (GameCode.Length >= GameCodeLength)
            {
                RegionCode = GameCode[GameCodeLength - 1];
            }
            else
            {
                Log.Instance.Warn($"The gamecode for '{decPath}' is not valid: '{GameCode}'");
            }


            int titleInfoAddress = BitConverter.ToInt32(contentBytes.Slice(TitleInfoAddressOffset, TitleInfoAddressSize, true).Reverse().ToArray());

            if (titleInfoAddress == 0x00000000)
            {
                return;
            }

            TitleInfoVersion = (TitleInfoVersions)BitConverter.ToInt16(contentBytes.Slice(titleInfoAddress, 2, true).Reverse().ToArray());

            UnicodeEncoding encoding   = new UnicodeEncoding(false, false);
            int             titleCount = TitleInfoVersion == TitleInfoVersions.Original ? 6 : TitleInfoVersion == TitleInfoVersions.ChineseTitle ? 7 : 8;

            for (int i = 0; i < titleCount; i++)
            {
                Titles[i] = encoding.GetString(contentBytes.Slice(titleInfoAddress + TitleInfoTitlesOffset + TitleInfoTitleSize * i, TitleInfoTitleSize)).Trim('\0', '\uffff').AsNullIfEmpty();
            }

            if (!parseImages)
            {
                return;
            }

            // Static icon
            StaticIcon = BuildImage(ParseBitmapIndices(contentBytes.Slice(titleInfoAddress + TitleInfoStaticIconOffset, IconBitmapSize)),
                                    ParsePalette(contentBytes.Slice(titleInfoAddress + TitleInfoStaticIconOffset + IconBitmapSize, IconPaletteBytesPerColour * IconPaletteColours)));

            PngMetadata pngMetadata = StaticIcon.Metadata.GetFormatMetadata(PngFormat.Instance);

            pngMetadata.ColorType = PngColorType.Palette;
            pngMetadata.TextData  = new List <PngTextData> {
                new PngTextData("description", $"Icon for the DSiWare title \"{GetFriendlyTitle()}\" (game code \"{GameCode}\").", "en-ca", "")
            };

            // Animated icon
            if (TitleInfoVersion != TitleInfoVersions.ChineseKoreanTitlesAnimated)
            {
                return;
            }

            byte[] sequenceBytes = contentBytes.Slice(titleInfoAddress + TitleInfoAnimIconSequenceOffset, TitleInfoAnimIconSequenceFrameCount * 2);

            // Non-animated icons start with 0x01000001
            if (sequenceBytes[0] == 0x01 && sequenceBytes[1] == 0x00 && sequenceBytes[2] == 0x00 && sequenceBytes[3] == 0x01)
            {
                return;
            }

            byte[][] bitmapPaletteIndices = new byte[TitleInfoAnimIconBitmapCount][];
            for (int i = 0; i < TitleInfoAnimIconBitmapCount; i++)
            {
                bitmapPaletteIndices[i] = ParseBitmapIndices(contentBytes.Slice(
                                                                 titleInfoAddress + TitleInfoAnimIconBitmapsOffset + i * IconBitmapSize,
                                                                 IconBitmapSize));
            }

            Rgba32[][] paletteColours = new Rgba32[TitleInfoAnimIconPaletteCount][];
            for (int i = 0; i < TitleInfoAnimIconPaletteCount; i++)
            {
                paletteColours[i] = ParsePalette(contentBytes.Slice(
                                                     titleInfoAddress + TitleInfoAnimIconPalettesOffset + i * IconPaletteBytesPerColour * IconPaletteColours,
                                                     IconPaletteBytesPerColour * IconPaletteColours));
            }

            AnimatedIcon = new Image <Rgba32>(IconSquareDim, IconSquareDim);
            for (int i = 0; i < TitleInfoAnimIconSequenceFrameCount; i++)
            {
                if (sequenceBytes[i * 2] == 0x00 && sequenceBytes[i * 2 + 1] == 0x00)
                {
                    break;
                }

                bool flipVertical   = (sequenceBytes[i * 2 + 1] & 0b10000000) >> 7 == 1;
                bool flipHorizontal = (sequenceBytes[i * 2 + 1] & 0b01000000) >> 6 == 1;
                byte paletteIndex   = (byte)((sequenceBytes[i * 2 + 1] & 0b00111000) >> 3);
                byte bitmapIndex    = (byte)(sequenceBytes[i * 2 + 1] & 0b00000111);
                byte frameDuration  = sequenceBytes[i * 2];                 // in 60Hz units

                Image <Rgba32> frame = BuildImage(bitmapPaletteIndices[bitmapIndex], paletteColours[paletteIndex], flipHorizontal, flipVertical);

                ImageFrame <Rgba32> aFrame        = AnimatedIcon.Frames.AddFrame(frame.Frames.RootFrame);
                GifFrameMetadata    frameMetadata = aFrame.Metadata.GetFormatMetadata(GifFormat.Instance);
                frameMetadata.FrameDelay     = (int)Math.Round(frameDuration * FrameDurationConversion);
                frameMetadata.DisposalMethod = GifDisposalMethod.RestoreToBackground;
            }
            AnimatedIcon.Frames.RemoveFrame(0);
            AnimatedIcon.Metadata.GetFormatMetadata(GifFormat.Instance).RepeatCount = 0;
            GifMetadata gifMetadata = AnimatedIcon.Metadata.GetFormatMetadata(GifFormat.Instance);

            gifMetadata.RepeatCount = 0;
            gifMetadata.Comments    = new List <string> {
                $"Icon for the DSiWare title \"{GetFriendlyTitle()}\" (game code \"{GameCode}\")."
            };
        }