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
00015 class PixelFormat;
00016 class Pixel;
00017 class ImageFileFormat;
00018
00019
00020
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
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
00084
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
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
00114
00115
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
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
00193
00194
00195
00196
00197
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
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
00395
00396
00397
00398
00399
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
00458
00459
00460
00461
00462
00463
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
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
00537
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
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