简体   繁体   English

转换向量 <unsigned char> 矢量 <unsigned short>

[英]Convert a vector<unsigned char> to vector<unsigned short>

I'm getting data from a binary file, reading from file and writing in a vector of unsigned char. 我从二进制文件中获取数据,从文件中读取数据并写入无符号字符的向量。 I can't edit it, because I'm using a external library. 我无法编辑它,因为我正在使用外部库。

But the data that I'm reading from file is a 16 bits image, and I'd like to put the data in a vector of unsigned short 但是我从文件中读取的数据是16位图像,我想将数据放入无符号short的向量中

Maybe I can do a cast for it? 也许我可以为此做演员?

Rgds. Rgds。

A generic approach (not bullet proof): 通用方法(非防弹):

#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>

typedef unsigned char u8;
typedef unsigned short u16;

u16 combine_two_bytes(u8 a, u8 b) {
    return a | (b << 8);
}

template<typename InIter, typename OutIter, typename InT, typename OutT>
void combine_pairs(InIter in, InIter in_end, OutIter out, OutT (*func)(InT, InT)) {
    while(1) {
        if(in == in_end) {
            break;
        }

        InT &left = *in++;

        if(in == in_end) {
            break;
        }

        InT &right = *in++;

        *out++ = func(left, right);
    }
}

int main() {
    using namespace std;    // lazy

    u8 input[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    const size_t in_size = sizeof(input) / sizeof(*input);
    u16 output[in_size / 2];

    cout << "Original: ";
    copy(input, input + in_size, ostream_iterator<int>(cout, " "));
    cout << endl;

    combine_pairs(input, input + in_size, output, combine_two_bytes);

    cout << "Transformed: ";
    copy(output, output + in_size / 2, ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}

If you just want to convert from one type to the other then use the standard constructor. 如果只想从一种类型转换为另一种类型,则使用标准构造函数。 As long as the iterators value type is auto convertible to the destination vectors value type the compiler will do the auto conversion between the two types. 只要迭代器值类型可以自动转换为目标向量值类型,编译器就会在两种类型之间进行自动转换。 Just use the standard constructor 只需使用标准构造函数

#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<unsigned char>      a;
    a.push_back((unsigned char)12);
    a.push_back((unsigned char)13);
    a.push_back((unsigned char)14);

    std::vector<unsigned short>     b(a.begin(),a.end());

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

> g++ t.cpp
> ./a.out
12  13 14

If you actually want to convert two bytes into one then some work is required. 如果您实际上想将两个字节转换为一个字节,则需要进行一些工作。 But it depends if the input data is actually the same endianess as the machine you are on. 但这取决于输入数据是否实际上与您所使用的机器具有相同的耐久性。 If you know that it is the same endianess that you just need to cast the input type. 如果您知道它具有相同的字节序,则只需要强制转换输入类型。

#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::vector<unsigned char>      a;

    // Make sure that the size is correct.
    // ie. An Odd number indicates that something is not quite correct.
    //
    std::vector<unsigned short>     b(static_cast<unsigned short*>(&a[0]),
                                      static_cast<unsigned short*>(&a[a.size()]));

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

Alternatively if you actually need to combine two values into a single value where the endianess is not the same as the target architecture, you can write a special iterator. 另外,如果您实际上需要将两个值组合成一个字节,并且字节序的字节序与目标体系结构不相同,则可以编写一个特殊的迭代器。 Something like this: 像这样:

#include <Converter.h>

int main()
{
    std::vector<unsigned char>      a;

    // Make sure that the size is correct.
    // ie. An Odd number indicates that something is not quite correct.
    //
    std::vector<unsigned short>     b(make_Converter(a.begin()),make_Converter(a.end()));

    // Print out the vector
    std::copy(b.begin(),b.end(),std::ostream_iterator<unsigned short>(std::cout,"\t"));
}

Converter.h Converter.h

#include <vector>
#include <iostream>
#include <iterator>

template<typename I>
struct Converter
{
    I   iterator;

    typedef typename std::input_iterator_tag                    iterator_category;
    typedef typename std::iterator_traits<I>::value_type        value_type;
    typedef typename std::iterator_traits<I>::difference_type   difference_type;
    typedef typename std::iterator_traits<I>::pointer           pointer;
    typedef typename std::iterator_traits<I>::reference         reference;

    Converter(I iter)
        :iterator(iter)
    {}

    Converter& operator++()
    {
        iterator++;
        return *this;
    }

    Converter operator++(int)
    {
        Converter   tmp(*this);
        this->operator++();

        return (tmp);
    }

    value_type operator*()
    {
        /*
         * The actual calculation done here will depend on the underlying hardware.
         */
        typename std::iterator_traits<I>::value_type val(*iterator);
        val << 8;
        iterator++;
        val |= (*iterator);

        return val;
    }

    bool operator!=(Converter const& rhs)
    {
        return iterator != rhs.iterator;
    }
};

template<typename I>
Converter<I> make_Converter(I iter)
{
    return Converter<I>(iter);
}
vector<unsigned char> a = ...;
vector<unsigned short> b(a.begin(), a.end());

But you want valarray s for simple data vectors. 但是,您希望将valarray用于简单的数据向量。

Assuming the binary data in your file is in little-endian order, I would do this the simple way: 假设文件中的二进制数据是按小端顺序排列的,那么我将以一种简单的方式执行此操作:

vector<unsigned char> a = ...;

std::vector<unsigned short> b;
b.reserve( a.size() / sizeof(unsigned short) );

for( std::vector<unsigned char>::const_iterator i=a.begin(); i!=a.end(); i+=2 )
{
    unsigned short shortValue = *(i+1);
    shortValue <<= 8;
    shortValue |= *i;
    b.push_back( shortValue );
}

If the data in your file is big-endian you will need to compose the short value the other way round. 如果文件中的数据是高位优先的,则需要反过来编写short值。 You should also guard against the number of entries in "a" not being a multiple of 2. 您还应防止“ a”中的条目数不是2的倍数。

disclaimer: I don't have a compiler right now: 免责声明:我现在没有编译器:

vector<unsigned char> vec = getVector();
vector<unsigned short> sv(reinterpret_cast<unsigned short*>(&vec[0]), 
                          reinterpret_cast<unsigned short*>(&vec[vec.size()]));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM