已知
1. 一个dat文件,由文件头与N个图形数据组成
2. 单个图形数据的大部分结构
我通过FileSteam把文件读入缓冲区,用这个结构去读这个缓冲区,可以顺利把数据取出。但
但因为缺乏图形编程的经验,所以无法把这些数据还原成图像。
特来求教。以下是部分代码(c#),也可用其他语言,能把逻辑讲明白即可,直接运行即可把相关数据读到缓冲区
//调试用,写死目标文件名
string path = @"C:\test.dat";
//FileStream方式读取文件到缓冲区buff
FileStream steam = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(steam);
//文件头部分,一个文件只有一个文件头
short unknow = reader.ReadInt16();
short width = reader.ReadInt16();
short height = reader.ReadInt16();
int depthRes = reader.ReadInt32();
int paletteFlag = reader.ReadInt32();
short[] paletteEntry = new short[256];
if (paletteFlag > 0)
{
for (int pe = 0; pe < 256; pe++)
{
paletteEntry[pe] = reader.ReadInt16();
}
}
string dataPos = Convert.ToString(reader.ReadInt32(), 16); //偏移值,用16进制来存,表示这里开始是图片数据
short imageCount = reader.ReadInt16(); //不用管
//以下直接创建297个数组,因为已知文件里有3个图形组,每个都有297个图形数据。这里只要能读取第一个组即可,所以直接这样写
short[] top = new short[297];
short[] left = new short[297];
short[] bottom = new short[297];
short[] right = new short[297];
int[] flag = new int[297];
int[] hasAlpha = new int[297];
int[] alpha_legth = new int[297];
int[] alpha_dataOffset = new int[297];_
int[] hasBase = new int[297];
int[] base_dataOffset = new int[297];
int[] base_length = new int[297];
int[] hasDepth = new int[297];
byte[] depthType = new byte[297];
short[] val2 = new short[297];
short[] nearestDist = new short[297];
int[] depthOffset = new int[297];
int[] depthSize = new int[297];
int[] unk2Length = new int[297];
int[] unk2Offset = new int[297];
//开始逐一从流中读取数据
int unknown1 = reader.ReadInt32();
if (unknown1 > 0)
{
int unknown2 = reader.ReadInt32();
}
//frameCount 为图片的总数量,示例里是每组 297 张图片
short frameCount= reader.ReadInt16();
for (int n = 0; n < frameCount; n++)
{
top[n] = reader.ReadInt16(); //推测:bottom与top的距离;right与left的距离即为单个图像的尺寸
left[n] = reader.ReadInt16();
bottom[n] = reader.ReadInt16();
right[n] = reader.ReadInt16();
flag[n] = reader.ReadInt32(); //不明
hasAlpha[n] = flag[n] & 8; // 0:hasAlpha 1:noAlpha
if (hasAlpha[n] == 0)
{
alpha_legth[n] = reader.ReadInt32();
alpha_dataOffset[n] = reader.ReadInt32();
}
hasBase[n] = flag[n] & 4; //0:noBase 1:hasBase
if (hasBase[n] != 0)
{
base_dataOffset[n] = reader.ReadInt32();
base_length[n] = reader.ReadInt32();
}
hasDepth[n] = flag[n] & 1; //0:noDepth 1:hasDepth
if (hasDepth[n] != 0)
{
depthType[n] = reader.ReadByte(); //0指WORD / depthRes, 1指BYTE / depthRes, 2指步长 3指填充nearestDist。(这个是网上找到的,具体意思不明)
val2[n] = reader.ReadInt16();
nearestDist[n] = reader.ReadInt16();
depthOffset[n] = reader.ReadInt32();
depthSize[n] = reader.ReadInt32();
}
unk2Length[n] = reader.ReadInt32();
if (unk2Length[n] > 0)
{
unk2Offset[n] = reader.ReadInt32();
}
代码运行后,会读出对应数据。以第[0]个图片为例,有用的数据为
width = 374;
height = 232;
depthRes = 10;
paletteFlag = 1;
paletteEntry[256] = [略]
dataPos = 14225;//偏移值,从这里开始是图形数据
imageCount = 3;//这个文件一共有3组图像
frameCount = 297;//一组图像数据里有297个图像数据
top[0]=-143;
left[0]=-95;
bottom[0]=2;
right[0]=70;
flag=5;
hasAlpha =0;
alpha_legth = 4288;
alpha_dataOffset = 0;//推测这里就是datapos,图形数据的起点,所以偏移值=0
hasBase!=0;
base_dataOffset = 4288; //偏移了4288,刚好是alpha的长度
base_length = 12256;
hasDepth!=0;
depthType=0;
nearestDist=199;
depthOffset=16544;
depthSize=510;
另外还有部分定义不知道怎么处理(完整描述见附件部分),如果正确写入到图形文件里的话,应该是下图的样子
求高手能讲解一下整个流还原图形的思路和对应使用的方法。
附件:
1. 测试用dat:链接: https://pan.baidu.com/s/1m1XZbHF0MgeBU8g3wdq0Ow 密码: w647
2. 完整数据结构参考https://shimo.im/docs/KB9AtVBVBHsK1va3
有大神帮帮忙吗。。。