private static PixImage CreateFromFiBitMap(FIBITMAP dib)
        {
            var sx    = (int)FreeImage.GetWidth(dib);
            var sy    = (int)FreeImage.GetHeight(dib);
            var delta = (int)FreeImage.GetPitch(dib);
            var ftype = FreeImage.GetImageType(dib);
            var bpp   = FreeImage.GetBPP(dib);

            var bits = FreeImage.GetBits(dib) + sy * delta;

            switch (ftype)
            {
            case FREE_IMAGE_TYPE.FIT_BITMAP:
                switch (bpp)
                {
                case 1:
                {
                    var palette = FreeImage.GetPaletteEx(dib);
                    var pi      = new PixImage <byte>(Col.Format.BW, sx, sy, 1);
                    var data    = pi.Volume.Data;
                    int i       = 0;
                    if (palette != null &&
                        palette[0].rgbRed + palette[0].rgbGreen + palette[0].rgbBlue >= 384)
                    {
                        for (var y = 0; y < sy; y++)
                        {
                            bits = bits - delta;
                            byte bit = 0x80; int bi = 0;
                            unsafe
                            {
                                byte *pixel = (byte *)bits;
                                for (var x = 0; x < sx; x++)
                                {
                                    data[i++] = ((pixel[bi] & bit) == 0) ? (byte)255 : (byte)0;
                                    bit     >>= 1; if (bit == 0)
                                    {
                                        bit = 0x80; bi++;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        for (var y = 0; y < sy; y++)
                        {
                            bits = bits - delta;
                            byte bit = 0x80; int bi = 0;
                            unsafe
                            {
                                byte *pixel = (byte *)bits;
                                for (var x = 0; x < sx; x++)
                                {
                                    data[i++] = ((pixel[bi] & bit) != 0) ? (byte)255 : (byte)0;
                                    bit     >>= 1; if (bit == 0)
                                    {
                                        bit = 0x80; bi++;
                                    }
                                }
                            }
                        }
                    }
                    return(pi);
                }

                case 8:
                {
                    var  pi   = new PixImage <byte>(sx, sy, 1);
                    var  data = pi.Volume.Data;
                    long i    = 0;
                    for (var y = 0; y < sy; y++)
                    {
                        bits = bits - delta;
                        unsafe
                        {
                            Byte *pixel = (Byte *)bits;
                            for (var x = 0; x < sx; x++)
                            {
                                data[i++] = pixel[x];
                            }
                        }
                    }
                    return(pi);
                }

                case 24:
                {
                    var  pi   = new PixImage <byte>(sx, sy, 3);
                    var  data = pi.Volume.Data;
                    long i    = 0;
                    for (var y = 0; y < sy; y++)
                    {
                        bits = bits - delta;
                        unsafe
                        {
                            Byte *pixel = (Byte *)bits;
                            for (var x = 0; x < sx; x++)
                            {
                                data[i++] = pixel[FreeImage.FI_RGBA_BLUE];
                                data[i++] = pixel[FreeImage.FI_RGBA_GREEN];
                                data[i++] = pixel[FreeImage.FI_RGBA_RED];
                                pixel    += 3;
                            }
                        }
                    }
                    return(pi);
                }

                case 32:
                {
                    var  pi   = new PixImage <byte>(sx, sy, 4);
                    var  data = pi.Volume.Data;
                    long i    = 0;
                    for (var y = 0; y < sy; y++)
                    {
                        bits = bits - delta;
                        unsafe
                        {
                            Byte *pixel = (Byte *)bits;
                            for (var x = 0; x < sx; x++)
                            {
                                data[i++] = pixel[FreeImage.FI_RGBA_BLUE];
                                data[i++] = pixel[FreeImage.FI_RGBA_GREEN];
                                data[i++] = pixel[FreeImage.FI_RGBA_RED];
                                data[i++] = pixel[FreeImage.FI_RGBA_ALPHA];
                                pixel    += 4;
                            }
                        }
                    }
                    return(pi);
                }
                }
                break;

            case FREE_IMAGE_TYPE.FIT_UINT16:
            {
                var  pi   = new PixImage <ushort>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        ushort *pixel = (ushort *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_INT16:
            {
                var  pi   = new PixImage <short>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        short *pixel = (short *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_UINT32:
            {
                var  pi   = new PixImage <uint>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        uint *pixel = (uint *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_INT32:
            {
                var  pi   = new PixImage <int>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        int *pixel = (int *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_FLOAT:
            {
                var  pi   = new PixImage <float>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        float *pixel = (float *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_DOUBLE:
            {
                var  pi   = new PixImage <double>(sx, sy, 1);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        double *pixel = (double *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x];
                        }
                    }
                }
            }
            break;

            case FREE_IMAGE_TYPE.FIT_COMPLEX:
            {
                var  pi   = new PixImage <double>(sx, sy, 2);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FICOMPLEX *pixel = (FICOMPLEX *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x].real;
                            data[i++] = pixel[x].imag;
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_RGB16:
            {
                var  pi   = new PixImage <ushort>(sx, sy, 3);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGB16 *pixel = (FIRGB16 *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x].red;
                            data[i++] = pixel[x].green;
                            data[i++] = pixel[x].blue;
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_RGBF:
            {
                var  pi   = new PixImage <float>(sx, sy, 3);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBF *pixel = (FIRGBF *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x].red;
                            data[i++] = pixel[x].green;
                            data[i++] = pixel[x].blue;
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_RGBA16:
            {
                var  pi   = new PixImage <ushort>(sx, sy, 4);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBA16 *pixel = (FIRGBA16 *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x].red;
                            data[i++] = pixel[x].green;
                            data[i++] = pixel[x].blue;
                            data[i++] = pixel[x].alpha;
                        }
                    }
                }
                return(pi);
            }

            case FREE_IMAGE_TYPE.FIT_RGBAF:
            {
                var  pi   = new PixImage <float>(sx, sy, 4);
                var  data = pi.Volume.Data;
                long i    = 0;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBAF *pixel = (FIRGBAF *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            data[i++] = pixel[x].red;
                            data[i++] = pixel[x].green;
                            data[i++] = pixel[x].blue;
                            data[i++] = pixel[x].alpha;
                        }
                    }
                }
                return(pi);
            }
            }
            return(null);
        }
        private static FIBITMAP NewFiBitMap(PixImage <ushort> pi)
        {
            FreeImageCheck(pi.Volume.Info);
            var  sx   = pi.Size.X;
            var  sy   = pi.Size.Y;
            var  data = pi.Volume.Data;
            long i    = pi.Volume.FirstIndex;
            long j    = pi.Volume.JY;

            switch (pi.ChannelCount)
            {
            case 1:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_UINT16, sx, sy, 16);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        ushort *pixel = (ushort *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x] = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            case 3:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGB16, sx, sy, 48);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGB16 *pixel = (FIRGB16 *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x].red   = data[i++];
                            pixel[x].green = data[i++];
                            pixel[x].blue  = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            case 4:
            {
                var dib   = FreeImage.AllocateT(FREE_IMAGE_TYPE.FIT_RGBA16, sx, sy, 64);
                var delta = (int)FreeImage.GetPitch(dib);
                var bits  = FreeImage.GetBits(dib) + sy * delta;
                for (var y = 0; y < sy; y++)
                {
                    bits = bits - delta;
                    unsafe
                    {
                        FIRGBA16 *pixel = (FIRGBA16 *)bits;
                        for (var x = 0; x < sx; x++)
                        {
                            pixel[x].red   = data[i++];
                            pixel[x].green = data[i++];
                            pixel[x].blue  = data[i++];
                            pixel[x].alpha = data[i++];
                        }
                    }
                    i += j;
                }
                return(dib);
            }

            default:
                break;
            }
            throw new ArgumentException("cannot save PixImage");
        }