Example #1
0
        //SFFV2 从组和编码获取图像数据
        public byte[] getSprDataV2(int group, int index, FI_FORMAT type)
        {
            sprMsgV2 spr;

            for (int i = 0; i < msgV2.sprNum; i++)
            {
                spr = getSprMsgV2(i);
                if (spr.group == group && spr.index == index)
                {
                    //转移事件
                    return(getSprDataV2(i, type));
                }
            }

            return(null);
        }
Example #2
0
        public static IntPtr LoadFromMemory(byte[] sprData, FI_FORMAT type)
        {
            //读图像数据并储存在非托管内存
            IntPtr sprPoint = Marshal.AllocHGlobal(sprData.Length);

            Marshal.Copy(sprData, 0, sprPoint, sprData.Length);

            //从非托管内存提交给FreeImage
            int    sprStream = FI.OpenMemory((int)sprPoint, sprData.Length);
            IntPtr dib       = FI.LoadFromMemory(type, sprStream, 0);

            //释放
            Marshal.FreeHGlobal(sprPoint);
            FI.CloseMemory(sprStream);

            return(dib);
        }
Example #3
0
        //SFFV1 从组和编号获取图像数据
        public byte[] getSprDataV1(int group, int index, FI_FORMAT type)
        {
            int offset = msgV1.sprOffset;

            for (int i = 0; i < msgV1.sprNum; i++)
            {
                seek(offset);
                offset = br.ReadInt32();
                seek(8, SeekOrigin.Current);
                if (br.ReadUInt16() == group && br.ReadUInt16() == index)
                {
                    //转移事件
                    return(getSprDataV1(i, type));
                }
            }
            return(null);
        }
Example #4
0
        public static bool SaveToMemory(IntPtr dib, ref byte[] sprData, FI_FORMAT type)
        {
            //保存图像到流
            int newSprStream = FI.OpenMemory(0, 0);

            if (FI.SaveToMemory(type, dib, newSprStream, 0) == false)
            {
                return(false);
            }

            //将非托管数据重新转为托管类型
            int newSprPoint = 0;
            int newLen      = 0;

            FI.AcquireMemory(newSprStream, ref newSprPoint, ref newLen);
            sprData = new byte[newLen];
            Marshal.Copy((IntPtr)newSprPoint, sprData, 0, newLen);

            //释放
            FI.CloseMemory(newSprStream);

            return(true);
        }
Example #5
0
 private static extern bool SaveToMemory(FI_FORMAT fif, IntPtr dib, int stream, int flag);
Example #6
0
 private static extern IntPtr LoadFromMemory(FI_FORMAT fif, int stream, int Flag);
Example #7
0
        //SFFV2 从索引获取图像数据
        public byte[] getSprDataV2(int index, out byte[] pp, FI_FORMAT type, bool loadPal = true)
        {
            byte[]   sprData;
            byte[]   palData = null;
            int      sprSize;
            IntPtr   dib;
            sprMsgV2 spr = getSprMsgV2(index);

            if (spr.dataLen == 0)
            {
                //链接型图像
                return(getSprDataV2(spr.linkIndex, out pp, type));
            }
            seek((spr.flags == 1 ? msgV2.tdataOffset : msgV2.ldataOffset) + spr.dataOffset);

            //压缩算法(fmt)常量声明这里省略了,直接使用值
            //0 无压缩
            //2 Rle8压缩
            //3 Rle5压缩 几乎不会用到 直接省略
            //4 Lz5压缩
            //10 PNG8
            //11 PNG24
            //12 PNG32
            if (spr.fmt == 0)
            {
                sprData = br.ReadBytes(spr.dataLen);
            }
            else
            {
                sprSize = br.ReadInt32();                //解压后的校验长度,这里省略了校验
                sprData = br.ReadBytes(spr.dataLen - 4);
            }
            switch (spr.fmt)
            {
            case 0:
                if (loadPal)
                {
                    palData = getPalData(spr.palIndex);
                }
                pp = palData;
                break;

            case 2:
                sprData = sffV2Decompress.unRle8(sprData);
                if (loadPal)
                {
                    palData = getPalData(spr.palIndex);
                }
                pp = palData;
                break;

            case 4:
                sprData = sffV2Decompress.unLz5(sprData);
                if (loadPal)
                {
                    palData = getPalData(spr.palIndex);
                }
                pp = palData;
                break;

            case 10:
                //压缩算法为PNG算法时读取的数据默认都是一个完整的PNG文件 可以直接载入
                palData = getPalData(spr.palIndex);
                dib     = FI.LoadFromMemory(sprData, FI_FORMAT.FIF_PNG);
                //PNG8调色板校正
                RGBQUAD *pale = FI.GetPalette(dib);
                for (int n = 0; n < 256; n++)
                {
                    pale [n].Red   = palData [n * 4];
                    pale [n].Green = palData [n * 4 + 1];
                    pale [n].Blue  = palData [n * 4 + 2];
                }
                FI.SaveToMemory(dib, ref sprData, type);
                pp = palData;
                return(sprData);

            case 11:
            case 12:
                pp = null;
                return(sprData);

            default:
                sprData = new byte[0];
                pp      = new byte[0];
                return(sprData);
            }

            if (type != FI_FORMAT.FIF_UNKNOWN)
            {
                //对于无压缩、Rle8和Lz5压缩的图像读取的数据是原始的像素数据 不能直接载入
                dib = FI.ConvertFromRawBits(sprData, spr.width, spr.height, spr.width, 8, 0, 0, 0, true);
                RGBQUAD *pal      = FI.GetPalette(dib);
                int      colorNum = palData.Length / 4;
                for (int n = 0; n < colorNum; n++)
                {
                    pal [n].Red   = palData [n * 4];
                    pal [n].Green = palData [n * 4 + 1];
                    pal [n].Blue  = palData [n * 4 + 2];
                }
                FI.SaveToMemory(dib, ref sprData, type);
                FI.Free(dib);
                return(sprData);
            }
            else
            {
                return(sprData);
            }
        }
Example #8
0
        //SFFV1 从索引获取指定图像数据
        public byte[] getSprDataV1(int index, out byte[] pp, FI_FORMAT type)
        {
            int      offset = msgV1.sprOffset;
            sprMsgV1 spr    = new sprMsgV1();

            byte[] facePalData = new byte[0];
            byte[] palData     = new byte[0];
            byte[] sprData     = new byte[0];
            for (int i = 0; i < msgV1.sprNum; i++)
            {
                seek(offset);
                offset         = br.ReadInt32();
                spr.pcxDataLen = br.ReadInt32();
                spr.x          = br.ReadInt16();
                spr.y          = br.ReadInt16();
                spr.group      = br.ReadUInt16();
                spr.index      = br.ReadUInt16();
                spr.linkIndex  = br.ReadUInt16();
                spr.palType    = br.ReadByte();
                if (i == 0)
                {
                    //第一张图强制为独立色表
                    spr.palType = 0;
                }
                seek(13, SeekOrigin.Current);
                if ((spr.group == 0 && spr.index == 0 || spr.group == 9000 && spr.index == 0) && facePalData.Length != 0)
                {
                    //0,0和9000,0强制为独立色表,且使用第一张色表
                    palData = facePalData;
                }
                if (i == index)
                {
                    if (spr.pcxDataLen == 0)
                    {
                        //链接型图像
                        return(getSprDataV1(spr.linkIndex, out pp, type));
                    }

                    sprData = br.ReadBytes(spr.pcxDataLen);
                    if (type != FI_FORMAT.FIF_UNKNOWN)
                    {
                        IntPtr dib = FI.LoadFromMemory(sprData, FI_FORMAT.FIF_PCX);
                        if (spr.palType == 1)
                        {
                            RGBQUAD *pal = FI.GetPalette(dib);
                            for (int n = 0; n < 256; n++)
                            {
                                pal[n].Red   = palData[n * 3];
                                pal[n].Green = palData[n * 3 + 1];
                                pal[n].Blue  = palData[n * 3 + 2];
                            }
                        }
                        FI.SaveToMemory(dib, ref sprData, type);


                        //释放图像流
                        FI.Free(dib);
                    }

                    pp = palData;
                    return(sprData);
                }
                else
                {
                    if (spr.palType == 0)
                    {
                        //读取PCX尾部色表数据
                        seek(spr.pcxDataLen - 768, SeekOrigin.Current);
                        palData = br.ReadBytes(768);
                        if (i == 0)
                        {
                            //保留第一张图的色表
                            facePalData = palData;
                        }
                    }
                }
            }

            pp = null;
            return(null);
        }