| TP1 : Échantillonnage et aliasing 
 Fichier : 2007/TP/bitmap.h #ifndef __bitmap_h__
#define __bitmap_h__
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <assert.h>
#ifdef LINUX
#  define SHOW(_S) system("kv " _S " || xv " _S);
#else
#  define SHOW(_S) system(_S);
#endif
#define SAVE_AND_SHOW(_I,_S) _I.saveFile(_S);SHOW(_S);
/*********************************************************************
 * RGB & OPERATORS
 *********************************************************************/
template <typename T=unsigned char> struct RGB {
  T R,G,B;
  template<typename U> RGB<T> operator = (RGB<U> X){
    R=X.R;
    G=X.G;
    B=X.B;
    return *this;
  };
  RGB<T> operator + (){
    return *this;
  };
  RGB<T> operator - (){
    R=-R;
    G=-G;
    B=-B;
    return *this;
  };
  template<typename U> RGB<T> operator + (RGB<U> X){
    RGB<T> Y={R+X.R,G+X.G,B+X.B};
    return Y;
  };
  template<typename U> RGB<T> operator - (RGB<U> X){
    RGB<T> Y={R-X.R,G-X.G,B-X.B};
    return Y;
  };
  template<typename U> RGB<T> operator * (U K){
    RGB<T> Y={R*K,G*K,B*K};
    return Y;
  };
  template<typename U> RGB<T> operator * (RGB<U> X){
    RGB<T> Y={R*X.R,G*X.G,B*X.B};
    return Y;
  };
  template<typename U> RGB<T> operator / (U K){
    RGB<T> Y={R/K,G/K,B/K};
    return Y;
  };
  template<typename U> RGB<T> operator / (RGB<U> X){
    RGB<T> Y={R/X.R,G/X.G,B/X.B};
    return Y;
  };
  template<typename U> RGB<T> operator += (RGB<U> X){
    R+=X.R;
    G+=X.G;
    B+=X.B;
    return *this;
  };
  template<typename U> RGB<T> operator -= (RGB<U> X){
    R-=X.R;
    G-=X.G;
    B-=X.B;
    return *this;
  };
  template<typename U> RGB<T> operator *= (U K){
    R*=K;
    G*=K;
    B*=K;
    return *this;
  };
  template<typename U> RGB<T> operator *= (RGB<U> X){
    R*=X.R;
    G*=X.G;
    B*=X.B;
    return *this;
  };
  template<typename U> RGB<T> operator /= (U K){
    R/=K;
    G/=K;
    B/=K;
    return *this;
  };
  template<typename U> RGB<T> operator /= (RGB<U> X){
    R/=X.R;
    G/=X.G;
    B/=X.B;
    return *this;
  };
};
template<typename T,typename U> RGB<U> operator * (T K,RGB<U> X){
  RGB<U> Y={X.R*K,X.G*K,X.B*K};
  return Y;
};
template<typename T> RGB<T> rgb(T r,T g,T b){
  RGB<T> x={r,g,b};
  return x;
};
template<typename T> RGB<T> gray(T value){
  RGB<T> x={value,value,value};
  return x;
};
RGB<int> black()  {return rgb(0x00,0x00,0x00);};
RGB<int> white()  {return rgb(0xFF,0xFF,0xFF);};
RGB<int> red()    {return rgb(0xFF,0x00,0x00);};
RGB<int> green()  {return rgb(0x00,0xFF,0x00);};
RGB<int> blue()   {return rgb(0x00,0x00,0xFF);};
RGB<int> yellow() {return rgb(0xFF,0xFF,0x00);};
RGB<int> cyan()   {return rgb(0x00,0xFF,0xFF);};
RGB<int> violet() {return rgb(0xFF,0x00,0xFF);};
/*********************************************************************
 * CLASS BITMAP
 *********************************************************************/
#pragma pack(push,1)
struct bitmapheader{
  unsigned long int Size;
  long int Width;
  long int Height;
  unsigned short int Planes;
  unsigned short int BitCount;
  unsigned long int Compression;
  unsigned long int SizeImage;
  long int XPelsPerMeter;
  long int YPelsPerMeter;
  unsigned long int ClrUsed;
  unsigned long int ClrImportant;
};
struct bitmapfileheader{
  char Tag[2];
  unsigned long int Size;
  unsigned long int Reserved;
  unsigned long int DataOffset;
  struct bitmapheader Header;
};
#pragma pack(pop)
template <typename T=unsigned char> class Bitmap {
  public:
    typedef struct RGB<T> RGB;
  private:
    int ModMirror(int x,const int l) const {
      if (x<0)
        x=-x;
      x=x % (2*l-1);
      if (x>=l)
        x=2*l-2-x;
      assert(x>=0 && x<l);
      return x;
    };
    int align32(const int x) const {
      int y=x % 4;
      return y?x+(4-y):x;
    };
  protected:
    int Width,Height;
    RGB *Pixels;
  public:
    Bitmap(){
      Pixels=NULL;
    };
    Bitmap(char *filename){
      Pixels=NULL;
      loadFile(filename);
    };
    Bitmap(const int size){
      Pixels=NULL;
      setSize(size,size);
    };
    Bitmap(const int width,const int height){
      Pixels=NULL;
      setSize(width,height);
    };
    ~Bitmap(){
      if (Pixels!=NULL) free(Pixels);
    };
    RGB* getData(){
      return Pixels;
    }
    RGB &operator()(int x,int y){
      return Pixels[ModMirror(x,Width)+ModMirror(y,Height)*Width];
    };
    RGB rgb(T r,T g,T b) const{
      RGB x={r,g,b};
      return x;
    };
    RGB gray(T value) const{
      RGB x={value,value,value};
      return x;
    };
    RGB black()  const{return rgb(0x00,0x00,0x00);};
    RGB white()  const{return rgb(0xFF,0xFF,0xFF);};
    RGB red()    const{return rgb(0xFF,0x00,0x00);};
    RGB green()  const{return rgb(0x00,0xFF,0x00);};
    RGB blue()   const{return rgb(0x00,0x00,0xFF);};
    RGB yellow() const{return rgb(0xFF,0xFF,0x00);};
    RGB cyan()   const{return rgb(0x00,0xFF,0xFF);};
    RGB violet() const{return rgb(0xFF,0x00,0xFF);};
    int getWidth(void) const{
      return Width;
    };
    int getHeight(void) const{
      return Height;
    };
    void setSize(const int width,const int height){
      assert(width>=0 && height>=0);
      Width=width;
      Height=height;
      if (width*height && !(Pixels=(RGB *) realloc(Pixels,Width*Height*sizeof(RGB))))
        throw "Memory allocation failed\n";
    };
    void setSize(const int size){
      setSize(size,size);
    };
    void setWidth(const int width){
      setSize(width,Height);
    };
    void setHeight(const int height){
      setSize(Width,height);
    };
    void fill(const RGB x){
      for (int i=Width*Height-1;i>=0;i--)
        Pixels[i]=x;
    }
    void loadStream(std::istream &s){
      bitmapfileheader h;
      int c;
      char *t,*u;
      s.read((char *) &h,sizeof(bitmapfileheader));
#define ASSERT(_c,_s) if (!(_c)) throw (_s);
      ASSERT(h.Tag[0]=='B',"Invalid bitmap image signature in bitmap image header");
      ASSERT(h.Tag[1]=='M',"Invalid bitmap image signature in bitmap image header");
      ASSERT(h.Header.Size==sizeof(bitmapheader),"Wrong header length in bitmap image header");
      ASSERT(h.Header.Planes==1,"Invalid planes count in bitmap image header");
      ASSERT(h.Header.BitCount==24,"Only 24 BBP Bitmaps are supported");
      ASSERT(h.Header.Compression==0,"Wrong pixel format in bitmap image header");
      ASSERT(h.Header.Width*h.Header.Height>0,"Invalid image size");
#undef ASSERT
      setSize(h.Header.Width,h.Header.Height);
      c=align32(Width*3);
      t=new char[c];
      try {
        for (int a=0;a<Height;a++){
          s.read(t,c);
          u=t;
          for (int b=0;b<Width;b++){
            RGB &p=Pixels[a*Width+b];
            p.B=*u++;
            p.G=*u++;
            p.R=*u++;
          }
        }
      }
      catch (...){
        delete[] t;
        throw;
      }
      delete[] t;
    };
    void saveStream(std::ostream &s) const{
      bitmapfileheader h={{'B','M'},0,0,sizeof(bitmapfileheader),{sizeof(struct bitmapheader),Width,Height,1,24,0,0,0,0,0,0}};
      int c=align32(Width*3);
      char *t,*u;
      s.write((char *) &h,sizeof(bitmapfileheader));
      t=new char[c];
      try {
        for (int a=0;a<c;a++)
          t[a]=0;
        for (int a=0;a<Height;a++){
          u=t;
          for (int b=0;b<Width;b++){
            RGB &p=Pixels[a*Width+b];
            *u++=(unsigned char) p.B;
            *u++=(unsigned char) p.G;
            *u++=(unsigned char) p.R;
          }
          s.write(t,c);
        }
      }
      catch (...){
        delete[] t;
        throw;
      }
      delete[] t;
    };
    void loadFile(const char *filename){
      std::ifstream s(filename,std::fstream::binary);
      loadStream(s);
    };
    void saveFile(const char *filename){
      std::ofstream s(filename,std::fstream::binary);
      saveStream(s);
    };
};
template<typename T> std::istream &operator << (std::istream &s,Bitmap<T> &b){
  b.saveStream(s);
  return s;
};
template<typename T> std::ostream &operator >> (std::ostream &s,Bitmap<T> &b){
  b.loadStream(s);
  return s;
};
#endif Ce document a été traduit de LaTeX par HeVeA |