7e152c29fc
The code has been split into different source files. This breaks for now rotation for tiled images and PPM format. The focus is now on the PGM format.
155 lines
2.5 KiB
C++
155 lines
2.5 KiB
C++
#include "image.h"
|
|
#include "pnm.h"
|
|
|
|
Image::Image()
|
|
: width(0)
|
|
, height(0)
|
|
, buffer(NULL)
|
|
, pixel_size(0)
|
|
{}
|
|
|
|
Image::~Image()
|
|
{
|
|
delete [] buffer;
|
|
}
|
|
|
|
Image::Image(unsigned int w, unsigned int h, pnm::Format type)
|
|
{
|
|
this->width = w;
|
|
this->height = h;
|
|
this->type = type;
|
|
|
|
switch (this->type)
|
|
{
|
|
case pnm::Format::PGM:
|
|
{
|
|
this->pixel_size = 1;
|
|
}
|
|
break;
|
|
|
|
case pnm::Format::PPM:
|
|
{
|
|
this->pixel_size = 4;
|
|
}
|
|
break;
|
|
}
|
|
|
|
buffer = new pvalue_t[width * height * pixel_size];
|
|
memset(buffer, 0, width * height * pixel_size * sizeof (pvalue_t));
|
|
}
|
|
|
|
Image::Image(string const& path)
|
|
: Image()
|
|
{
|
|
ifstream is(path);
|
|
if (!is.is_open())
|
|
{
|
|
cerr << "Cannot open file '" << path << "'" << endl;
|
|
abort();
|
|
}
|
|
|
|
if (!pnm::read_header(is, this->type, this->width, this->height))
|
|
{
|
|
cerr << "Invalid header." << endl;
|
|
abort();
|
|
}
|
|
|
|
switch (this->type)
|
|
{
|
|
case pnm::Format::PGM:
|
|
{
|
|
this->pixel_size = 1;
|
|
}
|
|
break;
|
|
|
|
case pnm::Format::PPM:
|
|
{
|
|
this->pixel_size = 4;
|
|
}
|
|
break;
|
|
}
|
|
|
|
|
|
if (!this->read_body(is))
|
|
{
|
|
delete buffer;
|
|
buffer = nullptr;
|
|
|
|
cerr << "Invalid header." << endl;
|
|
abort();
|
|
}
|
|
}
|
|
|
|
bool Image::save(string const& path) const
|
|
{
|
|
ofstream os(path);
|
|
if (!os.is_open())
|
|
{
|
|
cerr << "Cannot open file '" << path << "'" << endl;
|
|
return false;
|
|
}
|
|
pnm::write_header(os, this->type, this->width, this->height);
|
|
this->write_body(os);
|
|
return true;
|
|
}
|
|
|
|
bool Image::read_body(std::ifstream& istr)
|
|
{
|
|
unsigned int const nb_pixels = width * height;
|
|
buffer = new pvalue_t[nb_pixels * pixel_size];
|
|
|
|
pvalue_t* pixel = buffer;
|
|
for (unsigned int i = 0; i < nb_pixels; ++i)
|
|
{
|
|
switch (this->type)
|
|
{
|
|
case pnm::Format::PGM:
|
|
{
|
|
pixel[0] = istr.get();
|
|
}
|
|
break;
|
|
|
|
case pnm::Format::PPM:
|
|
{
|
|
pixel[0] = istr.get();
|
|
pixel[1] = istr.get();
|
|
pixel[2] = istr.get();
|
|
}
|
|
break;
|
|
}
|
|
|
|
pixel += pixel_size;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool Image::write_body(std::ofstream& ostr) const
|
|
{
|
|
unsigned int const nb_pixels = width * height;
|
|
pvalue_t* pixel = buffer;
|
|
for (unsigned int i = 0; i < nb_pixels; ++i)
|
|
{
|
|
switch (this->type)
|
|
{
|
|
case pnm::Format::PGM:
|
|
{
|
|
ostr << (char) pixel[0];
|
|
}
|
|
break;
|
|
|
|
case pnm::Format::PPM:
|
|
{
|
|
ostr << (char) pixel[0];
|
|
ostr << (char) pixel[1];
|
|
ostr << (char) pixel[2];
|
|
}
|
|
break;
|
|
}
|
|
|
|
pixel += pixel_size;
|
|
}
|
|
|
|
return true;
|
|
}
|