예제 #1
0
        public override TemplateBuilder Import(XElement template)
        {
            int version = (int)template.Attribute("Version");

            if (version < 1 || version > 2)
            {
                throw new ApplicationException("Versão de template desconhecido");
            }
            TemplateBuilder builder = new TemplateBuilder()
            {
                Minutiae = (from minutia in template.Elements("Minuncia")
                            select new TemplateBuilder.Minutia()
                {
                    Position = new Point(
                        (int)minutia.Attribute("X"),
                        (int)minutia.Attribute("Y")),
                    Direction = (byte)(uint)minutia.Attribute("Direção"),
                    Type = (TemplateBuilder.MinutiaType)Enum.Parse(
                        typeof(TemplateBuilder.MinutiaType),
                        (string)minutia.Attribute("Tipo"),
                        false)
                }).ToList()
            };

            if (version >= 2)
            {
                builder.OriginalDpi    = (int)template.Attribute("OriginalDpi");
                builder.OriginalWidth  = (int)template.Attribute("OriginalWidth");
                builder.OriginalHeight = (int)template.Attribute("OriginalHeight");
            }
            else
            {
                builder.OriginalDpi       = 500;
                builder.StandardDpiWidth  = template.Elements("Minuncia").Max(e => (int)e.Attribute("X")) + 1;
                builder.StandardDpiHeight = template.Elements("Minuncia").Max(e => (int)e.Attribute("Y")) + 1;
            }
            return(builder);
        }
예제 #2
0
        // References:
        // http://www.italdata-roma.com/PDF/Norme%20ISO-IEC%20Minutiae%20Data%20Format%2019794-2.pdf
        // https://biolab.csr.unibo.it/fvcongoing/UI/Form/Download.aspx (ISO section, sample ZIP, ISOTemplate.pdf)
        //
        // Format (all numbers are big-endian):
        // 4B magic "FMR\0"
        // 4B version (ignored, set to " 20\0"
        // 4B total length (including header)
        // 2B rubbish (zeroed)
        // 2B image size in pixels X
        // 2B image size in pixels Y
        // 2B rubbish (pixels per cm X, set to 196 = 500dpi)
        // 2B rubbish (pixels per cm Y, set to 196 = 500dpi)
        // 1B rubbish (number of fingerprints, set to 1)
        // 1B rubbish (zeroed)
        // 1B rubbish (finger position, zeroed)
        // 1B rubbish (zeroed)
        // 1B rubbish (fingerprint quality, set to 100)
        // 1B minutia count
        // N*6B minutiae
        //      2B minutia position X in pixels
        //          2b (upper) minutia type (01 ending, 10 bifurcation, 00 other (considered ending))
        //      2B minutia position Y in pixels (upper 2b ignored, zeroed)
        //      1B direction, compatible with SourceAFIS angles
        //      1B quality (ignored, zeroed)
        // 2B rubbish (extra data length, zeroed)
        // N*1B rubbish (extra data)

        public override byte[] Export(TemplateBuilder builder)
        {
            MemoryStream stream = new MemoryStream();
            BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8);

            checked
            {
                // 4B magic "FMR\0"
                writer.Write("FMR\0".ToCharArray());

                // 4B version (ignored, set to " 20\0"
                writer.Write(" 20\0".ToCharArray());

                // 4B total length (including header, will be updated later)
                writer.Write(0);

                // 2B rubbish (zeroed)
                writer.Write((short)0);

                // 2B image size in pixels X
                writer.Write(IPAddress.HostToNetworkOrder((short)builder.StandardDpiWidth));

                // 2B image size in pixels Y
                writer.Write(IPAddress.HostToNetworkOrder((short)builder.StandardDpiHeight));

                // 2B rubbish (pixels per cm X, set to 196 = 500dpi)
                writer.Write(IPAddress.HostToNetworkOrder((short)196));

                // 2B rubbish (pixels per cm Y, set to 196 = 500dpi)
                writer.Write(IPAddress.HostToNetworkOrder((short)196));

                // 1B rubbish (number of fingerprints, set to 1)
                writer.Write((byte)1);

                // 1B rubbish (zeroed)
                writer.Write((byte)0);

                // 1B rubbish (finger position, zeroed)
                writer.Write((byte)0);

                // 1B rubbish (zeroed)
                writer.Write((byte)0);

                // 1B rubbish (fingerprint quality, set to 100)
                writer.Write((byte)100);

                // 1B minutia count
                writer.Write((byte)builder.Minutiae.Count);

                // N*6B minutiae
                foreach (var minutia in builder.Minutiae)
                {
                    //      2B minutia position X in pixels
                    //          2b (upper) minutia type (01 ending, 10 bifurcation, 00 other (considered ending))
                    int x = minutia.Position.X;
                    AssertException.Check(x <= 0x3fff, "X position is out of range");
                    int type = minutia.Type == TemplateBuilder.MinutiaType.Extremidade ? 0x4000 : 0x8000;
                    writer.Write(IPAddress.HostToNetworkOrder(unchecked ((short)(x | type))));

                    //      2B minutia position Y in pixels (upper 2b ignored, zeroed)
                    int y = builder.StandardDpiHeight - minutia.Position.Y - 1;
                    AssertException.Check(y <= 0x3fff, "Y position is out of range");
                    writer.Write(IPAddress.HostToNetworkOrder((short)y));

                    //      1B direction, compatible with SourceAFIS angles
                    writer.Write(minutia.Direction);

                    //      1B quality (ignored, zeroed)
                    writer.Write((byte)0);
                }

                // 2B rubbish (extra data length, zeroed)
                // N*1B rubbish (extra data)
                writer.Write((short)0);
            }

            writer.Close();

            // update length
            byte[] template = stream.ToArray();
            BitConverter.GetBytes(IPAddress.HostToNetworkOrder(template.Length)).CopyTo(template, 8);

            return(template);
        }
예제 #3
0
        public override TemplateBuilder Import(byte[] template)
        {
            TemplateBuilder builder = new TemplateBuilder();

            builder.OriginalDpi = 500;

            MemoryStream stream = new MemoryStream(template);
            BinaryReader reader = new BinaryReader(stream, Encoding.UTF8);

            // 4B magic "FMR\0"
            AssertException.Check(new String(reader.ReadChars(4)) == "FMR\0", "This is not an ISO template.");

            // 4B version (ignored, set to " 20\0"
            reader.ReadChars(4);

            // 4B total length (including header)
            AssertException.Check(IPAddress.NetworkToHostOrder(reader.ReadInt32()) == template.Length, "Invalid template length.");

            // 2B rubbish (zeroed)
            reader.ReadInt16();

            // 2B image size in pixels X
            builder.StandardDpiWidth = IPAddress.NetworkToHostOrder(reader.ReadInt16());

            // 2B image size in pixels Y
            builder.StandardDpiHeight = IPAddress.NetworkToHostOrder(reader.ReadInt16());

            // 2B rubbish (pixels per cm X, set to 196 = 500dpi)
            reader.ReadInt16();

            // 2B rubbish (pixels per cm Y, set to 196 = 500dpi)
            reader.ReadInt16();

            // 1B rubbish (number of fingerprints, set to 1)
            AssertException.Check(reader.ReadByte() == 1, "Only single-fingerprint ISO templates are supported.");

            // 1B rubbish (zeroed)
            reader.ReadByte();

            // 1B rubbish (finger position, zeroed)
            reader.ReadByte();

            // 1B rubbish (zeroed)
            reader.ReadByte();

            // 1B rubbish (fingerprint quality, set to 100)
            reader.ReadByte();

            // 1B minutia count
            int minutiaCount = reader.ReadByte();

            // N*6B minutiae
            for (int i = 0; i < minutiaCount; ++i)
            {
                TemplateBuilder.Minutia minutia = new TemplateBuilder.Minutia();

                //      2B minutia position X in pixels
                //          2b (upper) minutia type (01 ending, 10 bifurcation, 00 other (considered ending))
                ushort xPacked = (ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16());
                minutia.Position.X = xPacked & (ushort)0x3fff;
                minutia.Type       = (xPacked & (ushort)0xc000) == 0x8000 ? TemplateBuilder.MinutiaType.Bifurcação : TemplateBuilder.MinutiaType.Extremidade;

                //      2B minutia position Y in pixels (upper 2b ignored, zeroed)
                minutia.Position.Y = builder.StandardDpiHeight - 1 - ((ushort)IPAddress.NetworkToHostOrder(reader.ReadInt16()) & (ushort)0x3fff);

                //      1B direction, compatible with SourceAFIS angles
                minutia.Direction = reader.ReadByte();

                //      1B quality (ignored, zeroed)
                reader.ReadByte();

                builder.Minutiae.Add(minutia);
            }

            // 2B rubbish (extra data length, zeroed)
            // N*1B rubbish (extra data)

            return(builder);
        }
예제 #4
0
 public abstract T Export(TemplateBuilder builder);
예제 #5
0
 public byte[] SerializeBuilder(TemplateBuilder builder)
 {
     return(Serialize(Export(builder)));
 }
예제 #6
0
 public override Template Export(TemplateBuilder builder)
 {
     return(new Template(builder));
 }