MemBitmap GetTransformedBitmapNoInterpolation()
        {
            var destCB = new MemBitmap(_destBounds.Width, _destBounds.Height);

#if DEBUG
            destCB._dbugNote = "GetTransformedBitmapNoInterpolation()";
#endif
            var    destWriter = new MyBitmapBlender(destCB);
            PointF ptInPlane  = new PointF();

            int    x1, y1;
            double dab, dbc, dcd, dda;

            int    rectWidth  = _destBounds.Width;
            int    rectHeight = _destBounds.Height;
            Vector ab_vec     = _AB;
            Vector bc_vec     = _BC;
            Vector cd_vec     = _CD;
            Vector da_vec     = _DA;
            int    rectLeft   = _destBounds.Left;
            int    rectTop    = _destBounds.Top;



            unsafe
            {
                using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr))
                {
                    BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height);

                    for (int y = 0; y < rectHeight; ++y)
                    {
                        for (int x = 0; x < rectWidth; ++x)
                        {
                            PointF srcPt = new PointF(x, y);
                            srcPt.Offset(rectLeft, rectTop);
                            if (!IsOnPlaneABCD(srcPt))
                            {
                                continue;
                            }
                            x1 = (int)ptInPlane.X;
                            y1 = (int)ptInPlane.Y;

                            reader.SetStartPixel(x1, y1);
                            destWriter.SetPixel(x, y, reader.Read1());
                            //-------------------------------------
                            dab         = Math.Abs((MyVectorHelper.NewFromTwoPoints(_p0, srcPt)).CrossProduct(ab_vec));
                            dbc         = Math.Abs((MyVectorHelper.NewFromTwoPoints(_p1, srcPt)).CrossProduct(bc_vec));
                            dcd         = Math.Abs((MyVectorHelper.NewFromTwoPoints(_p2, srcPt)).CrossProduct(cd_vec));
                            dda         = Math.Abs((MyVectorHelper.NewFromTwoPoints(_p3, srcPt)).CrossProduct(da_vec));
                            ptInPlane.X = (float)(_srcW * (dda / (dda + dbc)));
                            ptInPlane.Y = (float)(_srcH * (dab / (dab + dcd)));
                        }
                    }
                    return(destCB);
                }
            }
        }
        //ActualBitmap GetTransformedBilinearInterpolation()
        //{
        //    //4 points sampling
        //    //weight between four point
        //    ActualBitmap destCB = new ActualBitmap(rect.Width, rect.Height);
        //    MyBitmapBlender destWriter = new MyBitmapBlender(destCB);
        //    PointF ptInPlane = new PointF();
        //    int x1, x2, y1, y2;
        //    double dab, dbc, dcd, dda;
        //    float dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2;
        //    int rectWidth = rect.Width;
        //    int rectHeight = rect.Height;
        //    Vector ab_vec = this.AB;
        //    Vector bc_vec = this.BC;
        //    Vector cd_vec = this.CD;
        //    Vector da_vec = this.DA;
        //    int rectLeft = this.rect.Left;
        //    int rectTop = this.rect.Top;



        //    for (int y = 0; y < rectHeight; ++y)
        //    {
        //        for (int x = 0; x < rectWidth; ++x)
        //        {
        //            PointF srcPt = new PointF(x, y);
        //            srcPt.Offset(rectLeft, rectTop);
        //            if (!IsOnPlaneABCD(srcPt))
        //            {
        //                continue;
        //            }
        //            //-------------------------------------
        //            dab = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p0, srcPt).CrossProduct(ab_vec));
        //            dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p1, srcPt).CrossProduct(bc_vec));
        //            dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p2, srcPt).CrossProduct(cd_vec));
        //            dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p3, srcPt).CrossProduct(da_vec));

        //            ptInPlane.X = (float)(srcW * (dda / (dda + dbc)));
        //            ptInPlane.Y = (float)(srcH * (dab / (dab + dcd)));
        //            x1 = (int)ptInPlane.X;
        //            y1 = (int)ptInPlane.Y;

        //            if (x1 >= 0 && x1 < srcW && y1 >= 0 && y1 < srcH)
        //            {
        //                //bilinear interpolation ***
        //                x2 = (x1 == srcW - 1) ? x1 : x1 + 1;
        //                y2 = (y1 == srcH - 1) ? y1 : y1 + 1;
        //                dx1 = ptInPlane.X - x1;
        //                if (dx1 < 0) dx1 = 0;
        //                dx1 = 1f - dx1;
        //                dx2 = 1f - dx1;
        //                dy1 = ptInPlane.Y - y1;
        //                if (dy1 < 0) dy1 = 0;
        //                dy1 = 1f - dy1;
        //                dy2 = 1f - dy1;
        //                dx1y1 = dx1 * dy1;
        //                dx1y2 = dx1 * dy2;
        //                dx2y1 = dx2 * dy1;
        //                dx2y2 = dx2 * dy2;
        //                //use 4 points


        //                Drawing.Color x1y1Color = srcCB.GetPixel(x1, y1);
        //                Drawing.Color x2y1Color = srcCB.GetPixel(x2, y1);
        //                Drawing.Color x1y2Color = srcCB.GetPixel(x1, y2);
        //                Drawing.Color x2y2Color = srcCB.GetPixel(x2, y2);
        //                float a = (x1y1Color.alpha * dx1y1) + (x2y1Color.alpha * dx2y1) + (x1y2Color.alpha * dx1y2) + (x2y2Color.alpha * dx2y2);
        //                float b = (x1y1Color.blue * dx1y1) + (x2y1Color.blue * dx2y1) + (x1y2Color.blue * dx1y2) + (x2y2Color.blue * dx2y2);
        //                float g = (x1y1Color.green * dx1y1) + (x2y1Color.green * dx2y1) + (x1y2Color.green * dx1y2) + (x2y2Color.green * dx2y2);
        //                float r = (x1y1Color.red * dx1y1) + (x2y1Color.red * dx2y1) + (x1y2Color.red * dx1y2) + (x2y2Color.red * dx2y2);
        //                destWriter.SetPixel(x, y, new Drawing.Color((byte)a, (byte)b, (byte)g, (byte)r));
        //            }
        //        }
        //    }
        //    return destCB;
        //}
        unsafe MemBitmap GetTransformedBicubicInterpolation()
        {
            //4 points sampling
            //weight between four point
            PointF ptInPlane = new PointF();
            int    x1, x2, y1, y2;
            double dab, dbc, dcd, dda;
            //float dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2;
            int    destRectWidth  = _destBounds.Width;
            int    dectRectHeight = _destBounds.Height;
            Vector ab_vec         = _AB;
            Vector bc_vec         = _BC;
            Vector cd_vec         = _CD;
            Vector da_vec         = _DA;

            using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr))
            {
                BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height);

                MemBitmap destCB = new MemBitmap(_destBounds.Width, _destBounds.Height);
#if DEBUG
                destCB._dbugNote = "GetTransformedBicubicInterpolation()";
#endif
                MyBitmapBlender destWriter = new MyBitmapBlender(destCB);
                int             rectLeft   = _destBounds.Left;
                int             rectTop    = _destBounds.Top;

                //***
                PixelFarm.Drawing.Color[] colors = new PixelFarm.Drawing.Color[16];

                int srcW_lim = _srcW - 2;
                int srcH_lim = _srcH - 2;

                for (int y = 0; y < dectRectHeight; ++y)
                {
                    for (int x = 0; x < destRectWidth; ++x)
                    {
                        PointF srcPt = new PointF(x, y);
                        srcPt.Offset(rectLeft, 0);
                        if (!IsOnPlaneABCD(srcPt))
                        {
                            continue;
                        }
                        //-------------------------------------
                        dab         = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p0, srcPt).CrossProduct(ab_vec));
                        dbc         = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p1, srcPt).CrossProduct(bc_vec));
                        dcd         = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p2, srcPt).CrossProduct(cd_vec));
                        dda         = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p3, srcPt).CrossProduct(da_vec));
                        ptInPlane.X = (float)(_srcW * (dda / (dda + dbc)));
                        ptInPlane.Y = (float)(_srcH * (dab / (dab + dcd)));
                        x1          = (int)ptInPlane.X;
                        y1          = (int)ptInPlane.Y;
                        if (x1 >= 2 && x1 < srcW_lim &&
                            y1 >= 2 && y1 < srcH_lim)
                        {
                            reader.SetStartPixel(x1, y1);
                            //reader.Read16(pixelBuffer);
                            //do interpolate
                            //find src pixel and approximate
                            destWriter.SetPixel(x, y,

                                                GetApproximateColor_Bicubic(reader,
                                                                            colors,
                                                                            ptInPlane.X,
                                                                            ptInPlane.Y)); //TODO:review here blue switch to red channel
                        }
                    }
                    //newline
                    // startLine += stride2;
                    //targetPixelIndex = startLine;
                }


                //------------------------
                //System.Runtime.InteropServices.Marshal.Copy(
                //outputBuffer, 0,
                //bmpdata2.Scan0, outputBuffer.Length);
                //outputbmp.UnlockBits(bmpdata2);
                ////outputbmp.Save("n_lion_bicubic.png");
                //return outputbmp;
                return(destCB);
            }
        }
        unsafe MemBitmap GetTransformedBilinearInterpolation()
        {
            //4 points sampling
            //weight between four point
            MemBitmap destCB = new MemBitmap(_destBounds.Width, _destBounds.Height);

#if DEBUG
            destCB._dbugNote = "GetTransformedBilinearInterpolation()";
#endif
            MyBitmapBlender destWriter = new MyBitmapBlender(destCB);
            PointF          ptInPlane = new PointF();
            int             x1, x2, y1, y2;
            double          dab, dbc, dcd, dda;
            float           dx1, dx2, dy1, dy2, dx1y1, dx1y2, dx2y1, dx2y2;
            int             rectWidth  = _destBounds.Width;
            int             rectHeight = _destBounds.Height;
            Vector          ab_vec     = _AB;
            Vector          bc_vec     = _BC;
            Vector          cd_vec     = _CD;
            Vector          da_vec     = _DA;
            int             rectLeft   = _destBounds.Left;
            int             rectTop    = _destBounds.Top;

            int srcW_lim = _srcW - 1;
            int srcH_lim = _srcH - 1;

            using (TempMemPtr.FromBmp(_srcBmp, out int *bufferPtr))
            {
                BufferReader4 reader = new BufferReader4(bufferPtr, _srcBmp.Width, _srcBmp.Height);
                for (int y = 0; y < rectHeight; ++y)
                {
                    for (int x = 0; x < rectWidth; ++x)
                    {
                        PointF srcPt = new PointF(x, y);
                        srcPt.Offset(rectLeft, rectTop);
                        if (!IsOnPlaneABCD(srcPt))
                        {
                            continue;
                        }
                        //-------------------------------------
                        dab = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p0, srcPt).CrossProduct(ab_vec));
                        dbc = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p1, srcPt).CrossProduct(bc_vec));
                        dcd = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p2, srcPt).CrossProduct(cd_vec));
                        dda = Math.Abs(MyVectorHelper.NewFromTwoPoints(_p3, srcPt).CrossProduct(da_vec));

                        ptInPlane.X = (float)(_srcW * (dda / (dda + dbc)));
                        ptInPlane.Y = (float)(_srcH * (dab / (dab + dcd)));
                        x1          = (int)ptInPlane.X;
                        y1          = (int)ptInPlane.Y;

                        if (x1 >= 0 && x1 < srcW_lim &&
                            y1 >= 0 && y1 < srcH_lim)
                        {
                            //x2 = (x1 == srcW - 1) ? x1 : x1 + 1;
                            //y2 = (y1 == srcH - 1) ? y1 : y1 + 1;

                            x2 = x1 + 1;
                            y2 = y1 + 1;

                            dx1 = ptInPlane.X - x1;
                            if (dx1 < 0)
                            {
                                dx1 = 0;
                            }
                            dx1 = 1f - dx1;
                            dx2 = 1f - dx1;
                            //
                            //
                            dy1 = ptInPlane.Y - y1;
                            if (dy1 < 0)
                            {
                                dy1 = 0;
                            }
                            dy1 = 1f - dy1;
                            dy2 = 1f - dy1;
                            //
                            //
                            dx1y1 = dx1 * dy1;
                            dx1y2 = dx1 * dy2;
                            dx2y1 = dx2 * dy1;
                            dx2y2 = dx2 * dy2;
                            //use 4 points

                            reader.SetStartPixel(x1, y1);


                            Drawing.Color x1y1Color;
                            Drawing.Color x2y1Color;
                            Drawing.Color x1y2Color;
                            Drawing.Color x2y2Color;

                            reader.Read4(out x1y1Color, out x2y1Color, out x1y2Color, out x2y2Color);

                            //Drawing.Color x1y1Color = srcCB.GetPixel(x1, y1);
                            //Drawing.Color x2y1Color = srcCB.GetPixel(x2, y1);
                            //Drawing.Color x1y2Color = srcCB.GetPixel(x1, y2);
                            //Drawing.Color x2y2Color = srcCB.GetPixel(x2, y2);
                            float a = (x1y1Color.A * dx1y1) + (x2y1Color.A * dx2y1) + (x1y2Color.A * dx1y2) + (x2y2Color.A * dx2y2);
                            float b = (x1y1Color.B * dx1y1) + (x2y1Color.B * dx2y1) + (x1y2Color.B * dx1y2) + (x2y2Color.B * dx2y2);
                            float g = (x1y1Color.G * dx1y1) + (x2y1Color.G * dx2y1) + (x1y2Color.G * dx1y2) + (x2y2Color.G * dx2y2);
                            float r = (x1y1Color.R * dx1y1) + (x2y1Color.R * dx2y1) + (x1y2Color.R * dx1y2) + (x2y2Color.R * dx2y2);
                            destWriter.SetPixel(x, y, new Drawing.Color((byte)a, (byte)r, (byte)g, (byte)b));
                        }
                    }
                }
                return(destCB);
            }
        }