问完了将连续以10bit位存贮的数据转存到16bit位的问题后,
再问如何还原为以10bit存贮的数据呢?就是如何把存在16bit位
里的10bit位数据改回到连续以10bit位存贮。
多谢!

解决方案 »

  1.   

    学会使用 <<、>>、&操作符。
      

  2.   

    int convert(const unsigned short* src, int len, unsigned char*dest)
    {
    int off = 0;
    int index = 0;
    dest[0] = 0;
    for(int i = 0; i < len; i++)
    {
    off = 10 - (8 - off);
    dest[index] |= src[i] >> off;
    dest[index + 1] = ((unsigned char)src[i]) << (8 - off);
    index++;
    if(8 == off)
    {
    off = 0;
    index++;
    }
    } return 0 == off ? index : index + 1;
    }
      

  3.   

    steedhorse(晨星):
    我还是晕啊!
    convert(src, len, dest)
    这次的src是short int类型,dest是char类型,
    那么len是什么啊?是src的short int个数,还是src的长度呢!
    我认为是short int的个数,这样转完后长度是对的,但是里面的
    数值是错的啦!
    求steedhorse(晨星) 再指点
      

  4.   

    steedhorse(晨星)大侠:
    我是这样试的,先将一个10bit的文件用你给的方法转为16bit文件;
    之后再用上面的方法,转回10bit文件,用Windows的FC程序比较源10bit文件
    与转回的10bit文件时发现两个10bit文件完全不同啊!
    FC /b 源10bit文件.dat 转回的10bit文件.dat我的代码:
    void __fastcall TForm1::SpeedButton1Click(TObject *Sender) <<<===10b转16b
    {
    unsigned char srcData[5000];
    unsigned short int dest[4000];
    int iFileHandle;
    int oFileHandle;
    int iFileLen;
    int iFilePos;
    int iByteLen;
    int len;
    AnsiString outFileName;
        TOpenDialog *a = new TOpenDialog(this);
        a->Filter= "10bit files (*.10b)|*.DAT|All files (*.*)|*.*";
        if(a->Execute())
        {
           iByteLen=0;
           iFilePos=0;
           outFileName=a->FileName+".16b";
           iFileHandle=FileOpen(a->FileName,fmShareDenyNone);
           oFileHandle=FileCreate(outFileName);
           iFileLen=FileSeek(iFileHandle,0,2);
           FileSeek(iFileHandle,0,0);
           while(iFilePos<iFileLen)
           {
             iByteLen=FileRead(iFileHandle,&srcData,sizeof(srcData));
             len=convert_10to16(srcData, iByteLen, dest);
             FileWrite(oFileHandle,&dest,len*2);
             iFilePos+=iByteLen;
             if(iByteLen<5000) break;
           }
           FileClose(iFileHandle);
           FileClose(oFileHandle);
           ProgressBar1->Position =0;
           Application->MessageBoxA("10bit->16bit转换完成","提示",MB_OK);
        }
    }
    //--------------------------------------
    void __fastcall TForm1::SpeedButton2Click(TObject *Sender)  <<====16b转10b
    {
        TOpenDialog *a = new TOpenDialog(this);
        a->Filter= "16bit files (*.16b)|*.DAT|All files (*.*)|*.*";
        if(a->Execute())
        {
           iByteLen=0;
           iFilePos=0;
           outFileName=a->FileName+".10b";
           iFileHandle=FileOpen(a->FileName,fmShareDenyNone);
           oFileHandle=FileCreate(outFileName);
           iFileLen=FileSeek(iFileHandle,0,2);
           FileSeek(iFileHandle,0,0);
           while(iFilePos<iFileLen)
           {
             iByteLen=FileRead(iFileHandle,&dest,sizeof(dest));
             len=convert_16to10(dest, iByteLen/2, srcData);
             FileWrite(oFileHandle,&srcData,len);
             iFilePos+=iByteLen;
             if(iByteLen<5000) break;
           }
           FileClose(iFileHandle);
           FileClose(oFileHandle);
           ProgressBar1->Position =0;
           Application->MessageBoxA("16bit->10bit转换完成","提示",MB_OK);
        }
    }
      

  5.   

    调试过来,的确没有问题啊。要么你单步跟踪一下,使用小的文件,比如只有40个bit的一步一步测试一下,看那一步开始出现的问题 。
      

  6.   

    class CBitstream
    {
    public:
    CBitstream()
    {
    m_pBuffer = NULL;
    m_nNumCur = 0;
    m_nCount = 0;
    }


    void Init(unsigned char* pBytes, int len)
    {
    m_pBuffer = pBytes;
    m_nNumCur = 0;
    m_nCount = 8 * len;
    }

    void PutBits(int nRet, int numBits)
    {
    for (int i = numBits - 1; i >= 0; i--)
    {
    m_pBuffer[m_nNumCur >> 3] |= ((nRet >> i) & 1) << (7 - (m_nNumCur & 7));
    m_nNumCur++;
    }
    }

    int GetBits(int numBits)
    {
    int nRet = 0;

    for (int i = 0; i < numBits; i++)
    {
    nRet <<= 1;
    nRet |= (m_pBuffer[m_nNumCur/8]>> (7-(m_nNumCur%8))) & 1;
    if(++m_nNumCur>=m_nCount)
    break;
    }
    if(i<numBits)
    nRet <<=numBits-i;
    return nRet;
    }
    int GetLastBits()
    {
    return m_nCount - m_nNumCur;
    }

    protected:
    unsigned char* m_pBuffer;
    int m_nNumCur;
    int m_nCount;
    };//测试程序
    int main()
    {
        // 测试2进制序列: 0011110101 1010101001 0101010011 1111100000 0110100110
        // 其10进制值: 245 681 339 992 422
        // 如果按byte组合(最后补0): 
        //  00111101 01101010 10010101 01001111 11100000 01101001 10000000
        // 16进制:0x3d 0x6a 0x95 0x4f 0xe0 0x69 0x80
        unsigned char src[] = {0x3d, 0x6a, 0x95, 0x4f, 0xe0, 0x69, 0x80};
    CBitstream bs;

    unsigned short dest16[64]={0};
    unsigned char dest10[64]={0};
    int i,len=0;
    bs.Init(src,sizeof(src));
    while(bs.GetLastBits())
    dest16[len++]=bs.GetBits(10);
        // 打印出:245 681 339 992 422 0正确。
        for(i = 0; i < len; i++)
            printf("%d ",dest16[i]);
        printf("\n");

    bs.Init(dest10,sizeof(dest10));
    for(i = 0; i < len; i++)
    bs.PutBits(dest16[i],10);
    // 打印出:3d 6a 95 4f e0 69 80 正确。
    for(i = 0; i < sizeof(src); i++)
            printf("%x ",dest10[i]);
    printf("\n");


        return 0;
    }
      

  7.   

    steedhorse(晨星)大侠:
    如果我每次从10bit文件中读5字节(也就是4个10bit数,其10进制值: 245 681 339 992
    共使用40bit=5字节,对吧)如下:拆分为5个字节应是:0x3d, 0x6a, 0x95, 0x4f, 0xe0
    转为4个16bit数时总长变为8字节,其10进制值不变)
    unsigned char src[] = {0x3d, 0x6a, 0x95, 0x4f, 0xe0};//, 0x69, 0x80};
    但是此时输出是
    4个16bit数:245 681 339 1984 <<-----应是992
    再还原为4个10bit数:3d  6a  95  4f  c0  <<----应是e0
      

  8.   

    上贴错了:
    应是 按vcmute(横秋):的方法:
    如果我每次从10bit文件中读5字节(也就是4个10bit数,其10进制值: 245 681 339 992
    共使用40bit=5字节,对吧)如下:拆分为5个字节应是:0x3d, 0x6a, 0x95, 0x4f, 0xe0
    转为4个16bit数时总长变为8字节,其10进制值不变)
    unsigned char src[] = {0x3d, 0x6a, 0x95, 0x4f, 0xe0};//, 0x69, 0x80};
    但是此时输出是
    4个16bit数:245 681 339 1984 <<-----应是992
    再还原为4个10bit数:3d  6a  95  4f  c0  <<----应是e0
      

  9.   

    steedhorse(晨星):
    果然如steedhorse(晨星)所说:改为一次只读4个16bit数并转为5字节的10bit数时就对了。