Is there a way to do the following better? Current I write a set of pixels to a file called "PngFile.bmp". Then I read that file back in as a PNG encoded buffer.. Then I save that buffer back to the harddisk and delete "PngFile.bmp"

    /*std::fstream PngFile(TempPath, std::fstream::out | std::fstream::app | std::ofstream::binary);
    if (!PngFile.is_open()) return false;

    PngFile.write(reinterpret_cast<char*>(&bFileHeader), sizeof(BITMAPFILEHEADER));
    PngFile.write(reinterpret_cast<char*>(&Info.bmiHeader), sizeof(BITMAPINFOHEADER));
    PngFile.write(reinterpret_cast<char*>(&TEMP[0]), Size());
    PngFile.close();
    */

    //I do not want to write it to a physical file.. Maybe if I can write it to a memory location.. Maybe write it to a vector of unsigned chars.


    //There has to be a better way to do the following?..

    unsigned w = 0, h = 0;
    std::vector<unsigned char> bmp(sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + Size());
    unsigned char* Ppos = &bmp[0];
    memcpy(Ppos, &bFileHeader, sizeof(BITMAPFILEHEADER));   //copy the file header into the vector.
    Ppos += sizeof(BITMAPFILEHEADER);
    memcpy(Ppos, &Info.bmiHeader, sizeof(BITMAPINFOHEADER)); //copy the info header into the vector.
    Ppos += sizeof(BITMAPINFOHEADER);
    memcpy(Ppos, &TEMP[0], Size());                         //copy/append the vector of pixels into the vector.

    std::vector<unsigned char> image, png;
    if (DecodeBMP(image, w, h, bmp) || lodepng::encode(png, image, w, h)) return false;

    lodepng::save_file(png, FilePath);
    remove(TempPath);

So my question is.. Is there a better way to do the above? Currently I dislike having to do memcpy on a vector tbh. But then again, I'm not sure of any other way to do it. I tried using an iterator but it errors out since I actually created the iterator and it points to nothing + sizeof(...). I cannot enter values instead for std::copy.. It requires a valid iterator.

Please help me?

I tried:

    std::vector<unsigned char> BmpBuffer(sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER) + Size());
    BmpBuffer.insert(BmpBuffer.end(), &bFileHeader, sizeof(BITMAPFILEHEADER));
    BmpBuffer.insert(BmpBuffer.end(), &Info.bmiHeader, sizeof(BITMAPINFOHEADER));
    BmpBuffer.insert(BmpBuffer.end(), TEMP.begin(), TEMP.end());

but I'm not sure if that'll work. Inother words, should I even construct the vector with a size first? Or just insert?

Recommended Answers

All 2 Replies

You can copy to a vector in a number of ways.

Use an iterator

    std::vector<unsigned char> out;
    unsigned char buff[1204] = {0};

    // ...

    std::copy (buff, buff + 1024, std::back_inserter(out));

Or, since vector elements are guaranteed to be stored contiguously in memory, you can asign directly to reserved memory

    std::vector<unsigned char> out(1024);
    unsigned char buff[1204] = {0};

    // ...

    std::copy (buff, buff + 1024, &out[0]);

These are just examples using a raw unsigned char buffer. You can get the same effect using any iterator and std::copy. In fact, you can even read directly from the file into the vector. Or to a stringstream and then to the vector.

The two examples above should suffice, however.

commented: PERFECT! +6

Perfect! I ended up doing:

std::copy(reinterpret_cast<unsigned char*>(&bFileHeader), reinterpret_cast<unsigned char*>(&bFileHeader) + sizeof(BITMAPFILEHEADER), BmpBuffer.begin());
//Etc.. etc..

Had to cast to get it to work. None the less, everything works fine now. Thank you lots!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.