Skip to content

Commit

Permalink
Move PNMI/O code over to the proper image loading system.
Browse files Browse the repository at this point in the history
Fix some minor edge case bugs.
  • Loading branch information
edrosten committed Nov 18, 2010
1 parent 9031088 commit 30241cb
Show file tree
Hide file tree
Showing 4 changed files with 625 additions and 590 deletions.
4 changes: 2 additions & 2 deletions cvd/image_io.h
Expand Up @@ -234,7 +234,7 @@ namespace CVD
throw Exceptions::Image_IO::EofBeforeImage(); throw Exceptions::Image_IO::EofBeforeImage();


if(c == 'P') if(c == 'P')
PNM::readPNM(im, i); CVD::Internal::readImage<I, PNM::Reader>(im, i);
#ifdef CVD_HAVE_JPEG #ifdef CVD_HAVE_JPEG
else if(c == 0xff) else if(c == 0xff)
CVD::Internal::readImage<I, JPEG::reader>(im, i); CVD::Internal::readImage<I, JPEG::reader>(im, i);
Expand Down Expand Up @@ -296,7 +296,7 @@ namespace CVD
case ImageType::PNM: case ImageType::PNM:
case ImageType::Automatic: case ImageType::Automatic:
case ImageType::Unknown: case ImageType::Unknown:
Internal::writeImage<PixelType, PNM::pnm_writer>(im, o, p); break; Internal::writeImage<PixelType, PNM::Writer>(im, o, p); break;
#ifdef CVD_HAVE_JPEG #ifdef CVD_HAVE_JPEG
case ImageType::JPEG: Internal::writeImage<PixelType, JPEG::writer>(im,o, p); break; case ImageType::JPEG: Internal::writeImage<PixelType, JPEG::writer>(im,o, p); break;
#endif #endif
Expand Down
159 changes: 34 additions & 125 deletions cvd/internal/io/pnm_grok.h
Expand Up @@ -32,128 +32,43 @@ namespace CVD
{ {
namespace PNM namespace PNM
{ {
class pnm_in class pnm_in;
{
using CVD::Internal::TypeList;
using CVD::Internal::Head;
class Reader
{
public: public:
pnm_in(std::istream&); Reader(std::istream&);
bool is_2_byte()const {return m_is_2_byte;} ~Reader();
int channels(){return m_channels;}
long x_size() const {return xs;} ImageRef size();
long y_size() const {return ys;}
long elements_per_line() const {return xs * m_channels;} void get_raw_pixel_line(bool*);
void get_raw_pixel_lines(unsigned char*, unsigned long nlines); void get_raw_pixel_line(unsigned char*);
void get_raw_pixel_lines(unsigned short*, unsigned long nlines); void get_raw_pixel_line(unsigned short*);

void get_raw_pixel_line(Rgb<unsigned char>*);

void get_raw_pixel_line(Rgb<unsigned short>*);

std::string datatype();
std::string name();

typedef TypeList<bool,
TypeList<byte,
TypeList<unsigned short,
TypeList<Rgb<byte>,
TypeList<Rgb<unsigned short>,
Head> > > > > Types;

private: private:
std::istream& i; std::auto_ptr<pnm_in> p;
bool is_text;
int type, maxval;
int lines_so_far;
void read_header();
bool can_proc_lines(unsigned long);
long xs, ys;
bool m_is_2_byte;
int m_channels;
};

template <class T, class S, int N> struct PNMReader;

template <class T, class S> struct PNMReader<T,S,3>
{
typedef Rgb<S> array;
static void readPixels(BasicImage<T>& im, pnm_in& pnm)
{
std::vector<array> rowbuf(pnm.x_size());
for (int r=0; r<pnm.y_size(); r++)
{
pnm.get_raw_pixel_lines((S*) &(rowbuf[0]), 1);
Pixel::ConvertPixels<array, T>::convert(&(rowbuf[0]), im[r], pnm.x_size());
}
}
}; };

template <class T, class S> struct PNMReader<T,S,1>
{
static void readPixels(BasicImage<T>& im, pnm_in& pnm)
{
std::vector<S> rowbuf(pnm.x_size());
for (int r=0; r<pnm.y_size(); r++)
{
pnm.get_raw_pixel_lines(&(rowbuf[0]), 1);
Pixel::ConvertPixels<S, T>::convert(&(rowbuf[0]), im[r], pnm.x_size());
}
}
};

template <> struct PNMReader<Rgb<byte>,byte,3>
{
static void readPixels(BasicImage<Rgb<byte> >& im, pnm_in& pnm)
{
pnm.get_raw_pixel_lines((byte*)im.data(), pnm.y_size());
}
};


template <> struct PNMReader<byte,byte,1>
{
static void readPixels(BasicImage<byte>& im, pnm_in& pnm)
{
pnm.get_raw_pixel_lines(im.data(), pnm.y_size());
}
};


template <> struct PNMReader<Rgb<unsigned short>,unsigned short,3>
{
static void readPixels(BasicImage<Rgb<unsigned short> >& im, pnm_in& pnm)
{
pnm.get_raw_pixel_lines((unsigned short*)im.data(), pnm.y_size());
}
};


template <> struct PNMReader<unsigned short,unsigned short,1>
{
static void readPixels(BasicImage<unsigned short>& im, pnm_in& pnm)
{
pnm.get_raw_pixel_lines(im.data(), pnm.y_size());
}
};

template <class T> void readPNM(BasicImage<T>& im, pnm_in& pnm)
{
if (pnm.is_2_byte())
{
if (pnm.channels() == 3)
PNMReader<T,unsigned short,3>::readPixels(im, pnm);
else
PNMReader<T,unsigned short,1>::readPixels(im, pnm);
}
else
{
if (pnm.channels() == 3)
PNMReader<T,unsigned char,3>::readPixels(im, pnm);
else
PNMReader<T,unsigned char,1>::readPixels(im, pnm);
}
}

template <class T> void readPNM(BasicImage<T>&im, std::istream& in)
{
pnm_in pnm(in);
ImageRef size(pnm.x_size(), pnm.y_size());


if(size != im.size())
throw Exceptions::Image_IO::ImageSizeMismatch(size, im.size());

readPNM(im, pnm);


}

template <class T> void readPNM(Image<T>&im, std::istream& in)
{
pnm_in pnm(in);
im.resize(ImageRef(pnm.x_size(), pnm.y_size()));
readPNM(im, pnm);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// //
// PNM writing. // PNM writing.
Expand All @@ -164,11 +79,12 @@ namespace CVD
template<> struct ComponentMapper<0,1> { typedef byte type; }; template<> struct ComponentMapper<0,1> { typedef byte type; };
template<> struct ComponentMapper<0,0> { typedef unsigned short type; }; template<> struct ComponentMapper<0,0> { typedef unsigned short type; };


class pnm_writer class pnm_writer;
class Writer
{ {
public: public:
pnm_writer(std::ostream&, ImageRef size, const std::string& type, const std::map<std::string, Parameter<> >& p); Writer(std::ostream&, ImageRef size, const std::string& type, const std::map<std::string, Parameter<> >& p);
~pnm_writer(); ~Writer();


//void write_raw_pixel_line(const bool*); //void write_raw_pixel_line(const bool*);
void write_raw_pixel_line(const unsigned char*); void write_raw_pixel_line(const unsigned char*);
Expand All @@ -184,14 +100,7 @@ namespace CVD
std::numeric_limits<Element>::digits <= 8>::type type; std::numeric_limits<Element>::digits <= 8>::type type;
}; };
private: private:

std::auto_ptr<pnm_writer> p;
template<class P> void sanity_check(const P*);
void write_shorts(const unsigned short*, int n);

long row;
std::ostream& o;
ImageRef size;
std::string type;
}; };




Expand Down

0 comments on commit 30241cb

Please sign in to comment.