public static String[] Convert(Bitmap bmp, ConfigManager cm, CharManager charm)
        {
            char[,] table     = GetTable(bmp);         //画像取得
            char[,] toneTable = GetToneTable(bmp, cm); //トーン

            int h = charm[0].Height;
            int w = table.GetLength(0);

            List <char[, ]> lstSplitTable     = new List <char[, ]>();
            List <char[, ]> lstSplitToneTable = new List <char[, ]>();

            for (int top = 0; top < table.GetLength(1); top += h)
            {
                lstSplitTable.Add(TrimTable(table, top, 0, h, w, 0));

                if (cm.Tone && cm.ToneText.Length > 0)
                {
                    lstSplitToneTable.Add(TrimTable(toneTable, top, 0, h, w, 0));
                }
                else
                {
                    lstSplitToneTable.Add(new char[0, 0]);
                }
            }

            char[][,] splitTable = lstSplitTable.ToArray();

            StringBuilder sbAA     = new StringBuilder();
            StringBuilder sbAAType = new StringBuilder();

            int prog = 0;

            int multi = 1;

            if (cm.IsMulti)
            {
                AsciiArtConverter08.Win32.Win32Api.SYSTEM_INFO sysInfo = new AsciiArtConverter08.Win32.Win32Api.SYSTEM_INFO();
                AsciiArtConverter08.Win32.Win32Api.GetSystemInfo(ref sysInfo);

                multi = (int)sysInfo.dwNumberOfProcessors;
            }

            for (int i = 0; i < splitTable.Length; i += multi)
            {
                if (i + multi >= splitTable.Length)
                {
                    multi = splitTable.Length - i;
                }

                AAConvThread[] at = new AAConvThread[multi];
                Thread[]       t  = new Thread[multi];

                for (int j = 0; j < at.Length; j++)
                {
                    at[j] = new AAConvThread(cm, charm, splitTable[i + j], lstSplitToneTable[i + j]);
                    t[j]  = new Thread(at[j].DoThread);
                    t[j].Start();
                }

                while (true)
                {
                    Application.DoEvents();
                    Thread.Sleep(100);

                    for (int j = 0; j < at.Length; j++)
                    {
                        if (at[j].AA == "")
                        {
                            goto LOOP;
                        }
                    }

                    break;

LOOP:

                    ;
                }

                prog += at.Length;


                for (int j = 0; j < at.Length; j++)
                {
                    sbAA.Append(at[j].AA + "\r\n");
                    sbAAType.Append(at[j].AA_Type + "\r\n");
                }
            }

            //Debug.WriteLine(sb.ToString());

            return(new string[] { sbAA.ToString(), sbAAType.ToString() });
        }
        public unsafe static IntPtr getAA(int *buf, int bufW, int bufH, IntPtr cmsPtr /*, IntPtr res*/) //JNAのPointerはint[]では受け取れない.オブジェクト的なやつだからね
        {                                                                                               //AA変換結果であるresだけはjavaが利用し終わるまでGCしてはならない
            //String test = "auioe";
                                                                                                        ///if (true) return Marshal.StringToCoTaskMemUni(test);
            ConfigManagerStruct cms = *(ConfigManagerStruct *)(cmsPtr.ToPointer());

            ConfigManager cm    = new ConfigManager(cms);
            CharManager   charm = new CharManager(cm);  //ここまでok



            Bitmap bmp;

            unsafe
            {
                bmp = new Bitmap(bufW, bufH, bufW * 4, PixelFormat.Format32bppArgb, new IntPtr(buf)); //buf
            }

            bmp               = (Bitmap)ConvertLine(bmp, cm);
            char[,] table     = GetTable(bmp);         //画像取得
            char[,] toneTable = GetToneTable(bmp, cm); //トーン

            int h = charm[0].Height;
            int w = table.GetLength(0);

            List <char[, ]> lstSplitTable     = new List <char[, ]>();
            List <char[, ]> lstSplitToneTable = new List <char[, ]>();

            for (int top = 0; top < table.GetLength(1); top += h)
            {
                lstSplitTable.Add(TrimTable(table, top, 0, h, w, 0));

                if (cm.Tone && cm.ToneText.Length > 0)
                {
                    lstSplitToneTable.Add(TrimTable(toneTable, top, 0, h, w, 0));
                }
                else
                {
                    lstSplitToneTable.Add(new char[0, 0]);
                }
            }

            char[][,] splitTable = lstSplitTable.ToArray();

            StringBuilder sbAA     = new StringBuilder();
            StringBuilder sbAAType = new StringBuilder();

            int prog = 0;

            int multi = 1;

            if (cm.IsMulti)
            {
                AsciiArtConverter08.Win32.Win32Api.SYSTEM_INFO sysInfo = new AsciiArtConverter08.Win32.Win32Api.SYSTEM_INFO();
                AsciiArtConverter08.Win32.Win32Api.GetSystemInfo(ref sysInfo);

                multi = (int)sysInfo.dwNumberOfProcessors;
            }

            for (int i = 0; i < splitTable.Length; i += multi)
            {
                if (i + multi >= splitTable.Length)
                {
                    multi = splitTable.Length - i;
                }
                AAConvThread[] at = new AAConvThread[multi];

                for (int j = 0; j < at.Length; j++)
                {
                    at[j] = new AAConvThread(cm, charm, splitTable[i + j], lstSplitToneTable[i + j]);
                    at[j].DoThread();
                }
                while (true)
                {
                    Application.DoEvents();
                    Thread.Sleep(100);

                    for (int j = 0; j < at.Length; j++)
                    {
                        if (at[j].AA == "")
                        {
                            goto LOOP;
                        }
                    }

                    break;

LOOP:

                    ;
                }
                prog += at.Length;

                for (int j = 0; j < at.Length; j++)
                {
                    sbAA.Append(at[j].AA + "\r\n");
                    sbAAType.Append(at[j].AA_Type + "\r\n");
                }
            }
            //char[] aa = sbAA.ToString().ToCharArray();//copy?
            //IntPtr aaPtr = Marshal.AllocCoTaskMem(aa.Length * sizeof(char));    //TODO AllocHGlobalとの違い
            //Marshal.Copy(aa, 0, aaPtr, aa.Length);  //copy
            //GC.KeepAlive(aaPtr);
            //Console.WriteLine("4");
            return(Marshal.StringToCoTaskMemUni(sbAA.ToString())); //aaPtr;
        }