从struct到std :: vector的二进制复制数据

时间:2018-12-25 21:44:22

标签: c++ vector binary-data stdcopy

我正在使用一个可以从内存中加载BMP图像的库。

我有一个代表BMP的类。

要从内存中加载,我必须提供指向内存中某些BMP格式数据的指针以及该数据大小的变量。 (void* data, size_t length)

我想将数据存储在std::vector中。 (避免手动内存管理)

我试图编写一个返回std::vector<unsigned char>的函数,但是我认为我所获得的不是很好。

std::vector<unsigned char> BMP::BITMAP::SaveMem() const
{

    // memory storage
    std::vector<unsigned char> memory;


    BITMAPFILEHEADER f_head;
    f_head.bfType = ushort_rev(((WORD)'B' << 0x08) | ((WORD)'M' << 0x00));
    f_head.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_width_memory * m_height;
    f_head.bfReserved1 = 0;
    f_head.bfReserved2 = 0;
    f_head.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);


    // build standard bitmap file header
    BITMAPINFOHEADER i_head;
    i_head.biSize = sizeof(BITMAPINFOHEADER);
    i_head.biWidth = m_width;
    i_head.biHeight = m_height;
    i_head.biPlanes = 1;
    i_head.biBitCount = m_bit_count;
    i_head.biCompression = 0;
    i_head.biSizeImage = m_width_memory * m_height;
    i_head.biXPelsPerMeter = 0;
    i_head.biYPelsPerMeter = 0;
    i_head.biClrUsed = 0;
    i_head.biClrImportant = 0;


    // alloc
    memory.resize(f_head.bfSize);

    std::copy(&f_head, &f_head + sizeof(f_head), memory.at(0));
    std::copy(&i_head, &i_head + sizeof(i_head), memory.at(0) + sizeof(f_head));


    // write data
    for(unsigned int y = 0; y < m_height; ++ y)
    {
        std::copy(&m_data[y * m_width_memory], m_data[y * m_width_memory + 3 * m_size_x], memory.at(0) + sizeof(f_head) + sizeof(i_head));
    }

}

很显然,这无法编译。我想不出std::copy的替代方案。这真的是完成工作的正确工具吗?

要使其编译,我认为我应该将memory.at(x)更改为memory.data() + x ...这样,我将使用原始指针-这就是为什么我不认为std::copy是比memcpy更好。

请问对此有何建议?这有点不合逻辑,我早些时候就知道这一要求,所以我会将像素数据存储在unsigned char中,而位图文件头位于数据之前。不幸的是,现在更改设计将需要大量工作,因此我宁愿不去尝试。

1 个答案:

答案 0 :(得分:1)

三个问题:

  1. 您要复制 bytes ,但是std::copy函数提供了指向BITMAPFILEHEADER(或BITMAPINFOHEADER)结构的指针。您需要将指针转换为 bytes ,例如reinterpret_cast<uint8_t*>(&f_head)

  2. 前者会导致数据末尾的其他问题,表达式&f_head + sizeof(f_head)实际上等于(&f_head)[sizeof(f_head)],并且超出了结构末尾。您还需要在此处使用字节,例如reinterpret_cast<uint8_t*>(&f_head) + sizeof f_head

  3. 最后一个问题是std::copy调用的目标,因为它的类型必须与源相似,即指向uint8_t的指针(对于我的演员来说) 。您可以通过例如&memory[0]。第二个电话是&memory[sizeof f_head]