blob: 2411888c5d95cb32432c7ddeb4122e1324d9c476 [file] [log] [blame]
#define LOG_TAG "ImageIo"
#include <private/dvr/image_io_ppm.h>
#include <cwctype>
#include <fstream>
#include <string>
#include <private/dvr/image_io_logging.h>
bool ImageIoPpmWriter::WriteRgb888() {
std::ofstream out(filename_);
if (!out) {
ALOGE("Failed to open output file %s.", filename_.c_str());
return false;
}
// Write a PPM header. See http://netpbm.sourceforge.net/doc/ppm.html for
// the format specification.
constexpr int maximum_intensity = 255;
out << "P6\n"
<< width_ << "\n"
<< height_ << "\n"
<< maximum_intensity << "\n";
// Write out the image itself.
out.write(reinterpret_cast<const char*>(image_), 3 * width_ * height_);
if (!out) {
ALOGE("Failed to write .ppm image to %s.", filename_.c_str());
return false;
}
return true;
}
bool ImageIoPpmReader::ReadRgb888() {
std::ifstream in(filename_);
if (!in) {
ALOGE("Failed to open input file %s.", filename_.c_str());
return false;
}
// Read PPM header. See http://netpbm.sourceforge.net/doc/ppm.html for
// the format specification.
char magic_number[2];
in.read(magic_number, 2);
if (magic_number[0] != 'P' || magic_number[1] != '6') {
ALOGE("Failed to read PPM, not a P6 file %s.", filename_.c_str());
return false;
}
int maximum_intensity = 0;
in >> width_;
in >> height_;
in >> maximum_intensity;
char delimiter;
in.read(&delimiter, 1);
if (!iswspace(delimiter) || width_ <= 0 || height_ <= 0 ||
maximum_intensity <= 0) {
ALOGE("Failed to parse PPM header for %s.", filename_.c_str());
return false;
}
if (maximum_intensity != 255) {
ALOGE("Failed to read PPM, only 8-bit depth supported %s.",
filename_.c_str());
return false;
}
// Read RGB data.
const int data_begin = in.tellg();
in.seekg(0, in.end);
const int data_end = in.tellg();
in.seekg(data_begin, in.beg);
const int data_size = data_end - data_begin;
if (data_size != 3 * width_ * height_) {
ALOGE("Failed to read PPM, unexpected data size %s.", filename_.c_str());
return false;
}
image_.reset(new uint8_t[data_size]);
char* data = reinterpret_cast<char*>(image_.get());
const auto it_data_begin = std::istreambuf_iterator<char>(in);
const auto it_data_end = std::istreambuf_iterator<char>();
std::copy(it_data_begin, it_data_end, data);
return true;
}