c++ofstreamppm

Can I write single byte to a file without temporary variable?


I have a simple debug function that writes bytes to a file that will be displayed as image. It follows ppm format.

Originally, I used this:

static void SaveDebugImage(const std::string& filePath, const unsigned char* psdata, const int resolution)
{
  // Debug: print stored data in file
  std::ofstream file;
  file.open(filePath, std::ios::out | std::ios::binary);
  if (!file.is_open())
  {
    // Throws error and crashes the program on purpose
    RError("[ImageDebug::SaveDebugImage] Cannot write to %s", filePath.c_str());
  }

  file << "P6"
    << "\n"
    << resolution << "\n"
    << resolution << "\n"
    << "255"
    << "\n";

  const char zero = 0;
  for (int i = 0; i < resolution * resolution; ++i)
  {

    file.write(reinterpret_cast<const char*>(pxdata), sizeof(*pxdata));
    ++pxdata;
    file.write(reinterpret_cast<const char*>(pxdata), sizeof(*pxdata));
    ++pxdata;
    file.write(&zero, sizeof(zero));
    ++pxdata;
  }
  file.flush();
  file.close();
}

You can see it skips last byte of color, that's because the data are not strictly RGB image, but rather a meta information format. R, G and B channels mean something else than color. You can also observe the need for const char zero = 0 that I have to use to write zeros.

I now have a function on hand that really provides the surface color, it may look like this:

OurLibrary::Color getRealColor(byte r, byte g, byte b);

Now assuming this fictional Color class has a unsigned char getR() const method, how can I write the result to file without temporary variable. Now I have to do this:

OurLibrary::Color pixelColor(getRealColor( ... ));
const unsigned char colorR = pixelColor.getR();
file.write(reinterpret_cast<const char*>(&colorR), sizeof(colorR));

I would prefer:

file.write(pixelColor.getR());

Is there any such method? I couldn't find it in docs.


Solution

  • Per the documentation, put "inserts a character".

    So, simply:

    file.put(pixelColor.getR());
    

    (You may need to cast to char to avoid some narrowing-conversion warnings; not sure.)


    Also, that flush() is completely pointless. C++ streams flush on close.