/// <summary>
        ///     Encodes the specified <see cref="SkeletonImage"/> into a byte array.
        /// </summary>
        /// <remarks>
        ///     This codification uses two bytes to store <see cref="SkeletonImage.Width"/>; two more bytes to store <see cref="SkeletonImage.Height"/>; and one bit for each pixel of the <see cref="SkeletonImage"/>. Therefore, this method is ineffective for values of <see cref="SkeletonImage.Width"/> and <see cref="SkeletonImage.Height"/> greater than 65535.
        /// </remarks>
        /// <param name="skImg">The <see cref="SkeletonImage"/> object which is going to be encoded to a byte array.</param>
        /// <returns>The byte array containing the encoded <see cref="SkeletonImage"/> object.</returns>
        public static byte[] ToByteArray(SkeletonImage skImg)
        {
            int length = (int)Math.Ceiling(skImg.Width * skImg.Height / 8.0);

            byte[] raw = new byte[length + 4];

            raw[0] = (byte)(255 & skImg.Width);
            raw[1] = (byte)(255 & (skImg.Width >> 8));
            raw[2] = (byte)(255 & skImg.Height);
            raw[3] = (byte)(255 & (skImg.Height >> 8));

            int counter   = 0;
            int cursor    = 4;
            int currValue = 0;

            for (int i = 0; i < skImg.Height; i++)
            {
                for (int j = 0; j < skImg.Width; j++)
                {
                    currValue |= (skImg[i, j] == 255 ? 1 : 0) << counter;
                    if (counter == 7)
                    {
                        raw[cursor++] = (byte)currValue;
                        currValue     = 0;
                        counter       = 0;
                    }
                    else
                    {
                        counter++;
                    }
                }
            }

            return(raw);
        }
        internal JYMtiaDescriptor(SkeletonImage skeletonImage, List<Minutia> minutiae, short mainMtiaIdx, short mtiaIdx0, short mtiaIdx1)
        {
            this.minutiae = minutiae;
            this.mainMtiaIdx = mainMtiaIdx;
            nearestMtiaIdx = mtiaIdx0;
            farthestMtiaIdx = mtiaIdx1;

            MtiaEuclideanDistance dist = new MtiaEuclideanDistance();
            dist0 = dist.Compare(MainMinutia, NearestMtia);
            dist1 = dist.Compare(MainMinutia, FarthestMtia);
            if (dist1 < dist0)
            {
                nearestMtiaIdx = mtiaIdx1;
                farthestMtiaIdx = mtiaIdx0;
                double temp = dist0;
                dist0 = dist1;
                dist1 = temp;
            }

            alpha0 = ComputeAlpha(MainMinutia, NearestMtia);
            alpha1 = ComputeAlpha(MainMinutia, FarthestMtia);

            beta0 = ComputeBeta(MainMinutia, NearestMtia);
            beta1 = ComputeBeta(MainMinutia, FarthestMtia);

            ridgeCount0 = ComputeRidgeCount(skeletonImage, MainMinutia, NearestMtia);
            ridgeCount1 = ComputeRidgeCount(skeletonImage, MainMinutia, FarthestMtia);
        }
        /// <summary>
        ///     Save the specified <see cref="SkeletonImage"/> to the specified file name.
        /// </summary>
        /// <remarks>
        ///     Before saving, the <see cref="SkeletonImage"/> is encoded using the method <see cref="ToByteArray"/>.
        /// </remarks>
        /// <param name="fileName">The file name where the specified <see cref="SkeletonImage"/> will be saved.</param>
        /// <param name="skImg">The <see cref="SkeletonImage"/> to be saved.</param>
        public static void Serialize(string fileName, SkeletonImage skImg)
        {
            var byteArr = ToByteArray(skImg);

            File.WriteAllBytes(fileName, byteArr);
        }
        /// <summary>
        ///     Encodes the specified <see cref="SkeletonImage"/> into a byte array.
        /// </summary>
        /// <remarks>
        ///     This codification uses two bytes to store <see cref="SkeletonImage.Width"/>; two more bytes to store <see cref="SkeletonImage.Height"/>; and one bit for each pixel of the <see cref="SkeletonImage"/>. Therefore, this method is ineffective for values of <see cref="SkeletonImage.Width"/> and <see cref="SkeletonImage.Height"/> greater than 65535.
        /// </remarks>
        /// <param name="skImg">The <see cref="SkeletonImage"/> object which is going to be encoded to a byte array.</param>
        /// <returns>The byte array containing the encoded <see cref="SkeletonImage"/> object.</returns>
        public static byte[] ToByteArray(SkeletonImage skImg)
        {
            int length = (int)Math.Ceiling(skImg.Width * skImg.Height / 8.0);
            byte[] raw = new byte[length + 4];

            raw[0] = (byte)(255 & skImg.Width);
            raw[1] = (byte)(255 & (skImg.Width >> 8));
            raw[2] = (byte)(255 & skImg.Height);
            raw[3] = (byte)(255 & (skImg.Height >> 8));

            int counter = 0;
            int cursor = 4;
            int currValue = 0;
            for (int i = 0; i < skImg.Height; i++)
                for (int j = 0; j < skImg.Width; j++)
                {
                    currValue |= (skImg[i, j] == 255 ? 1 : 0) << counter;
                    if (counter == 7)
                    {
                        raw[cursor++] = (byte)currValue;
                        currValue = 0;
                        counter = 0;
                    }
                    else
                        counter++;
                }

            return raw;
        }
 /// <summary>
 ///     Save the specified <see cref="SkeletonImage"/> to the specified file name.
 /// </summary>
 /// <remarks>
 ///     Before saving, the <see cref="SkeletonImage"/> is encoded using the method <see cref="ToByteArray"/>.
 /// </remarks>
 /// <param name="fileName">The file name where the specified <see cref="SkeletonImage"/> will be saved.</param>
 /// <param name="skImg">The <see cref="SkeletonImage"/> to be saved.</param>
 public static void Serialize(string fileName, SkeletonImage skImg)
 {
     var byteArr = ToByteArray(skImg);
     File.WriteAllBytes(fileName, byteArr);
 }
 private byte ComputeRidgeCount(SkeletonImage skeletonImage, Minutia mtia0, Minutia mtia1)
 {
     return skeletonImage.RidgeCount(mtia0.X, mtia0.Y, mtia1.X, mtia1.Y);
 }