00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef PNM_GROK_H
00022 #define PNM_GROK_H
00023
00024 #include <iostream>
00025 #include <string>
00026 #include <vector>
00027 #include <cvd/internal/convert_pixel_types.h>
00028 #include <cvd/image.h>
00029 #include <cvd/internal/load_and_save.h>
00030
00031 namespace CVD
00032 {
00033 namespace PNM
00034 {
00035 class pnm_in
00036 {
00037 public:
00038 pnm_in(std::istream&);
00039 bool is_2_byte()const {return m_is_2_byte;}
00040 int channels(){return m_channels;}
00041 long x_size() const {return xs;}
00042 long y_size() const {return ys;}
00043 long elements_per_line() const {return xs * m_channels;}
00044 void get_raw_pixel_lines(unsigned char*, unsigned long nlines);
00045 void get_raw_pixel_lines(unsigned short*, unsigned long nlines);
00046
00047
00048 private:
00049 std::istream& i;
00050 bool is_text;
00051 int type, maxval;
00052 int lines_so_far;
00053 void read_header();
00054 bool can_proc_lines(unsigned long);
00055 long xs, ys;
00056 bool m_is_2_byte;
00057 int m_channels;
00058 };
00059
00060 template <class T, class S, int N> struct PNMReader;
00061
00062 template <class T, class S> struct PNMReader<T,S,3>
00063 {
00064 typedef Rgb<S> array;
00065 static void readPixels(BasicImage<T>& im, pnm_in& pnm)
00066 {
00067 std::vector<array> rowbuf(pnm.x_size());
00068 for (int r=0; r<pnm.y_size(); r++)
00069 {
00070 pnm.get_raw_pixel_lines((S*) &(rowbuf[0]), 1);
00071 Pixel::ConvertPixels<array, T>::convert(&(rowbuf[0]), im[r], pnm.x_size());
00072 }
00073 }
00074 };
00075
00076 template <class T, class S> struct PNMReader<T,S,1>
00077 {
00078 static void readPixels(BasicImage<T>& im, pnm_in& pnm)
00079 {
00080 std::vector<S> rowbuf(pnm.x_size());
00081 for (int r=0; r<pnm.y_size(); r++)
00082 {
00083 pnm.get_raw_pixel_lines(&(rowbuf[0]), 1);
00084 Pixel::ConvertPixels<S, T>::convert(&(rowbuf[0]), im[r], pnm.x_size());
00085 }
00086 }
00087 };
00088
00089 template <> struct PNMReader<Rgb<byte>,byte,3>
00090 {
00091 static void readPixels(BasicImage<Rgb<byte> >& im, pnm_in& pnm)
00092 {
00093 pnm.get_raw_pixel_lines((byte*)im.data(), pnm.y_size());
00094 }
00095 };
00096
00097 template <> struct PNMReader<byte,byte,1>
00098 {
00099 static void readPixels(BasicImage<byte>& im, pnm_in& pnm)
00100 {
00101 pnm.get_raw_pixel_lines(im.data(), pnm.y_size());
00102 }
00103 };
00104
00105 template <> struct PNMReader<Rgb<unsigned short>,unsigned short,3>
00106 {
00107 static void readPixels(BasicImage<Rgb<unsigned short> >& im, pnm_in& pnm)
00108 {
00109 pnm.get_raw_pixel_lines((unsigned short*)im.data(), pnm.y_size());
00110 }
00111 };
00112
00113 template <> struct PNMReader<unsigned short,unsigned short,1>
00114 {
00115 static void readPixels(BasicImage<unsigned short>& im, pnm_in& pnm)
00116 {
00117 pnm.get_raw_pixel_lines(im.data(), pnm.y_size());
00118 }
00119 };
00120
00121 template <class T> void readPNM(BasicImage<T>& im, pnm_in& pnm)
00122 {
00123 if (pnm.is_2_byte())
00124 {
00125 if (pnm.channels() == 3)
00126 PNMReader<T,unsigned short,3>::readPixels(im, pnm);
00127 else
00128 PNMReader<T,unsigned short,1>::readPixels(im, pnm);
00129 }
00130 else
00131 {
00132 if (pnm.channels() == 3)
00133 PNMReader<T,unsigned char,3>::readPixels(im, pnm);
00134 else
00135 PNMReader<T,unsigned char,1>::readPixels(im, pnm);
00136 }
00137 }
00138
00139 template <class T> void readPNM(BasicImage<T>&im, std::istream& in)
00140 {
00141 pnm_in pnm(in);
00142 ImageRef size(pnm.x_size(), pnm.y_size());
00143
00144 if(size != im.size())
00145 throw Exceptions::Image_IO::ImageSizeMismatch(size, im.size());
00146
00147 readPNM(im, pnm);
00148
00149 }
00150
00151 template <class T> void readPNM(Image<T>&im, std::istream& in)
00152 {
00153 pnm_in pnm(in);
00154 im.resize(ImageRef(pnm.x_size(), pnm.y_size()));
00155 readPNM(im, pnm);
00156 }
00158
00159
00160
00161
00162 template<int isRgb, int isbyte> struct ComponentMapper { typedef Rgb<byte> type; };
00163 template<> struct ComponentMapper<1,0> { typedef Rgb<unsigned short> type; };
00164 template<> struct ComponentMapper<0,1> { typedef byte type; };
00165 template<> struct ComponentMapper<0,0> { typedef unsigned short type; };
00166
00167 class pnm_writer
00168 {
00169 public:
00170 pnm_writer(std::ostream&, ImageRef size, const std::string& type, const std::map<std::string, Parameter<> >& p);
00171 ~pnm_writer();
00172
00173
00174 void write_raw_pixel_line(const unsigned char*);
00175 void write_raw_pixel_line(const unsigned short*);
00176 void write_raw_pixel_line(const Rgb<unsigned char>*);
00177 void write_raw_pixel_line(const Rgb<unsigned short>*);
00178
00179 template<class Incoming> struct Outgoing
00180 {
00181 typedef typename Pixel::Component<Incoming>::type Element;
00182 typedef typename ComponentMapper<Pixel::is_Rgb<Incoming>::value,
00183 std::numeric_limits<Element>::is_integer &&
00184 std::numeric_limits<Element>::digits <= 8>::type type;
00185 };
00186 private:
00187
00188 template<class P> void sanity_check(const P*);
00189 void write_shorts(const unsigned short*, int n);
00190
00191 long row;
00192 std::ostream& o;
00193 ImageRef size;
00194 std::string type;
00195 };
00196
00197
00198 }
00199 }
00200 #endif