//SFFV2 获取指定图像信息 public sprMsgV2 getSprMsgV2(int index, sprMsgV2 sp = null) { sprMsgV2 spr; if (sp == null) { spr = new sprMsgV2(); } else { spr = sp; } seek(msgV2.sprOffset + 28 * index); spr.group = br.ReadUInt16(); spr.index = br.ReadUInt16(); spr.width = br.ReadUInt16(); spr.height = br.ReadUInt16(); spr.x = br.ReadInt16(); spr.y = br.ReadInt16(); spr.linkIndex = br.ReadUInt16(); spr.fmt = br.ReadByte(); spr.depth = br.ReadByte(); spr.dataOffset = br.ReadInt32(); spr.dataLen = br.ReadInt32(); spr.palIndex = br.ReadUInt16(); spr.flags = br.ReadUInt16(); return(spr); }
public void AssignTo(ref sprMsgV2 other) { if (other == null) { other = new sprMsgV2(); } other.group = group; other.index = index; other.width = width; other.height = height; other.x = x; other.y = y; other.linkIndex = linkIndex; other.fmt = fmt; other.depth = depth; other.dataOffset = dataOffset; other.dataLen = dataLen; other.palIndex = palIndex; other.flags = flags; }
public bool RawForeachV2(TOnRawForeachV2 OnRawForeachV2) { if (ver != 2 || OnRawForeachV2 == null) { return(false); } sprMsgV2 spr = null; sprMsgV2 linkSpr = null; #if _USE_PAL_LINK Dictionary <int, KeyValuePair <ushort, ushort> > palIndexMap = null; #endif for (int i = 0; i < getSprNum(); ++i) { spr = getSprMsgV2(i, spr); if (spr.dataLen == 0) { // 链接类型 spr.AssignTo(ref linkSpr); while (linkSpr.dataLen == 0) { linkSpr = getSprMsgV2(linkSpr.linkIndex, linkSpr); } // 暂时不做PNG类型的支持 if (linkSpr.fmt == 10 || linkSpr.fmt == 11 || linkSpr.fmt == 12) { return(false); } OnRawForeachV2(this, spr, linkSpr.group, linkSpr.index, -1, -1, null); } else { // 暂时不做PNG类型的支持 if (spr.fmt == 10 || spr.fmt == 11 || spr.fmt == 12) { return(false); } /* * if (spr.group == 1005 && spr.index == 5) { * Debug.Log ("ok"); * } */ int linkPalGroup = -1; int linkPalIndex = -1; bool isPattleLink = false; #if _USE_PAL_LINK if (palIndexMap != null) { KeyValuePair <ushort, ushort> vvv; isPattleLink = palIndexMap.TryGetValue(spr.palIndex, out vvv); if (isPattleLink) { linkPalGroup = vvv.Key; linkPalIndex = vvv.Value; } } #endif byte[] pal; bool isHasPal = isPattleLink || IsHasPalMap(spr.group, spr.index); byte[] colors = getSprDataV2(i, out pal, FI_FORMAT.FIF_UNKNOWN, !isHasPal); if (colors == null || colors.Length <= 0) { return(false); } if (!isHasPal && pal != null && pal.Length > 0) { KeyValuePair <ushort, ushort> key = new KeyValuePair <ushort, ushort> (spr.group, spr.index); PalMap.Add(key, pal); #if _USE_PAL_LINK if (palIndexMap == null) { palIndexMap = new Dictionary <int, KeyValuePair <ushort, ushort> > (); } palIndexMap.Add(spr.palIndex, key); #endif } OnRawForeachV2(this, spr, -1, -1, linkPalGroup, linkPalIndex, colors); } } return(true); }
//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); } }