mirror of https://github.com/google/gemma.cpp.git
Add an overload of `Image::ReadPPM` method
Make it able to load image data from a stream.
This commit is contained in:
parent
a4d6adbc43
commit
a784b8459d
|
|
@ -55,14 +55,14 @@ float StretchToSigned(float value) {
|
||||||
|
|
||||||
bool IsLineBreak(int c) { return c == '\r' || c == '\n'; }
|
bool IsLineBreak(int c) { return c == '\r' || c == '\n'; }
|
||||||
|
|
||||||
void SkipWhitespaceAndComments(std::ifstream& file) {
|
void SkipWhitespaceAndComments(std::istream& in) {
|
||||||
int value = file.get();
|
int value = in.get();
|
||||||
while (std::isspace(value)) value = file.get();
|
while (std::isspace(value)) value = in.get();
|
||||||
while (value == '#') { // Skip comment lines.
|
while (value == '#') { // Skip comment lines.
|
||||||
while (!IsLineBreak(value)) value = file.get();
|
while (!IsLineBreak(value)) value = in.get();
|
||||||
while (std::isspace(value)) value = file.get();
|
while (std::isspace(value)) value = in.get();
|
||||||
}
|
}
|
||||||
file.unget(); // Rewind last byte.
|
in.unget(); // Rewind last byte.
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
@ -72,25 +72,37 @@ bool Image::ReadPPM(const std::string& filename) {
|
||||||
std::cerr << "Failed to open " << filename << "\n";
|
std::cerr << "Failed to open " << filename << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!ReadPPM(file)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (file.get() != EOF) {
|
||||||
|
std::cerr << "Extra data in file\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Image::ReadPPM(std::istream& in) {
|
||||||
std::string format;
|
std::string format;
|
||||||
file >> format;
|
in >> format;
|
||||||
if (format != "P6") {
|
if (format != "P6") {
|
||||||
std::cerr << "We only support binary PPM (P6) but got: " << format << "\n";
|
std::cerr << "We only support binary PPM (P6) but got: " << format << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
int width, height, max_value;
|
int width, height, max_value;
|
||||||
SkipWhitespaceAndComments(file);
|
SkipWhitespaceAndComments(in);
|
||||||
file >> width;
|
in >> width;
|
||||||
SkipWhitespaceAndComments(file);
|
SkipWhitespaceAndComments(in);
|
||||||
file >> height;
|
in >> height;
|
||||||
SkipWhitespaceAndComments(file);
|
SkipWhitespaceAndComments(in);
|
||||||
file >> max_value;
|
in >> max_value;
|
||||||
if (max_value <= 0 || max_value > 255) {
|
if (max_value <= 0 || max_value > 255) {
|
||||||
std::cerr << "Unsupported max value " << max_value << "\n";
|
std::cerr << "Unsupported max value " << max_value << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// P6 requires exactly one whitespace character after the header.
|
// P6 requires exactly one whitespace character after the header.
|
||||||
int value = file.get();
|
int value = in.get();
|
||||||
if (!std::isspace(value)) {
|
if (!std::isspace(value)) {
|
||||||
std::cerr << "Missing whitespace after header\n";
|
std::cerr << "Missing whitespace after header\n";
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -100,19 +112,14 @@ bool Image::ReadPPM(const std::string& filename) {
|
||||||
int data_size = width * height * 3;
|
int data_size = width * height * 3;
|
||||||
data_.resize(data_size);
|
data_.resize(data_size);
|
||||||
std::vector<uint8_t> data_bytes(data_size);
|
std::vector<uint8_t> data_bytes(data_size);
|
||||||
file.read(reinterpret_cast<char*>(data_bytes.data()), data_size);
|
in.read(reinterpret_cast<char*>(data_bytes.data()), data_size);
|
||||||
if (file.gcount() != data_size) {
|
if (in.gcount() != data_size) {
|
||||||
std::cerr << "Failed to read " << data_size << " bytes\n";
|
std::cerr << "Failed to read " << data_size << " bytes\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < data_size; ++i) {
|
for (int i = 0; i < data_size; ++i) {
|
||||||
data_[i] = StretchToSigned(static_cast<float>(data_bytes[i]) / max_value);
|
data_[i] = StretchToSigned(static_cast<float>(data_bytes[i]) / max_value);
|
||||||
}
|
}
|
||||||
if (file.get() != EOF) {
|
|
||||||
std::cerr << "Extra data in file\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
file.close();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <istream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace gcpp {
|
namespace gcpp {
|
||||||
|
|
@ -30,6 +31,9 @@ class Image {
|
||||||
// Reads a file in PPM format (P6, binary), normalizes to [-1, 1].
|
// Reads a file in PPM format (P6, binary), normalizes to [-1, 1].
|
||||||
// Returns true on success.
|
// Returns true on success.
|
||||||
bool ReadPPM(const std::string& filename);
|
bool ReadPPM(const std::string& filename);
|
||||||
|
// Reads PPM format (P6, binary) data from a stream, normalizes to [-1, 1].
|
||||||
|
// Returns true on success.
|
||||||
|
bool ReadPPM(std::istream& in);
|
||||||
// Resizes to 224x224 (nearest-neighbor for now, bilinear or antialias would
|
// Resizes to 224x224 (nearest-neighbor for now, bilinear or antialias would
|
||||||
// be better).
|
// be better).
|
||||||
void Resize();
|
void Resize();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue