//ライセンス情報はAgeOnフォルダのLISENCEフォルダを参照してください
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace nispi
{
    class ImageUtil
    {
        public ImageUtil()
        {
        }

        public static Bitmap DeepCopy(Bitmap sourceBitmap)
        {
            Bitmap desBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);
            BitmapData sourceBmpd, newBmpd;

            byte[] desPixels;
            long pixelsize;
            //DeepCopy
            sourceBmpd = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            newBmpd = desBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
                ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            pixelsize = sourceBmpd.Width * sourceBmpd.Height * 4;
            desPixels = new byte[pixelsize];
            Marshal.Copy(sourceBmpd.Scan0, desPixels, 0, desPixels.Length);
            Marshal.Copy(desPixels, 0, newBmpd.Scan0, desPixels.Length);
            sourceBitmap.UnlockBits(sourceBmpd);
            desBitmap.UnlockBits(newBmpd);

            return desBitmap;
        }

        //塗りつぶした地図とポイントを描いた地図を合成する
        //ポイント描画画像の値＝１は黒ではな。それを合成によって黒に変換する
        public static Bitmap SynthesisImage(Bitmap fillImage, Bitmap pointImage)
        {
            //ピクセル単位の配列を準備
            int w = fillImage.Width;
            int h = fillImage.Height;

            Bitmap newBmp = new Bitmap(w, h);
            BitmapData fillBmpd, pointBmpd, newBmpd;

            byte[] fillPixels;
            byte[] pointPixels;
            long pixelsize;

            //表の図。描画を行う//準備
            fillBmpd = fillImage.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);
            pointBmpd = pointImage.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);
            newBmpd = newBmp.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);
            //準備２
            pixelsize = w * h * 4;
            fillPixels = new byte[pixelsize];
            Marshal.Copy(fillBmpd.Scan0, fillPixels, 0, fillPixels.Length);
            pointPixels = new byte[pixelsize];
            Marshal.Copy(pointBmpd.Scan0, pointPixels, 0, pointPixels.Length);

            for (int count = 0; count < pixelsize; count += 4)
            {
                if ((pointPixels[count] != 0) && (pointPixels[count] != 1))
                {
                    fillPixels[count] = pointPixels[count];
                    fillPixels[count + 1] = pointPixels[count + 1];
                    fillPixels[count + 2] = pointPixels[count + 2];
                    //透過値はスルー                    
                    //fillPixels[count] = pointPixels[count];
                }
                else if (pointPixels[count] == 1)
                {
                    fillPixels[count] = 0;
                    fillPixels[count + 1] = 0;
                    fillPixels[count + 2] = 0;
                    //透過値はスルー                    
                    //fillPixels[count] = pointPixels[count];
                }
            }

            //新規データにコピー
            Marshal.Copy(fillPixels, 0, newBmpd.Scan0, fillPixels.Length);

            //メモリ解放
            fillImage.UnlockBits(fillBmpd);
            pointImage.UnlockBits(pointBmpd);
            newBmp.UnlockBits(newBmpd);

            return newBmp;
        }

        //塗りつぶした地図とポイントを描いた地図を合成する
        //ポイント描画画像の値＝１は黒ではなし。それを合成によって黒に変換する
        public static Bitmap SynthesisImageUnsafe(Bitmap fillImage, Bitmap pointImage)
        {
            //ピクセル単位の配列を準備
            int w = fillImage.Width;
            int h = fillImage.Height;

            Bitmap newBmp = (Bitmap)fillImage.Clone();

            BitmapData fillBmpd, pointBmpd, newBmpd;

            long pixelsize = w * h * 4;

            //表の図。描画を行う//準備
            fillBmpd = fillImage.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);
            pointBmpd = pointImage.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);
            newBmpd = newBmp.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);

            unsafe
            {

                byte* fillPixelsPtr = (byte*)fillBmpd.Scan0.ToPointer();
                byte* pointPixelsPtr = (byte*)pointBmpd.Scan0.ToPointer();
                byte* newPixelsPtr = (byte*)newBmpd.Scan0.ToPointer();

                for (int count = 0; count < pixelsize; count += 4)
                {
                    if ((pointPixelsPtr[count + 0] != 0) && (pointPixelsPtr[count + 0] != 1))
                    {
                        newPixelsPtr[count + 0] = pointPixelsPtr[count + 0];
                        newPixelsPtr[count + 1] = pointPixelsPtr[count + 1];
                        newPixelsPtr[count + 2] = pointPixelsPtr[count + 2];
                        //透過値はスルー                    
                        //fillPixels[count] = pointPixels[count];
                    }
                    else if (pointPixelsPtr[count + 0] == 1)
                    {
                        newPixelsPtr[count + 0] = 0;
                        newPixelsPtr[count + 1] = 0;
                        newPixelsPtr[count + 2] = 0;
                        //透過値はスルー                    
                        //fillPixels[count] = pointPixels[count];
                    }
                    else
                    {
                        newPixelsPtr[count + 0] = fillPixelsPtr[count + 0];
                        newPixelsPtr[count + 1] = fillPixelsPtr[count + 1];
                        newPixelsPtr[count + 2] = fillPixelsPtr[count + 2];
                    }
                }
            }
                /*int count = 0;
                while (count < pixelsize)
                {
                    if ((*pointPixelsPtr != 0) && (*pointPixelsPtr != 1))
                    {
                        *newPixelsPtr = *pointPixelsPtr;
                        *(newPixelsPtr+1) = *(pointPixelsPtr+1);
                        *(newPixelsPtr+2) = *(pointPixelsPtr+2);
                        //透過値はスルー                    
                        //fillPixels[count] = pointPixels[count];
                    }
                    else if (*pointPixelsPtr == 1)
                    {
                        *newPixelsPtr = 0;
                        *(newPixelsPtr+1) = 0;
                        *(newPixelsPtr+2) = 0;
                        //透過値はスルー                    
                        //fillPixels[count] = pointPixels[count];
                    }
                    else
                    {
                        *newPixelsPtr = *fillPixelsPtr;
                        *(newPixelsPtr + 1) = *(fillPixelsPtr + 1);
                        *(newPixelsPtr + 2) = *(fillPixelsPtr + 2);
                    }
                    fillPixelsPtr += 4;
                    pointPixelsPtr += 4;
                    newPixelsPtr += 4;
                    count += 4;
                }*/
                //新規データにコピー
                //Marshal.Copy(fillPixels, 0, newBmpd.Scan0, fillPixels.Length);

            //メモリ解放
            newBmp.UnlockBits(newBmpd);
            fillImage.UnlockBits(fillBmpd);
            pointImage.UnlockBits(pointBmpd);


            return newBmp;
        }
    }
}