标题: ls11格式详解
性别:未知-离线 boylinming

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 2
编号 36874
注册 2005-4-16


发表于 2005-4-16 08:52 资料 短消息 看全部作者
我是新人,前两天才知道有这个论坛,看了LS的解压缩,不知道你们如何测试出来的,我觉得GetCode函数应该改进,昨晚测到0点30分,应该快了不少,方法是利用查表代替测试Bit位。(为了能够让大家看明白意思,我没有做进一步的优化)

m_bitPos初始化为0,不是7了。

struct CompressValue
{
        union
        {
                int nValue;
                BYTE byValue[4];
        };
};

int g_CodeLen[] =
{
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 0
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 1
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 2
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 3
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 4
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 5
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 6
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // 7
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 8
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 9
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 10
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  // 11
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // 12
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  // 13
        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,  // 14
        4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,  // 15
};

int g_nValue[] =
{
        0, 2, 6, 14, 30, 62, 126, 254
};

int g_nMask[] =
{
        1, 3, 7, 15, 31, 63, 127, 255, 511
};

unsigned int GetCode()
{
        // 得到3个字节的数据, 反序
        CompressValue data;
        data.byValue[3] = m_pSrc[m_srcPos];
        data.byValue[2] = m_pSrc[m_srcPos+1];
        data.byValue[1] = m_pSrc[m_srcPos+2];

        // 移位, 使得最高位是有效数据
        data.nValue <<= m_bitPos;

        // 查表得到有效数据里面Bit==1的个数
        int nSetBitsNum = g_CodeLen[data.byValue[3]];

        // 查表得到uCode1
        unsigned int uCode1 = g_nValue[nSetBitsNum];

        // 数据移位, 消去uCode1使用部分
        // 同时使得data.byValue[3]的Bit0就是uCode2的Bit0
        // x <<= y, 当 y < 0 时有问题, 如果直接用汇编写, 就可能不需要分之判断
        // (我的8086的汇编忘光了, 但一些DSP芯片支持这样的指令的)
        int nShiftNum = (2*(nSetBitsNum+1) - 8);
        if (nShiftNum > 0)
        {
                data.nValue <<= nShiftNum;
        }
        else
        {
                data.nValue >>= abs(nShiftNum);
        }
       
        // 通过掩码计算, 得到uCode2
        unsigned int uCode2 = (data.byValue[3] & g_nMask[nSetBitsNum+1]);

        // 计算bitPos和srcPos的改变, 并改变之
        m_srcPos += ((2*(nSetBitsNum+1)+m_bitPos) >> 3);
        m_bitPos += 2*(nSetBitsNum+1);
        m_bitPos &= 7;

        return uCode1 + uCode2;
}


精华帖
顶部
性别:未知-离线 boylinming

Rank: 1
组别 百姓
级别 在野武将
功绩 0
帖子 2
编号 36874
注册 2005-4-16


发表于 2005-4-18 12:36 资料 短消息 看全部作者
我开始领会错了,是会溢出。
我修改下,生成的曹操传data.e5文件和网上下载的一样。但里面有几个if语句很不爽,谁优化下,尽量不要清空计算机的流水线。修改后的程序连续的1的个数也不能太多,12个以后也可能会出问题(曹操传data文件里面包含了几部分,不知道是否也是这个原因)。那个大表格不用动,其它改动如下:
struct CompressValue
{
        union
        {
                unsigned int nValue;
                unsigned short sValue[2];
                BYTE byValue[4];
        };
};

int g_nValue[] =
{
        0, 2, 6, 14, 30, 62, 126, 254, 510, 1022, 2046, 4094, 8190, 16382
};

int g_nMask[] =
{
        1, 3, 7, 15, 31, 63, 127, 255, 511, 1023
};

unsigned int LSCompress::GetCode()
{
        // 得到4个字节的数据, 反序
        CompressValue data;
        data.byValue[3] = m_pSrc[m_srcPos];
        data.byValue[2] = m_pSrc[m_srcPos+1];
        data.byValue[1] = m_pSrc[m_srcPos+2];
        data.byValue[0] = m_pSrc[m_srcPos+3];

        data.nValue <<= m_bitPos;

        int nSetBitsNum = g_CodeLen[data.byValue[3]];
        int nSetBitsNum1 = g_CodeLen[data.byValue[2]];

        unsigned int uCode1;       
        unsigned int uCode2;

        if (nSetBitsNum >= 8)
        {
                uCode1 = g_nValue[nSetBitsNum+nSetBitsNum1];

                int nRealShiftNum = nSetBitsNum + nSetBitsNum1 + 1;
                data.nValue <<= nRealShiftNum;
                data.nValue >>= (16-nRealShiftNum);
                uCode2 = data.sValue[1];

                m_srcPos += ((2*nRealShiftNum+m_bitPos) >> 3);
                m_bitPos += 2*(nRealShiftNum);
                m_bitPos &= 7;
        }
        else
        {               
                uCode1 = g_nValue[nSetBitsNum];

                int nShiftNum = (2*(nSetBitsNum+1) - 8);
                if (nShiftNum > 0)
                {
                        data.nValue <<= nShiftNum;
                }
                else
                {
                        data.nValue >>= abs(nShiftNum);
                }
                uCode2 = (data.byValue[3] & g_nMask[nSetBitsNum+1]);

                m_srcPos += ((2*(nSetBitsNum+1)+m_bitPos) >> 3);
                m_bitPos += 2*(nSetBitsNum+1);
                m_bitPos &= 7;
        }       

        return uCode1 + uCode2;
}


精华帖
顶部

正在浏览此帖的会员 - 共 1 人在线




当前时区 GMT+8, 现在时间是 2025-4-6 21:14
京ICP备2023018092号 轩辕春秋 2003-2023 www.xycq.org.cn

Powered by Discuz! 5.0.0 2001-2006 Comsenz Inc.
Processed in 0.010274 second(s), 9 queries , Gzip enabled

清除 Cookies - 联系我们 - 轩辕春秋 - Archiver - WAP