/// <summary>
        /// Display a specific sigle frame - 1 based
        /// I frame can be shown immediately, otherwise mulitple frames must be decoded
        /// backuo to find the I frame or start with P
        /// </summary>
        public void DisplayFrame(ushort frame, ushort xPos = 0, ushort yPos = 0, ushort zoom = 1)
        {
            Console.WriteLine($"Display Frame {frame} - {Data.Name}");
            bool displayed = false;

            DecodedFrameDef F = DFrames[frame - 1];

            if (F.Type == FrameType.I)
            {
                Display(F.Ifd, xPos, yPos, zoom);
                displayed = true;
            }
            else
            {
                var look = frame - 1;
                while (look >= 0)
                {
                    F = DFrames[look];
                    if (F.Type == FrameType.I)
                    {
                        Console.WriteLine($"starting at frame {look + 1}");
                        Display(F.Ifd, xPos, yPos, zoom);
                        displayed = true;

                        // Show the interveneing frames to get to the desired one
                        for (var f = look + 1; f < frame; f++)
                        {
                            var FF = DFrames[f];
                            Console.WriteLine($"  then frame {f + 1} {FF.Type}");
                            if (FF.Type == FrameType.P)
                            {
                                Display(FF.Pfd, xPos, yPos, zoom);
                            }
                        }
                        look = -1;
                    }
                    else
                    {
                        look -= 1;
                    }
                }
            }

            if (!displayed)
            {
                F = DFrames[frame - 1];
                if (F.Type == FrameType.P)
                {
                    Display(F.Pfd, xPos, yPos, zoom);
                    displayed = true;
                }
            }

            if (displayed)
            {
                graphics.Show();
            }
            else
            {
                Console.WriteLine($"WARNING !! Frame {frame} could not be displayed - {Data.Name}");
            }
        }
        private void LoadFrames()
        {
            Frames = new List <FrameDef>();
            int i = 0;

            do
            {
                string t   = Data.FramesHex.Substring(i, 2);
                int    num = int.Parse(t, NumberStyles.AllowHexSpecifier);
                i += 2;

                if (Enum.IsDefined(typeof(FrameType), num))
                {
                    FrameType FT = (FrameType)num;

                    t   = Data.FramesHex.Substring(i, 4);
                    num = int.Parse(t, NumberStyles.AllowHexSpecifier);
                    i  += 4;

                    int mult = 1;
                    if (FT == FrameType.P)
                    {
                        // how to tell 8bit or 16bit position - if row is the same 6 bytes later then 16bits
                        if (Data.FramesHex.Substring(i, 2) == Data.FramesHex.Substring(i + 6, 2))
                        {
                            mult = 6;
                        }
                        else
                        {
                            mult = 4;
                        }
                        Frames.Add(new FrameDef()
                        {
                            Type = FT, Count = (ushort)num, Data = Data.FramesHex.Substring(i, num * mult)
                        });
                    }
                    else if (FT == FrameType.I)
                    {
                        mult = 2;
                        Frames.Add(new FrameDef()
                        {
                            Type = FT, Count = (ushort)num, Data = Data.FramesHex.Substring(i, num * mult)
                        });
                    }
                    else if (FT == FrameType.D || FT == FrameType.F)
                    {
                        Frames.Add(new FrameDef()
                        {
                            Type = FT, Count = (ushort)num, Data = ""
                        });
                    }
                    i += num * mult;

                    Console.WriteLine($"  Frame {Frames.Count} is {FT} {num}");
                }
                else
                {
                    Console.WriteLine($"  WARNING!! Unexpected Frame Type {num:X2}");
                    i += 4; // ? how many bytes to skip for unknown frame type
                }
            } while (i < Data.FramesHexLength);

            // further decode the frames to remove all the Hex strings
            DFrames = new List <DecodedFrameDef>();
            foreach (var F in Frames)
            {
                DecodedFrameDef F2 = new DecodedFrameDef()
                {
                    Type = F.Type, Count = F.Count
                };

                switch (F.Type)
                {
                case FrameType.I:
                    F2.Ifd = GetIFrame(F);
                    F2.Pfd = null;
                    break;

                case FrameType.P:
                    F2.Pfd = GetPFrame(F);
                    F2.Ifd = null;
                    break;

                case FrameType.D:
                case FrameType.F:
                    F2.Ifd = null;
                    F2.Pfd = null;
                    break;
                }

                DFrames.Add(F2);
            }

            if (Frames.Count == Data.FrameCount)
            {
                Console.WriteLine($"  Loaded {Frames.Count} Frames");
            }
            else
            {
                Console.WriteLine($"  WARNING !!! - Loaded {Frames.Count} Frames but expected {Data.FrameCount} !!");
            }

            Frames = null; // GC
        }