Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

image.h

Go to the documentation of this file.
00001 #ifndef fl_image_h
00002 #define fl_image_h
00003 
00004 
00005 #include "fl/pointer.h"
00006 
00007 #include <iostream>
00008 #include <string>
00009 #include <vector>
00010 
00011 
00012 namespace fl
00013 {
00014   // Forward declaration for use by Image
00015   class PixelFormat;
00016   class Pixel;
00017   class ImageFileFormat;
00018   
00019 
00020   // Image --------------------------------------------------------------------
00021 
00022   class Image
00023   {
00024   public:
00025         Image ();  
00026         Image (const PixelFormat & format);  
00027         Image (int width, int height);  
00028         Image (int width, int height, const PixelFormat & format);  
00029         Image (const Image & that);  
00030         Image (unsigned char * buffer, int width, int height, const PixelFormat & format);  
00031         Image (const std::string & fileName);  
00032 
00033         void read (const std::string & fileName);  
00034         void read (std::istream & stream);
00035         void write (const std::string & fileName, const std::string & formatName = "pgm") const;  
00036         void write (std::ostream & stream, const std::string & formatName = "pgm") const;
00037 
00038         Image & operator <<= (const Image & that);  
00039         void copyFrom (const Image & that);  
00040         void copyFrom (unsigned char * buffer, int width, int height, const PixelFormat & format);  
00041         void attach (unsigned char * buffer, int width, int height, const PixelFormat & format);  
00042         void detach ();  
00043 
00044         void resize (int width, int height);  
00045         void bitblt (const Image & that, int toX = 0, int toY = 0, int fromX = 0, int fromY = 0, int width = -1, int height = -1);  
00046         void clear (unsigned int rgba = 0);  
00047 
00048         Image operator + (const Image & that);  
00049         Image operator - (const Image & that);  
00050         Image operator * (double factor);  
00051         Image & operator *= (double factor);  
00052         Image & operator += (double value);  
00053 
00054         Pixel         operator () (int x, int y) const;  
00055         unsigned int  getRGBA  (int x, int y) const;  
00056         void          getRGBA  (int x, int y, float values[]) const;
00057         unsigned int  getYUV   (int x, int y) const;
00058         unsigned char getGray  (int x, int y) const;
00059         void          getGray  (int x, int y, float & gray) const;
00060         unsigned char getAlpha (int x, int y) const;
00061         void          setRGBA  (int x, int y, unsigned int rgba);  
00062         void          setRGBA  (int x, int y, float values[]);
00063         void          setYUV   (int x, int y, unsigned int yuv);
00064         void          setGray  (int x, int y, unsigned char gray);
00065         void          setGray  (int x, int y, float gray);
00066         void          setAlpha (int x, int y, unsigned char alpha);
00067 
00068         // Data
00069         Pointer             buffer;
00070         const PixelFormat * format;
00071         int                 width;  
00072         int                 height;  
00073         double              timestamp;  
00074   };
00075 
00079   template<class T>
00080   class ImageOf : public Image
00081   {
00082   public:
00083         // These constructors blindly wrap the constructors of Image, without
00084         // regard to the size or type of data returned by operator (x,y).
00085         ImageOf () {}
00086         ImageOf (const PixelFormat & format) : Image (format) {}
00087         ImageOf (int width, int height) : Image (width, height) {}
00088         ImageOf (int width, int height, const PixelFormat & format) : Image (width, height, format) {}
00089         ImageOf (const Image & that) : Image (that) {}
00090 
00091         T & operator () (int x, int y) const
00092         {
00093           return ((T *) buffer)[y * width + x];
00094         }
00095   };
00096 
00097 
00098   // Filter -------------------------------------------------------------------
00099 
00104   class Filter
00105   {
00106   public:
00107         virtual Image filter (const Image & image) = 0;  
00108   };
00109 
00110   inline Image
00111   operator * (const Filter & filter, const Image & image)
00112   {
00113         // We lie about Filter being const.  This allows you to construct a Filter
00114         // object right in the middle of an expression without getting complaints
00115         // from the compiler.  Ditto for the other operators below.
00116         return ((Filter &) filter).filter (image);
00117   }
00118 
00119   inline Image
00120   operator * (const Image & image, const Filter & filter)
00121   {
00122         return ((Filter &) filter).filter (image);
00123   }
00124 
00125   inline Image &
00126   operator *= (Image & image, const Filter & filter)
00127   {
00128         return image = image * ((Filter &) filter);
00129   }
00130 
00131 
00132   // PixelFormat --------------------------------------------------------------
00133 
00163   class PixelFormat : public Filter
00164   {
00165   public:
00166         virtual Image filter (const Image & image);  
00167         void fromAny (const Image & image, Image & result) const;
00168 
00169         virtual bool operator == (const PixelFormat & that) const;  
00170         bool operator != (const PixelFormat & that) const
00171         {
00172           return ! operator == (that);
00173         }
00174 
00175         virtual unsigned int  getRGBA  (void * pixel) const = 0;  
00176         virtual void          getRGBA  (void * pixel, float values[]) const;  
00177         virtual void          getXYZ   (void * pixel, float values[]) const;
00178         virtual unsigned int  getYUV   (void * pixel) const;
00179         virtual unsigned char getGray  (void * pixel) const;
00180         virtual void          getGray  (void * pixel, float & gray) const;
00181         virtual unsigned char getAlpha (void * pixel) const;  
00182         virtual void          setRGBA  (void * pixel, unsigned int rgba) const = 0;
00183         virtual void          setRGBA  (void * pixel, float values[]) const;  
00184         virtual void          setXYZ   (void * pixel, float values[]) const;
00185         virtual void          setYUV   (void * pixel, unsigned int yuv) const;
00186         virtual void          setGray  (void * pixel, unsigned char gray) const;
00187         virtual void          setGray  (void * pixel, float gray) const;
00188         virtual void          setAlpha (void * pixel, unsigned char alpha) const;  
00189 
00190         int depth;  
00191         int precedence;  
00192         // The following two flags could be implemented several different ways.
00193         // One alternative would be to make a more complicated class hierarchy
00194         // that implies the information.  Eg: have intermediate classes
00195         // PixelFormatMonochrome and PixelFormatColor.  Another alternative is
00196         // to put channel information into a bitmap and use masks to determine
00197         // various states.
00198         bool monochrome;  
00199         bool hasAlpha;  
00200   };
00201 
00202   class PixelFormatGrayChar : public PixelFormat
00203   {
00204   public:
00205         PixelFormatGrayChar ();
00206 
00207         virtual Image filter (const Image & image);
00208         void fromGrayFloat  (const Image & image, Image & result) const;
00209         void fromGrayDouble (const Image & image, Image & result) const;
00210         void fromRGBAChar   (const Image & image, Image & result) const;
00211         void fromRGBABits   (const Image & image, Image & result) const;
00212         void fromAny        (const Image & image, Image & result) const;
00213 
00214         virtual unsigned int  getRGBA (void * pixel) const;
00215         virtual void          getXYZ  (void * pixel, float values[]) const;
00216         virtual unsigned char getGray (void * pixel) const;
00217         virtual void          getGray (void * pixel, float & gray) const;
00218         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00219         virtual void          setXYZ  (void * pixel, float values[]) const;
00220         virtual void          setGray (void * pixel, unsigned char gray) const;
00221         virtual void          setGray (void * pixel, float gray) const;
00222   };
00223 
00224   class PixelFormatGrayFloat : public PixelFormat
00225   {
00226   public:
00227         PixelFormatGrayFloat ();
00228 
00229         virtual Image filter (const Image & image);
00230         void fromGrayChar   (const Image & image, Image & result) const;
00231         void fromGrayDouble (const Image & image, Image & result) const;
00232         void fromRGBAChar   (const Image & image, Image & result) const;
00233         void fromRGBABits   (const Image & image, Image & result) const;
00234         void fromAny        (const Image & image, Image & result) const;
00235 
00236         virtual unsigned int  getRGBA (void * pixel) const;
00237         virtual void          getRGBA (void * pixel, float values[]) const;
00238         virtual void          getXYZ  (void * pixel, float values[]) const;
00239         virtual unsigned char getGray (void * pixel) const;
00240         virtual void          getGray (void * pixel, float & gray) const;
00241         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00242         virtual void          setRGBA (void * pixel, float values[]) const;
00243         virtual void          setXYZ  (void * pixel, float values[]) const;
00244         virtual void          setGray (void * pixel, unsigned char gray) const;
00245         virtual void          setGray (void * pixel, float gray) const;
00246   };
00247 
00248   class PixelFormatGrayDouble : public PixelFormat
00249   {
00250   public:
00251         PixelFormatGrayDouble ();
00252 
00253         virtual Image filter (const Image & image);
00254         void fromGrayChar  (const Image & image, Image & result) const;
00255         void fromGrayFloat (const Image & image, Image & result) const;
00256         void fromRGBAChar  (const Image & image, Image & result) const;
00257         void fromRGBABits  (const Image & image, Image & result) const;
00258         void fromAny       (const Image & image, Image & result) const;
00259 
00260         virtual unsigned int  getRGBA (void * pixel) const;
00261         virtual void          getRGBA (void * pixel, float values[]) const;
00262         virtual void          getXYZ  (void * pixel, float values[]) const;
00263         virtual unsigned char getGray (void * pixel) const;
00264         virtual void          getGray (void * pixel, float & gray) const;
00265         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00266         virtual void          setRGBA (void * pixel, float values[]) const;
00267         virtual void          setXYZ  (void * pixel, float values[]) const;
00268         virtual void          setGray (void * pixel, unsigned char gray) const;
00269         virtual void          setGray (void * pixel, float gray) const;
00270   };
00271 
00272   class PixelFormatRGBAChar : public PixelFormat
00273   {
00274   public:
00275         PixelFormatRGBAChar ();
00276 
00277         virtual Image filter (const Image & image);
00278         void fromGrayChar   (const Image & image, Image & result) const;
00279         void fromGrayFloat  (const Image & image, Image & result) const;
00280         void fromGrayDouble (const Image & image, Image & result) const;
00281         void fromRGBABits   (const Image & image, Image & result) const;
00282 
00283         virtual bool operator == (const PixelFormat & that) const;
00284 
00285         virtual unsigned int  getRGBA  (void * pixel) const;
00286         virtual unsigned char getAlpha (void * pixel) const;
00287         virtual void          setRGBA  (void * pixel, unsigned int rgba) const;
00288         virtual void          setAlpha (void * pixel, unsigned char alpha) const;
00289 
00290         static void shift (unsigned int redMask, unsigned int greenMask, unsigned int blueMask, unsigned int alphaMask, int & redShift, int & greenShift, int & blueShift, int & alphaShift);  
00291   };
00292 
00293   class PixelFormatRGBABits : public PixelFormat
00294   {
00295   public:
00296         PixelFormatRGBABits (int depth, unsigned int redMask, unsigned int greenMask, unsigned int blueMask, unsigned int alphaMask);
00297 
00298         virtual Image filter (const Image & image);
00299         void fromGrayChar   (const Image & image, Image & result) const;
00300         void fromGrayFloat  (const Image & image, Image & result) const;
00301         void fromGrayDouble (const Image & image, Image & result) const;
00302         void fromRGBAChar   (const Image & image, Image & result) const;
00303         void fromRGBABits   (const Image & image, Image & result) const;
00304 
00305         virtual bool operator == (const PixelFormat & that) const;
00306 
00307         virtual unsigned int  getRGBA  (void * pixel) const;
00308         virtual unsigned char getAlpha (void * pixel) const;
00309         virtual void          setRGBA  (void * pixel, unsigned int rgba) const;
00310         virtual void          setAlpha (void * pixel, unsigned char alpha) const;
00311 
00312         void shift (unsigned int redMask, unsigned int greenMask, unsigned int blueMask, unsigned int alphaMask, int & redShift, int & greenShift, int & blueShift, int & alphaShift) const;
00313 
00314         unsigned int redMask;
00315         unsigned int greenMask;
00316         unsigned int blueMask;
00317         unsigned int alphaMask;
00318   };
00319 
00320   class PixelFormatRGBAFloat : public PixelFormat
00321   {
00322   public:
00323         PixelFormatRGBAFloat ();
00324 
00325         virtual unsigned int  getRGBA  (void * pixel) const;
00326         virtual void          getRGBA  (void * pixel, float values[]) const;
00327         virtual unsigned char getAlpha (void * pixel) const;
00328         virtual void          setRGBA  (void * pixel, unsigned int rgba) const;
00329         virtual void          setRGBA  (void * pixel, float values[]) const;
00330         virtual void          setAlpha (void * pixel, unsigned char alpha) const;
00331   };
00332 
00339   class PixelFormatYVYUChar : public PixelFormat
00340   {
00341   public:
00342         PixelFormatYVYUChar ();
00343 
00344         virtual Image filter (const Image & image);
00345         void fromVYUYChar (const Image & image, Image & result) const;
00346 
00347         virtual unsigned int  getRGBA (void * pixel) const;
00348         virtual unsigned int  getYUV  (void * pixel) const;
00349         virtual unsigned char getGray (void * pixel) const;
00350         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00351         virtual void          setYUV  (void * pixel, unsigned int yuv) const;
00352   };
00353 
00354   // Same as YVYU, but with different ordering within the word
00355   class PixelFormatVYUYChar : public PixelFormat
00356   {
00357   public:
00358         PixelFormatVYUYChar ();
00359 
00360         virtual Image filter (const Image & image);
00361         void fromYVYUChar (const Image & image, Image & result) const;
00362 
00363         virtual unsigned int  getRGBA (void * pixel) const;
00364         virtual unsigned int  getYUV  (void * pixel) const;
00365         virtual unsigned char getGray (void * pixel) const;
00366         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00367         virtual void          setYUV  (void * pixel, unsigned int yuv) const;
00368   };
00369 
00370   class PixelFormatHLSFloat : public PixelFormat
00371   {
00372   public:
00373         PixelFormatHLSFloat ();
00374 
00375         virtual unsigned int  getRGBA (void * pixel) const;
00376         virtual void          getRGBA (void * pixel, float values[]) const;
00377         virtual void          setRGBA (void * pixel, unsigned int rgba) const;
00378         virtual void          setRGBA (void * pixel, float values[]) const;
00379 
00380         float HLSvalue (const float & n1, const float & n2, float h) const;  
00381   };
00382 
00383   extern PixelFormatGrayChar   GrayChar;
00384   extern PixelFormatGrayFloat  GrayFloat;
00385   extern PixelFormatGrayDouble GrayDouble;
00386   extern PixelFormatRGBAChar   RGBAChar;
00387   extern PixelFormatRGBABits   BGRChar;  
00388   extern PixelFormatRGBABits   ABGRChar;  
00389   extern PixelFormatRGBAFloat  RGBAFloat;
00390   extern PixelFormatYVYUChar   YVYUChar;
00391   extern PixelFormatVYUYChar   VYUYChar;
00392   extern PixelFormatHLSFloat   HLSFloat;
00393 
00394   // Naming convention for RGBBits (other than BGRChar):
00395   // R<red bits>G<green bits>B<blue bits>
00396   // EG: R5G5B5 would be a 15 bit RGB format.
00397 
00398 
00399   // Pixel --------------------------------------------------------------------
00400 
00431   class Pixel
00432   {
00433   public:
00434         Pixel ();
00435         Pixel (unsigned int rgba);
00436         Pixel (const Pixel & that);
00437         Pixel (const PixelFormat & format, void * pixel);
00438 
00439         unsigned int getRGBA () const;
00440         void         getRGBA (float values[]) const;
00441         void         getXYZ  (float values[]) const;
00442         void         setRGBA (unsigned int rgba) const;
00443         void         setRGBA (float values[]) const;
00444         void         setXYZ  (float values[]) const;
00445 
00446         Pixel & operator = (const Pixel & that);  
00447         Pixel & operator += (const Pixel & that);  
00448         Pixel operator + (const Pixel & that) const;  
00449         Pixel operator * (const Pixel & that) const;  
00450         Pixel operator * (float scalar) const;  
00451         Pixel operator / (float scalar) const;  
00452         Pixel operator << (const Pixel & that);  
00453 
00454         const PixelFormat * format;
00455         void * pixel;  
00456 
00457         // This union is rather gross, and it would be nice not carry the baggage
00458         // around.  However, this is cheaper than allocating a small piece on the
00459         // heap.  Since Pixel is mainly intended to allow linear ops on abstract
00460         // image elements, it will frequently need its own storage (for
00461         // intermediate values) as opposed to referrencing an Image buffer.
00462         // "Frequently" means in the middle of an O(n^3) loop where n is the width
00463         // or height of an Image.
00464         union
00465         {
00466           unsigned char graychar;
00467           float         grayfloat;
00468           double        graydouble;
00469           unsigned int  rgbchar;
00470           float         rgbafloat[4];
00471         } data;
00472   };
00473 
00474 
00475   // File formats -------------------------------------------------------------
00476 
00485   class ImageFileFormat
00486   {
00487   public:
00488         ImageFileFormat ();
00489         virtual ~ImageFileFormat ();
00490 
00491         virtual void read (const std::string & fileName, Image & image) const;
00492         virtual void read (std::istream & stream, Image & image) const = 0;
00493         virtual void write (const std::string & fileName, const Image & image) const;
00494         virtual void write (std::ostream & stream, const Image & image) const = 0;
00495         virtual bool isIn (std::istream & stream) const = 0;  
00496         virtual bool handles (const std::string & formatName) const = 0;  
00497 
00498         static ImageFileFormat * find (const std::string & fileName);  
00499         static ImageFileFormat * find (std::istream & stream);  
00500         static ImageFileFormat * findName (const std::string & formatName);  
00501         static void getMagic (std::istream & stream, std::string & magic);  
00502 
00503         static std::vector<ImageFileFormat *> formats;
00504   };
00505 
00506   class ImageFileFormatPGM : public ImageFileFormat
00507   {
00508   public:
00509         virtual void read (std::istream & stream, Image & image) const;
00510         virtual void write (std::ostream & stream, const Image & image) const;
00511         virtual bool isIn (std::istream & stream) const;
00512         virtual bool handles (const std::string & formatName) const;
00513   };
00514 
00515   class ImageFileFormatEPS : public ImageFileFormat
00516   {
00517   public:
00518         virtual void read (std::istream & stream, Image & image) const;
00519         virtual void write (std::ostream & stream, const Image & image) const;
00520         virtual bool isIn (std::istream & stream) const;
00521         virtual bool handles (const std::string & formatName) const;
00522   };
00523 
00524   class ImageFileFormatJPEG : public ImageFileFormat
00525   {
00526   public:
00527         virtual void read (std::istream & stream, Image & image) const;
00528         virtual void write (std::ostream & stream, const Image & image) const;
00529         virtual bool isIn (std::istream & stream) const;
00530         virtual bool handles (const std::string & formatName) const;
00531   };
00532 
00533   class ImageFileFormatTIFF : public ImageFileFormat
00534   {
00535   public:
00536         // Note: This format can't read and write streams, so those two methods
00537         // will throw an exception.
00538         virtual void read (const std::string & fileName, Image & image) const;
00539         virtual void read (std::istream & stream, Image & image) const;
00540         virtual void write (const std::string & fileName, const Image & image) const;
00541         virtual void write (std::ostream & stream, const Image & image) const;
00542         virtual bool isIn (std::istream & stream) const;
00543         virtual bool handles (const std::string & formatName) const;
00544   };
00545 
00546   class ImageFileFormatMatlab : public ImageFileFormat
00547   {
00548   public:
00549         virtual void read (std::istream & stream, Image & image) const;
00550         virtual void write (std::ostream & stream, const Image & image) const;
00551         virtual bool isIn (std::istream & stream) const;
00552         virtual bool handles (const std::string & formatName) const;
00553         void parseType (int type, int & numericType) const;
00554   };
00555 
00556 
00557   // Image inlines ------------------------------------------------------------
00558 
00559   inline Image &
00560   Image::operator <<= (const Image & that)
00561   {
00562         buffer    = that.buffer;
00563         format    = that.format;
00564         width     = that.width;
00565         height    = that.height;
00566         timestamp = that.timestamp;
00567         return *this;
00568   }
00569 
00570   inline Pixel
00571   Image::operator () (int x, int y) const
00572   {
00573         return Pixel (*format, & ((char *) buffer)[(y * width + x) * format->depth]);
00574   }
00575 
00576   inline void
00577   Image::getRGBA (int x, int y, float values[]) const
00578   {
00579         format->getRGBA (& ((char *) buffer)[(y * width + x) * format->depth], values);
00580   }
00581 
00582   inline unsigned int
00583   Image::getYUV (int x, int y) const
00584   {
00585         return format->getYUV (& ((char *) buffer)[(y * width + x) * format->depth]);
00586   }
00587 
00588   inline unsigned char
00589   Image::getGray (int x, int y) const
00590   {
00591         return format->getGray (& ((char *) buffer)[(y * width + x) * format->depth]);
00592   }
00593 
00594   inline void
00595   Image::getGray (int x, int y, float & gray) const
00596   {
00597         format->getGray (& ((char *) buffer)[(y * width + x) * format->depth], gray);
00598   }
00599 
00600   inline unsigned char
00601   Image::getAlpha (int x, int y) const
00602   {
00603         return format->getAlpha (& ((char *) buffer)[(y * width + x) * format->depth]);
00604   }
00605 
00606   inline void
00607   Image::setRGBA (int x, int y, float values[])
00608   {
00609         format->setRGBA (& ((char *) buffer)[(y * width + x) * format->depth], values);
00610   }
00611 
00612   inline void
00613   Image::setYUV (int x, int y, unsigned int yuv)
00614   {
00615         format->setYUV (& ((char *) buffer)[(y * width + x) * format->depth], yuv);
00616   }
00617 
00618   inline void
00619   Image::setGray (int x, int y, unsigned char gray)
00620   {
00621         format->setGray (& ((char *) buffer)[(y * width + x) * format->depth], gray);
00622   }
00623 
00624   inline void
00625   Image::setGray (int x, int y, float gray)
00626   {
00627         format->setGray (& ((char *) buffer)[(y * width + x) * format->depth], gray);
00628   }
00629 
00630   inline void
00631   Image::setAlpha (int x, int y, unsigned char alpha)
00632   {
00633         format->setAlpha (& ((char *) buffer)[(y * width + x) * format->depth], alpha);
00634   }
00635 }
00636 
00637 
00638 #endif

Generated on Thu Dec 9 17:13:24 2004 for fl by doxygen1.2.18