public static unsafe void ToStream(Bitmap bmp, FileStream stream)
        {
            int w = bmp.Width, h = bmp.Height;

            TGAHeader header = new TGAHeader();
            TGAFooter footer = new TGAFooter(0, 0);

            PaletteEncoder pEnc = null;
            ColorParser    cEnc = null;
            ColorPalette   pal  = null;

            header.imageSpecification.width  = (ushort)w;
            header.imageSpecification.height = (ushort)h;
            header.imageType = TGAImageType.UncompressedTrueColor;
            switch (bmp.PixelFormat)
            {
            case PixelFormat.Format4bppIndexed:
            case PixelFormat.Format8bppIndexed:
            {
                pal = bmp.Palette;

                header.colorMapType = 1;
                header.imageType    = TGAImageType.UncompressedColorMapped;
                header.colorMapSpecification.length    = (ushort)pal.Entries.Length;
                header.colorMapSpecification.entrySize = 24;
                header.imageSpecification.pixelDepth   = 8;

                pEnc = (ref VoidPtr ptr, Color c) => { *(RGBPixel *)ptr = (RGBPixel)c; ptr += 3; };

                if (bmp.PixelFormat == PixelFormat.Format4bppIndexed)
                {
                    cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                    { ((byte *)dPtr)[dIndex] = ((sIndex & 1) == 0) ? (byte)(((byte *)sPtr)[sIndex >> 1] >> 4) : (byte)(((byte *)sPtr)[sIndex >> 1] & 0xF); }
                }
                ;
                else
                {
                    cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                    { ((byte *)dPtr)[dIndex] = ((byte *)sPtr)[sIndex]; }
                };

                break;
            }

            case PixelFormat.Format32bppRgb:
            case PixelFormat.Format32bppArgb:
            {
                header.imageSpecification.pixelDepth = 32;
                header.imageSpecification.AlphaBits  = (bmp.PixelFormat == PixelFormat.Format32bppArgb) ? (byte)8 : (byte)0;

                cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                { ((ARGBPixel *)dPtr)[dIndex] = ((ARGBPixel *)sPtr)[sIndex]; };
                break;
            }

            case PixelFormat.Format24bppRgb:
            {
                header.imageSpecification.pixelDepth = 24;

                cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                { ((RGBPixel *)dPtr)[dIndex] = ((RGBPixel *)sPtr)[sIndex]; };
                break;
            }

            case PixelFormat.Format16bppRgb555:
            {
                header.imageSpecification.pixelDepth = 15;
                cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                { ((RGB555Pixel *)dPtr)[dIndex] = ((RGB555Pixel *)sPtr)[sIndex]; };
                break;
            }

            case PixelFormat.Format16bppArgb1555:
            {
                header.imageSpecification.pixelDepth = 16;
                header.imageSpecification.AlphaBits  = 1;
                cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                { ((RGB555Pixel *)dPtr)[dIndex] = ((RGB555Pixel *)sPtr)[sIndex]; };
                break;
            }

            default:
                throw new FormatException("Input pixel format unsupported.");
            }

            int mapLen  = header.colorMapSpecification.DataLength;
            int dataLen = header.imageSpecification.DataLength;

            int totalLen = TGAHeader.Size + mapLen + dataLen + TGAFooter.Size;

            stream.SetLength(totalLen);

            BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, bmp.PixelFormat);

            //using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 0x1000, FileOptions.RandomAccess))
            using (FileMap view = FileMap.FromStream(stream))// stream.MapView(0, (uint)totalLen, FileMapProtect.ReadWrite))
            {
                //Create header
                TGAHeader *pHeader = (TGAHeader *)view.Address;
                *          pHeader = header;

                //Write id

                //Write color map
                if (pal != null)
                {
                    VoidPtr pMap = pHeader->ColorMapData;
                    for (int i = 0; i < pal.Entries.Length; i++)
                    {
                        pEnc(ref pMap, pal.Entries[i]);
                    }
                }

                //Write color data
                int   dstStride = (pHeader->imageSpecification.pixelDepth * w).Align(8) / 8;
                int   origin    = (int)pHeader->imageSpecification.ImageOrigin;
                int   xStep     = ((origin & 1) == 0) ? 1 : -1;
                int   yStep     = ((origin & 2) != 0) ? 1 : -1;
                byte *imgDst    = pHeader->ImageData;
                for (int sY = (yStep == 1) ? 0 : h - 1, dY = 0; dY < h; sY += yStep, dY++)
                {
                    VoidPtr imgSrc = (VoidPtr)data.Scan0 + (data.Stride * sY);

                    //Do RLE encoding

                    for (int sX = (xStep == 1) ? 0 : w - 1, dX = 0; dX < w; sX += xStep, dX++)
                    {
                        cEnc(imgSrc, sX, imgDst, dX);
                    }

                    imgDst += dstStride;
                }

                //Write footer
                TGAFooter *pFooter = (TGAFooter *)(pHeader->ImageData + pHeader->imageSpecification.DataLength);
                *          pFooter = footer;
            }
            bmp.UnlockBits(data);
        }
        public static unsafe void ToStream(Bitmap bmp, FileStream stream)
        {
            int w = bmp.Width, h = bmp.Height;

            TGAHeader header = new TGAHeader();
            TGAFooter footer = new TGAFooter(0, 0);

            PaletteEncoder pEnc = null;
            ColorParser cEnc = null;
            ColorPalette pal = null;

            header.imageSpecification.width = (ushort)w;
            header.imageSpecification.height = (ushort)h;
            header.imageType = TGAImageType.UncompressedTrueColor;
            switch (bmp.PixelFormat)
            {
                case PixelFormat.Format4bppIndexed:
                case PixelFormat.Format8bppIndexed:
                    {
                        pal = bmp.Palette;

                        header.colorMapType = 1;
                        header.imageType = TGAImageType.UncompressedColorMapped;
                        header.colorMapSpecification.length = (ushort)pal.Entries.Length;
                        header.colorMapSpecification.entrySize = 24;
                        header.imageSpecification.pixelDepth = 8;

                        pEnc = (ref VoidPtr ptr, Color c) => { *(RGBPixel*)ptr = (RGBPixel)c; ptr += 3; };

                        if (bmp.PixelFormat == PixelFormat.Format4bppIndexed)
                            cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                            { ((byte*)dPtr)[dIndex] = ((sIndex & 1) == 0) ? (byte)(((byte*)sPtr)[sIndex >> 1] >> 4) : (byte)(((byte*)sPtr)[sIndex >> 1] & 0xF); };
                        else
                            cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                            { ((byte*)dPtr)[dIndex] = ((byte*)sPtr)[sIndex]; };

                        break;
                    }
                case PixelFormat.Format32bppRgb:
                case PixelFormat.Format32bppArgb:
                    {
                        header.imageSpecification.pixelDepth = 32;
                        header.imageSpecification.AlphaBits = (bmp.PixelFormat == PixelFormat.Format32bppArgb) ? (byte)8 : (byte)0;

                        cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((ARGBPixel*)dPtr)[dIndex] = ((ARGBPixel*)sPtr)[sIndex]; };
                        break;
                    }

                case PixelFormat.Format24bppRgb:
                    {
                        header.imageSpecification.pixelDepth = 24;

                        cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGBPixel*)dPtr)[dIndex] = ((RGBPixel*)sPtr)[sIndex]; };
                        break;
                    }

                case PixelFormat.Format16bppRgb555:
                    {
                        header.imageSpecification.pixelDepth = 15;
                        cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGB555Pixel*)dPtr)[dIndex] = ((RGB555Pixel*)sPtr)[sIndex]; };
                        break;
                    }
                case PixelFormat.Format16bppArgb1555:
                    {
                        header.imageSpecification.pixelDepth = 16;
                        header.imageSpecification.AlphaBits = 1;
                        cEnc = delegate(VoidPtr sPtr, int sIndex, VoidPtr dPtr, int dIndex)
                        { ((RGB555Pixel*)dPtr)[dIndex] = ((RGB555Pixel*)sPtr)[sIndex]; };
                        break;
                    }

                default:
                    throw new FormatException("Input pixel format unsupported.");
            }

            int mapLen = header.colorMapSpecification.DataLength;
            int dataLen = header.imageSpecification.DataLength;

            int totalLen = TGAHeader.Size + mapLen + dataLen + TGAFooter.Size;
            stream.SetLength(totalLen);

            BitmapData data = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, bmp.PixelFormat);
            //using (FileStream stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None, 0x1000, FileOptions.RandomAccess))
            using (FileMap view = FileMap.FromStream(stream))// stream.MapView(0, (uint)totalLen, FileMapProtect.ReadWrite))
            {
                //Create header
                TGAHeader* pHeader = (TGAHeader*)view.Address;
                *pHeader = header;

                //Write id

                //Write color map
                if (pal != null)
                {
                    VoidPtr pMap = pHeader->ColorMapData;
                    for (int i = 0; i < pal.Entries.Length; i++)
                        pEnc(ref pMap, pal.Entries[i]);
                }

                //Write color data
                int dstStride = (pHeader->imageSpecification.pixelDepth * w).Align(8) / 8;
                int origin = (int)pHeader->imageSpecification.ImageOrigin;
                int xStep = ((origin & 1) == 0) ? 1 : -1;
                int yStep = ((origin & 2) != 0) ? 1 : -1;
                byte* imgDst = pHeader->ImageData;
                for (int sY = (yStep == 1) ? 0 : h - 1, dY = 0; dY < h; sY += yStep, dY++)
                {
                    VoidPtr imgSrc = (VoidPtr)data.Scan0 + (data.Stride * sY);

                    //Do RLE encoding

                    for (int sX = (xStep == 1) ? 0 : w - 1, dX = 0; dX < w; sX += xStep, dX++)
                        cEnc(imgSrc, sX, imgDst, dX);

                    imgDst += dstStride;
                }

                //Write footer
                TGAFooter* pFooter = (TGAFooter*)(pHeader->ImageData + pHeader->imageSpecification.DataLength);
                *pFooter = footer;
            }
            bmp.UnlockBits(data);
        }