rotate-me-fast/image.cpp
Fabien Freling 9dbaafece1 Add padding table.
We don't set the memory to 0 anymore, we'll use padding.
We can see artifacts in the background for now.
2014-08-05 22:16:10 +02:00

154 lines
2.4 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];
}
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;
}