public static int CountJpegsFrames(string filename)
        {
            int count = 0;

            try
            {
                int     batchsize         = 1000;
                int     linelimit         = 0;
                byte?[] jpegHeaderpattern =
                    new byte?[] { 0x69, 0x6D, 0x61, 0x67, 0x65, 0x2F, 0x6A, 0x70, 0x65, 0x67 };
                //new byte?[] { 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x6E, 0x74, 0x2D, 0x6C, 0x65, 0x6E, 0x67, 0x74, 0x68, 0x3A };
                //new byte?[] { 0xFF, 0xD8, 0xFF, 0xE0, 0x00, 0x10, 0x4A, 0x46, 0x49, 0x46 };
                //new byte?[]{0x2D, 0x2D, 0x76, 0x69, 0x64, 0x65, 0x6F, 0x62, 0x6F, 0x75, 0x6E, 0x64, 0x61, 0x72, 0x79};
                //new byte?[] { 0xFF, null, 0xFF, null };
                byte[] buffer = new byte[batchsize];
                using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
                {
                    while (br.BaseStream.Length > br.BaseStream.Position)
                    {
                        int datastart = ByteArrayUtils.IndexOf(buffer, jpegHeaderpattern, linelimit, batchsize);
                        if (datastart != -1)
                        {
                            count++;
                        }
                        Array.Copy(br.ReadBytes(batchsize), buffer, batchsize);
                    }
                }
            }
            catch (Exception ee)
            {
                DebugMessageLogger.LogError(ee);
            }
            return(count);
        }
        /// <summary>
        /// This method looks for the index at the end of the frame packet. This should be in the format DateTime.Int
        /// following a final "--videoboundary"
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="stampA"></param>
        /// <param name="stampB"></param>
        /// <returns></returns>
        public static List <KeyValuePair <DateTime, int> > GetTimeStampsFromFrameIndex(byte[] buffer)
        {
            List <KeyValuePair <DateTime, int> > times = new List <KeyValuePair <DateTime, int> >();
            long utcmask       = ((long)DateTimeKind.Utc << 62);
            long localantimask = ~((long)DateTimeKind.Local << 62);

            long unspmask = ~((long)3 << 62);

            try
            {
                ASCIIEncoding encoder    = new ASCIIEncoding();
                string        stamp      = "--videoboundary--";
                byte[]        stampbytes = encoder.GetBytes(stamp);

                int index_of_index = -1;
                int pos            = buffer.Length;

                while (index_of_index == -1 && pos > 0)
                {
                    pos           -= 5000;
                    index_of_index = ByteArrayUtils.IndexOf(buffer, stampbytes, pos, buffer.Length - pos);
                }
                if (index_of_index == -1)
                {
                    throw new IOException("Invalid buffer");
                }

                pos = index_of_index + stampbytes.Length;
                while (pos < buffer.Length - 12)
                {
                    long bytes = BitConverter.ToInt64(buffer, pos);
                    //bytes = bytes | utcmask;
                    //bytes = bytes & localantimask;
                    bytes = bytes & unspmask;
                    DateTime time = DateTime.FromBinary(bytes);

                    //this fixes the timezone issue
                    time = ChangeDateTimeKind(time, DateTimeKind.Utc);

                    int bytepos = BitConverter.ToInt32(buffer, pos + 8);

                    //sometimes there are blank bytes at the end of the file. Don't record these as index entries.
                    //if (bytepos > 0)
                    times.Add(new KeyValuePair <DateTime, int>(time, bytepos));

                    pos += 12;
                }
            }
            catch (Exception ee)
            {
                DebugMessageLogger.LogError(ee);
            }

            return(times);
        }
        public static bool GetDimensionsOfImageFromJpegData(byte[] jpegdata, out int width, out int height)
        {
            bool success = false;

            width  = 0;
            height = 0;
            int loc = 0;

            try
            {
                int trys = 0;
                while (success == false && loc != -1 && loc < 2000 && trys < 20)
                {
                    loc = ByteArrayUtils.IndexOf(jpegdata, new byte[] { 0xFF, 0xC0 }, loc, 2000);

                    if (loc > 0)
                    {
                        byte[] heightbyte = new byte[] { jpegdata[loc + 6], jpegdata[loc + 5] }; //make BigEndian
                        byte[] widthbyte  = new byte[] { jpegdata[loc + 8], jpegdata[loc + 7] };

                        height = BitConverter.ToInt16(heightbyte, 0);

                        width = BitConverter.ToInt16(widthbyte, 0);

                        if (height > 0 && height < 65535 &&
                            width > 0 && width < 65535)
                        {
                            success = true;
                        }
                        else
                        {
                            success = false;
                            loc    += 2;
                            trys++;
                        }
                    }
                }

                if (success == false)
                {
                    DebugMessageLogger.LogEvent("Failed to recover good height ({0}) and width ({1}) from jpeg data. Tried {2} times", width, height, trys);
                }
            }
            catch (Exception ee)
            {
                success = false;
                DebugMessageLogger.LogError(ee);
            }

            return(success);
        }
        public static string GetPrefixedLine(byte[] array, string prefix, int startIndex, int count, Encoding encoding, out int lineLimit)
        {
            lineLimit = -1;
            byte[] prefixBytes = encoding.GetBytes(prefix);

            int prefixPosition = ByteArrayUtils.IndexOf(array, prefixBytes, startIndex, count);

            if (prefixPosition == -1)
            {
                return(null);
            }
            return(ByteArrayUtils.GetLine(array, prefixPosition + prefixBytes.Length,
                                          count - prefixPosition - prefixBytes.Length + startIndex, encoding, out lineLimit));
        }
        /// <summary>
        /// This method looks for the index at the end of the frame packet. This should be in the format DateTime.Int
        /// following a final "--videoboundary"
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="stampA"></param>
        /// <param name="stampB"></param>
        /// <returns></returns>
        public static List <KeyValuePair <DateTime, int> > GetTimeStampsFromFrameIndex(byte[] buffer, DateTime start, TimeSpan duration)
        {
            List <KeyValuePair <DateTime, int> > times = new List <KeyValuePair <DateTime, int> >();
            long utcmask       = ((long)DateTimeKind.Utc << 62);
            long localantimask = ~((long)DateTimeKind.Local << 62);

            DateTime end = start + duration;

            //this is because the gob start time from the db can be slightly off the first frame time
            DateTime startLimit = start.AddSeconds(-120);
            DateTime endLimit   = end.AddSeconds(120);
            TimeSpan?offset     = null;

            //long unspmask = ~((long)3 << 62);

            try
            {
                ASCIIEncoding encoder    = new ASCIIEncoding();
                string        stamp      = "--videoboundary--";
                byte[]        stampbytes = encoder.GetBytes(stamp);

                int index_of_index = -1;
                int pos            = buffer.Length;

                while (index_of_index == -1 && pos > 0)
                {
                    pos           -= 5000;
                    index_of_index = ByteArrayUtils.IndexOf(buffer, stampbytes, pos, buffer.Length - pos);
                }
                if (index_of_index == -1)
                {
                    throw new IOException("Invalid buffer");
                }

                pos = index_of_index + stampbytes.Length;
                while (pos < buffer.Length - 12)
                {
                    long bytes = BitConverter.ToInt64(buffer, pos);
                    bytes = bytes | utcmask;
                    bytes = bytes & localantimask;
                    //bytes = bytes & unspmask;
                    DateTime time = DateTime.FromBinary(bytes);

                    //this fixes the timezone issue
                    //time = ChangeDateTimeKind(time, DateTimeKind.Utc);

                    //rationality check, for timezone and daylight savings problems
                    if (time < startLimit || time > endLimit)
                    {
                        if (offset.HasValue == false)
                        {
                            long roundedticks = (long)((time.Ticks / 10000) * 10000);
                            long diff         = time.Ticks - roundedticks;
                            if (diff > 5000)  ///to unround the number (workaround for a bug on some pcs)
                            {
                                roundedticks += 10000;
                            }
                            DateTime roundedTime = new DateTime(roundedticks);
                            //assume first frame
                            offset = start - roundedTime;

                            DebugMessageLogger.LogEvent("Time is off in this Frame Packet - adjusting by {0}", offset);
                        }
                        time = time + offset.Value;
                    }

                    int bytepos = BitConverter.ToInt32(buffer, pos + 8);

                    //sometimes there are blank bytes at the end of the file. Don't record these as index entries.
                    //if (bytepos > 0)
                    times.Add(new KeyValuePair <DateTime, int>(time, bytepos));

                    pos += 12;
                }
            }
            catch (Exception ee)
            {
                DebugMessageLogger.LogError(ee);
            }

            return(times);
        }