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 |