各位好。我正在进行分析flash影片*.swf二进制文件的工作,但是我遇到了我从来没有想到的问题:某些字节不能作为字节处理,而要把他们处理成一列位(bit),然后由这些bit组成的数字才是我想要的内容。当然,这样的描述难于理解,下面我给出一个例子:在该swf文件中,有如下字节:77 FB 0D E2 FF B0 0F B0对应的二进制位分别是:
77 FB 0D E2 FF B0 0F B0
01110111 11111011 00001101 11100010 11111111 10110000 00001111 10110000这8个字节代表一个矩形,并且不是固定的8个字节,有可能多或者少,所以不能单纯的作为8个字节来一次性读取。我把这8个字节所有的64位所代表的意义分析一下,前5位所组成的数字01110(十进制14)说明了组成矩形的两个坐标[x1,y1][x2,y2]的四个数字分别应该占用14个二进制的位,并且是顺序排列的,上面的64位分隔成如下的序列:01110 11111111011000 01101111000101 11111111011000 00000111110110 000
位数 x1 x2 y1 y2 补充位,使其成为字节现在的问题是,如何通过程序将这8个字节64位分割成我想要得5 - 14 - 14 - 14 -14 结构,注意,位数是无符号的、x1、x2、y1、y2是有符号的。
77 FB 0D E2 FF B0 0F B0
01110111 11111011 00001101 11100010 11111111 10110000 00001111 10110000这8个字节代表一个矩形,并且不是固定的8个字节,有可能多或者少,所以不能单纯的作为8个字节来一次性读取。我把这8个字节所有的64位所代表的意义分析一下,前5位所组成的数字01110(十进制14)说明了组成矩形的两个坐标[x1,y1][x2,y2]的四个数字分别应该占用14个二进制的位,并且是顺序排列的,上面的64位分隔成如下的序列:01110 11111111011000 01101111000101 11111111011000 00000111110110 000
位数 x1 x2 y1 y2 补充位,使其成为字节现在的问题是,如何通过程序将这8个字节64位分割成我想要得5 - 14 - 14 - 14 -14 结构,注意,位数是无符号的、x1、x2、y1、y2是有符号的。
解决方案 »
- 一个再简单不过的多线程同步问题。。。
- Microsoft.VC80.CRT 文件缺失
- 我的程序中用到了gdi+,但是客户端不想安装.net,如何单独安装gdi+呢?需要那些支持文件?
- 请问列表控件的标题部分能不能支持复杂点的功能,比如支持换行???
- 用IshellFolder::EnumObjects列举文件夹的各项,无法获取隐藏文件或文件夹???
- 请问,如何设置CPropertySheet在Dialog上的位置?
- 高手们帮帮忙把,谢谢
- 那一个有directshow或directx8.1的中文入门书
- 内存泄漏问题(这是道笔试题)
- 为什么AviFileOpen在win2000里会出错?
- 结构数组可以动态创建吗??在线等待!!
- 如何在第二次运行同一个程序的实例时,后者不运行而把第一个实例激活在最前端显示?
比如
你先一次读出整个数=a
y2 = a & (2(14次方)-1)
y1 = (a>>14) & (2(14次方)-1)
...
9BIT,你可以用16BIT(WORD)来代啊,你可以认为高7位没有定义啊!
{
union ULONGLONG data64;
union struct
{
BYTE b1;
BYTE b2;
BYTE b3;
BYTE b4;
};
WORD Get14BIT0()
{
return (WORD)(data64 & 0x0000000000003FFF);
}
WORD Get14BIT1()
{
return (WORD)((data64 >> 14) & 0x0000000000003FFF);
}
WORD Get14BIT2()
{
return (WORD)((data64 >> 28) & 0x0000000000003FFF);
}
WORD Get14BIT3()
{
return (WORD)((data64 >> 42) & 0x0000000000003FFF);
}
BYTE GetHight5BIT()
{
return (BYTE)((data64 >> 56) & 0x000000000000001F);
}
}BITMAKER, *PBITMAKER;
typedef struct _BITMAKER
{
union
{
ULONGLONG data64;
struct
{
BYTE b1;
BYTE b2;
BYTE b3;
BYTE b4;
};
}
WORD Get14BIT0()
{
return (WORD)(data64 & 0x0000000000003FFF);
}
WORD Get14BIT1()
{
return (WORD)((data64 >> 14) & 0x0000000000003FFF);
}
WORD Get14BIT2()
{
return (WORD)((data64 >> 28) & 0x0000000000003FFF);
}
WORD Get14BIT3()
{
return (WORD)((data64 >> 42) & 0x0000000000003FFF);
}
BYTE GetHight5BIT()
{
return (BYTE)((data64 >> 56) & 0x000000000000001F);
}
}BITMAKER, *PBITMAKER;
// 从指定的地址块pData的第nFrom位(nFrom >= 0)读取nBits(nBits >= 0)
// 结果作为一个DWORD返回,可以通过强制类型转换变为其它类型
DWORD GetDataByBit(LPBYTE pData, int nFrom, int nBits)
{
int nByteOffset = nFrom >> 3; // 起始字节偏移数(nFrom / 8)
int nBitOffset = nFrom - nByteOffset << 3; // 起始位偏移数(nFrom % 8)
LPBYTE pb = pData + nOffset; // 第一个字节
DWORD r = 0;
int l = 8 - nBitOffset; // 第一个字节余下的位数
BYTE b;
if (nBits <= l) // 所读的位数全在第一个字节内
{
b = (*pb << nBitOffset) >> (8 - nBits);
r = (DWORD)b;
return r;
} // 先读第一个字节内余下的位
b = (*pb << nBitOffset) ) >> nBitOffset;;
r = (DWORD)b;
pb++; // 循环读取后续字节内的位
int nLen = nBits - l; // 还需要读的位数
while (nLen >= 8) // 按字节读取
{
b = *pb;
r <<= 8;
r |= (DWORD)b;
nLen -= 8;
pb++;
}
if (nLen > 0) // 还余有未成字节的位
{
b = *pb >> (8 - nLen);
r <<= 8;
r |= (DWORD)b;
} return r;
}
byte nBit, rectBytes;
unsigned short nRectBits, nRectBytes;
long long nRect = 0; m_swfFile.Read(&nBit, UI8);
nBit >>= 3;
nRectBits = nBit * 4 + 5;
if(nRectBits % 8)
nRectBytes = nRectBits / 8 + 1;
else
nRectBytes = nRectBits / 8; // 并将这些字节的所有位按顺序存入一个long long数据中
m_swfFile.Seek(-1, CFile::current);
for(int i = 1; i <= nRectBytes; i++)
{
m_swfFile.Read(&rectBytes, UI8);
if( i == 1)
{
nRect = rectBytes;
nRect <<= 61;
nRect >>= 61;
}
else if( i == nRectBytes)
{
if(nBit * 4 % 8)
nRect <<= (nBit * 4 % 8 - 3);
else
nRect <<= 5;
rectBytes >>= 3;
nRect |= rectBytes;
}
else
{
nRect <<= 8;
nRect |= rectBytes;
}
} // 使用位运算依次得出四个坐标
long long x1, x2, y1, y2;
x1 = (nRect << (64 - nBit * 4)) >> (64 - nBit);
x2 = (nRect << (64 - nBit * 3)) >> (64 - nBit);
y1 = (nRect << (64 - nBit * 2)) >> (64 - nBit);
y2 = (nRect << (64 - nBit)) >> (64 - nBit);