0

I want to read a binary .pbm file. This is so far what I have:

void readPBMFile(const std::string& filePath, std::vector<std::vector<int>>& pixels) {
    std::ifstream file(filePath, std::ios::binary);

    std::string header;
    std::getline(file, header);

    if (header != "P4") {
        throw std::runtime_error("File is not in PBM format.");
    }

    int width, height;
    file >> width >> height;

    pixels.resize(height, std::vector<int>(width));

    // This is the part where I read the file data after the header
    for (int y = 0; y < height; ++y) {
        for (int x = 0; x < width; ++x) {
            unsigned char byte;
            file.read(reinterpret_cast<char*>(&byte), 1);
            int pixelValue = byte ? 1 : 0;
            pixels[y][x] = pixelValue;
        }
    }
}

And the save function:

void savePBMFile(const std::string& filePath, const std::vector<std::vector<int>>& pixels) {
    std::ofstream file(filePath, std::ios::binary);

    file << "P4\n";

    int width = pixels[0].size();
    int height = pixels.size();
    file << width << " " << height << "\n";

    for (const auto& row : pixels) {
        for (const auto& pixel : row) {
            unsigned char byte = pixel ? 1 : 0;
            file.write(reinterpret_cast<const char*>(&byte), 1);
        }
    }
}

But I ended with a strange image with correct white spaces and black vertical lines. The black areas are ignored. What am I doing wrong?

  • Don't mix formatted and unformatted reads/writes. Always use `read` and `write` functions to operate on binary files. – Evg Jun 12 '23 at 22:17
  • You can mix formatted input with `read` as long as you are careful. From what I remember about the P4 format there are two things that seem incorrect in this code. After the width and height there is a space character that is not being skipped before reading pixels. The pixels are packed bits so one bit == one pixel and one byte == 8 pixels. This code is seems to be treating each byte as one pixel, and since you're not checking the return value from `read` you could be trying to read past the end of the file and not know it. – Retired Ninja Jun 12 '23 at 22:41
  • Please read the [PBM P4 structure description](https://fejlesztek.hu/pbm-p4-image-file-format/) carefully. It looks like the data is given in bits, not in bytes. Please add a reference to a sample input image. [example.pbm](http://fejlesztek.hu/download/example.pbm) may be a good example. You may also limit the question to the simple case, where image width is a multiple of 8. – Rotem Jun 13 '23 at 21:26

0 Answers0