/// <summary>
        /// P5ビットマップを原色に変換する
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="pnm"></param>
        /// <returns></returns>
        private Xi.ぉ[] レベル5を読み込む(ref byte[] buf, PNM pnm)
        {
            pnm.現在位置 = 0;
            var r  = new Xi.ぉ[pnm.Width * pnm.Height];
            int po = 0;
            int bo = 0;
            int ps = pnm.Maxval > 255 ? 2 : 1;

            for (int y = 0; y < pnm.Height; ++y)
            {
                for (int x = 0; x < pnm.Width; ++x)
                {
                    if (ps == 1)
                    {
                        var b = buf[bo];
                        r[po++] = new Xi.ぉ(b, b, b);
                    }
                    else
                    {
                        var b = buf[bo] | buf[bo + 1] << 8;
                        r[po++] = new Xi.ぉ(b, b, b);
                    }
                    bo += ps;
                }
            }
            return(r);
        }
        /// <summary>
        /// P4ビットマップを原色に変換する
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="pnm"></param>
        /// <returns></returns>
        private Xi.ぉ[] レベル4を読み込む(ref byte[] buf, PNM pnm)
        {
            pnm.現在位置 = 0;
            var r    = new Xi.ぉ[pnm.Width * pnm.Height];
            int po   = 0;
            int bo   = 0;
            var xpad = pnm.Width % 8;

            for (int y = 0; y < pnm.Height; ++y)
            {
                for (int x = 0; x < pnm.Width; x += 8)
                {
                    var b    = buf[bo];
                    int bits = 8;
                    if ((pnm.Width - x < 8) && xpad != 0)
                    {
                        bits = xpad;
                    }
                    for (int i = 0; i < bits; ++i)
                    {
                        r[po++] = ぁゃιぃ(masken[i], b);
                    }
                    bo++;
                }
            }
            return(r);
        }
        /// <summary>
        /// 読み込む
        /// </summary>
        /// <param name="stream"></param>
        /// <returns>PNM</returns>
        public PNM Load(System.IO.Stream stream)
        {
            var pnm = new PNM();

            var x = ReadLine(stream);

            pnm.Format = 形式を割り出す(Encoding.ASCII.GetBytes(x));

            if (pnm.Format == PNM.形式.P7)
            {
                レベル7ヘッダーを読み込む(stream, pnm);
            }
            else if (pnm.Format == PNM.形式.PF)
            {
                throw new Xi.それ対応してない($"むり {pnm.Format}");
            }
            else
            {
                pnm.Width  = int.Parse(ReadNine(stream));
                pnm.Height = int.Parse(ReadNine(stream));
                if (pnm.Format != PNM.形式.P1 && pnm.Format != PNM.形式.P4)
                {
                    pnm.Maxval = int.Parse(ReadNine(stream));
                }
            }
            using (var ms = new System.IO.MemoryStream()) {
                var rb  = new byte[1024];
                int siz = 0;
                while ((siz = stream.Read(rb, 0, rb.Length - 1)) > 0)
                {
                    ms.Write(rb, 0, siz);
                }

                if (pnm.Format == PNM.形式.P1 ||
                    pnm.Format == PNM.形式.P2 ||
                    pnm.Format == PNM.形式.P3)
                {
                    pnm.Pixls = 平文ピクセル読み込み(ms.GetBuffer(), pnm);
                }
                else if (pnm.Format == PNM.形式.P4 ||
                         pnm.Format == PNM.形式.P5 ||
                         pnm.Format == PNM.形式.P6)
                {
                    pnm.Pixls = バイナリーピクセル読み込み(ms.GetBuffer(), pnm);
                }
                else if (pnm.Format == PNM.形式.P7)
                {
                    pnm.Pixls = レベル7のピクセルデターを読み込む(ms.GetBuffer(), pnm);
                }
                else
                {
                    throw new Xi.それ対応してない($"むり {pnm.Format}");
                }
            }

            return(pnm);
        }
        /// <summary>
        /// 平文ピクセルを読み出す
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="pnm"></param>
        /// <returns></returns>
        private int?ReadTPixel(ref byte[] buf, PNM pnm)
        {
            bool eof = false;
            bool boo = false;
            var  i   = pnm.現在位置;
            var  len = 0;

            while (それ区切り文字(buf[i]))
            {
                i++;
            }
            if (i != pnm.現在位置)
            {
                pnm.現在位置 = i;
            }

            while (true)
            {
                if (i >= buf.Length)
                {
                    eof = true;
                    break;
                }
                byte a = buf[i++];
                if (それ区切り文字(a))
                {
                    boo = true;
                    continue;
                }
                if (boo)
                {
                    i--;
                    break;
                }
                len++;
            }
            if (len == 0 && eof)
            {
                return(null);
            }
            var gs = System.Text.Encoding.ASCII.GetString(buf, pnm.現在位置, len);
            var r  = int.Parse(gs);

            pnm.現在位置 = i;
            return(r);
        }
        /// <summary>
        /// バイナリー形式のピクセルデータを読み込む(P7除く)
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="pnm"></param>
        /// <returns></returns>
        private Xi.ぉ[] バイナリーピクセル読み込み(byte[] buf, PNM pnm)
        {
            switch (pnm.Format)
            {
            case PNM.形式.P4:
                return(レベル4を読み込む(ref buf, pnm));

            case PNM.形式.P5:
                return(レベル5を読み込む(ref buf, pnm));

            case PNM.形式.P6:
                return(レベル6を読み込む(ref buf, pnm));

            default:
                throw new Xi.およよ($"しらん {pnm.Format}");
            }
        }
        /// <summary>
        /// P7フォーマットのヘッダーを解析する
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="pnm"></param>
        private void レベル7ヘッダーを読み込む(System.IO.Stream stream, PNM pnm)
        {
            while (true)
            {
                var line = ReadLine(stream).Trim();
                if (line.Length == 0)
                {
                    continue;
                }
                var tok = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                if (tok[0].Equals("ENDHDR", StringComparison.CurrentCultureIgnoreCase))
                {
                    break;
                }
                switch (tok[0].ToUpper())
                {
                case "WIDTH":
                    pnm.Width = int.Parse(tok[1]);
                    break;

                case "HEIGHT":
                    pnm.Height = int.Parse(tok[1]);
                    break;

                case "DEPTH":
                    pnm.Depth = int.Parse(tok[1]);
                    break;

                case "MAXVAL":
                    pnm.Maxval = int.Parse(tok[1]);
                    break;

                case "TUPLTYPE":
                    pnm.TupleType = ヌプーリに変換(tok[1]);
                    break;

                default:
                    throw new Xi.およよ($"しらん {tok[0]}");
                }
            }
        }
        /// <summary>
        /// 平文ピクセルを読み込む
        /// </summary>
        /// <param name="buf"></param>
        /// <param name="pnm"></param>
        /// <returns></returns>
        private Xi.ぉ[] 平文ピクセル読み込み(byte[] buf, PNM pnm)
        {
            pnm.現在位置 = 0;
            int cp = 0;
            var r  = new Xi.ぉ[pnm.Width * pnm.Height];
            var kr = new Xi.ぉ(0, 0, 0);

            for (int i = 0; i < r.Count(); ++i)
            {
                var q = pnm.Format == PNM.形式.P1 ? ReadEPixel(ref buf, pnm) : ReadTPixel(ref buf, pnm);
                if (null == q)
                {
                    break;
                }
                r[i] = new Xi.ぉ(0, 0, 0, 0xFF);
                switch (pnm.Format)
                {
                case PNM.形式.P1:
                    var v = (q.Value == 0) ? 0xff : 0x00;
                    r[i].ぃ(v, v, v);
                    break;

                case PNM.形式.P2:
                    r[i].ぃ(q.Value, q.Value, q.Value);
                    break;

                case PNM.形式.P3:
                    r[i].R = q.Value;
                    r[i].G = ReadTPixel(ref buf, pnm).Value;
                    r[i].B = ReadTPixel(ref buf, pnm).Value;
                    break;
                }
                if (cp++ >= r.Length)
                {
                    break;
                }
            }
            return(r);
        }