Main Page   Modules   Class Hierarchy   Compound List   File List   Compound Members   Related Pages   Examples  

Image.cpp

00001 /* Copyright (c) 2001 C. Grigorescu S.E. Grigorescu A. Jalba*/
00002 
00003 #include "Image.h"
00004 #include <string.h>
00005 #include <sys/wait.h>
00006 #include <math.h>
00007 
00008 const char* types[6]={" BYTE_2D", " SHORT_2D", " INT_2D", " FLOAT_2D", " DOUBLE_2D", " UNKNOWN"};
00009 
00010 template class Image< byte >;
00011 template class Image< int >;
00012 template class Image< float >;
00013 
00014 //  template Image<int> operator+< int >(const Image< int > &img1, const Image< int > &img2);
00015 //  template Image<int> operator-< int >(const Image< int > &img1, const Image< int > &img2);
00016 //  template Image<int> operator*< int >(const Image< int > &img1, const Image< int > &img2);
00017 
00018 template< class T > Image< T >::Image(char *name = "")
00019 {
00020   width = height = 0; 
00021   pixels = NULL;
00022   setName(name);
00023   pid = 0;    
00024 }
00025 
00026 template< class T > Image< T >::Image(int w, int h, char *name = "")
00027 {
00028   try
00029   {
00030     pixels = (T **)calloc(h, sizeof(T *));
00031     Assert<Fatal_error>(pixels);
00032     pixels[0] = (T *)calloc(w*h, sizeof(T));
00033     Assert<Fatal_error>(pixels[0]);
00034   }
00035   catch(Fatal_error e) { e.print("Unable to allocate memory"); }
00036 
00037   for(int i=1;i<h;i++)
00038     pixels[i] = pixels[i-1] + w;
00039 
00040   width = w; height = h;
00041   pid = 0;    
00042   setName(name);
00043 }
00044 
00045 template< class T > Image< T >::Image(const Image<T>& img)
00046 {
00047   width  = img.width;
00048   height = img.height;
00049   pixels = NULL;
00050   pid    = 0;
00051   setName(img.img_name);
00052   if (img.width*img.height != 0) 
00053     setPixels(img.width, img.height, img.pixels[0]);
00054 }
00055 
00056 template< class T > void Image< T >::destroyImage() 
00057 {
00058   if(pixels != NULL) {
00059     free(pixels[0]);
00060     free(pixels);
00061     pixels = NULL;
00062     width=height=0;
00063   }
00064 }
00065 
00066 template< class T > Image< T >::~Image()
00067 { 
00068   destroyImage();
00069   setName("");
00070   closeWindow();
00071 }
00072 
00073 template< class T > void Image< T >::setName(const char *name) 
00074 { 
00075   strncpy(img_name, name, 128); 
00076 }
00077 
00078 template< class T > void Image< T >::makeImage(int w, int h)
00079 {
00080   destroyImage(); 
00081   try
00082   {
00083     pixels = (T **)calloc(h, sizeof(T*));
00084     Assert<Fatal_error>(pixels);
00085     pixels[0] = (T*)calloc(w*h, sizeof(T));
00086     Assert<Fatal_error>(pixels[0]);
00087   }
00088   catch(Fatal_error e) { e.print("Unable to allocate memory"); }
00089 
00090   for(int i=1;i<h;i++)
00091     pixels[i] = pixels[i-1] + w;
00092 
00093   width = w; height = h;
00094 }
00095 
00096 template< class T > void Image< T >::setPixels(int w, int h, T* data)
00097 {
00098   makeImage(w, h);
00099   try
00100   {
00101     Assert<Fatal_error>(data);
00102     memcpy(pixels[0], data, getSize()*sizeof(T));
00103   }
00104   catch(Fatal_error e) { e.print("Invalid input data"); }
00105 }
00106 
00107 template< class T > T Image<T> :: min()
00108 {
00109   T res = pixels[0][0];
00110   for (int i = 0; i < height; i++)
00111     for (int j = 0; j < width; j++)
00112       res = (res < pixels[i][j]) ? res : pixels[i][j];
00113   return res;
00114 }
00115 
00116 template< class T > T Image<T> :: max()
00117 {
00118   T res = pixels[0][0];
00119   for (int i = 0; i < height; i++)
00120     for (int j = 0; j < width; j++)
00121       res = (res > pixels[i][j]) ? res : pixels[i][j];
00122   return res;
00123 }
00124 
00125 template< class T > float Image<T> :: avg()
00126 {
00127   float res = 0;
00128   for (int i = 0; i < height; i++)
00129     for (int j = 0; j < width; j++)
00130       res += (float)pixels[i][j];
00131   return (res/getSize());
00132 }
00133 
00134 template< class T > float Image<T> :: dev()
00135 {
00136   float res = 0;
00137   float mean;
00138   mean = avg();
00139   for (int i = 0; i < height; i++)
00140     for (int j = 0; j < width; j++)
00141       res += ((float)pixels[i][j] - mean)*((float)pixels[i][j] - mean);
00142   return (sqrt(res/getSize()));
00143 }
00144 
00145 template< class T > Image< T >& Image< T >::operator=(const Image< T >& img)
00146 {
00147   if(this != &img) {
00148     width = img.width;
00149     height = img.height;
00150     setName(img.img_name);
00151     if (img.width*img.height != 0)
00152       setPixels(img.width, img.height, img.pixels[0]);
00153     else
00154       pixels = NULL;
00155   }
00156   return *this;
00157 }
00158 
00159 template< class T > int Image< T >::operator==(const Image< T >&img)
00160 {
00161   if (width==img.width && height==img.height)
00162     return (!memcmp(pixels[0], img.pixels[0], getSize()*sizeof(T)));
00163   else
00164     return (width==img.width && height==img.height); 
00165 }
00166 
00167 template< class T > int Image< T >::operator!=(const Image< T >&img)
00168 {
00169   if (width==img.width && height==img.height)
00170     return (memcmp(pixels[0], img.pixels[0], getSize()*sizeof(T)));
00171   else
00172     return (width!=img.width && height!=img.height); 
00173 }
00174 
00175 template< class T > Image< T > &Image< T >::operator=(const T val)
00176 {
00177   for (int i=0;i<getSize();i++) 
00178     pixels[0][i] = val;
00179   return (*this);
00180 }
00181 
00182 template< class T > void Image< T >::clearImage(const T val)
00183 {
00184   for (int i=0;i<getSize();i++) 
00185     pixels[0][i] = val;
00186 }
00187 
00188 template< class T > Image< T > &Image< T >::operator+=(const T val)
00189 {
00190   for (int i=0;i<getSize();i++) 
00191     pixels[0][i] += val;
00192   return (*this);
00193 }
00194 
00195 template< class T > Image< T > &Image< T >::operator-=(const T val)
00196 {
00197   for (int i=0;i<getSize();i++) 
00198     pixels[0][i] -= val;
00199   return (*this);
00200 }
00201 
00202 template< class T > Image< T > &Image< T >::operator*=(const T val)
00203 {
00204   for (int i=0;i<getSize();i++) 
00205     pixels[0][i] = pixels[0][i] * val;
00206   return (*this);
00207 }
00208 
00209 template< class T > Image< T > &Image< T >::operator+=(const Image< T >&img)
00210 {
00211   if(width!=img.width || height!=img.height)
00212     throw Fatal_error("The two images have different sizes");
00213   else
00214   {
00215     for(int i=0;i<getSize();i++)
00216       pixels[0][i] += img.pixels[0][i];
00217     return *this;
00218   }
00219 }
00220 
00221 template< class T > Image< T > &Image< T >::operator-=(const Image< T >&img)
00222 {
00223   if(width!=img.width || height!=img.height)
00224   {
00225     throw Fatal_error("The two images have different sizes");
00226   }
00227   else
00228   {
00229     for(int i=0;i<getSize();i++)
00230       pixels[0][i] -= img.pixels[0][i];
00231     return *this;
00232   }
00233 }
00234 
00235 //  template< class T > Image< T > &Image< T >::operator+(const Image< T >&img)
00236 //  {
00237 //    Image< T > *temp = new Image< T >;
00238 //    temp->setPixels(width,height,pixels[0]);
00239 //    (*temp) += img;
00240 //    return (*temp);
00241 //  }
00242 
00243 //  template< class T > Image<T> operator+(const Image<T>& img1, const Image<T>& img2)
00244 //  {
00245 //    Image< T > rez;
00246 //    rez = img1;
00247 //    rez += img2;
00248 //    return rez;
00249 //  }
00250 
00251 template< class T > Image< T > &Image< T >::operator*=(const Image< T >&img)
00252 {
00253   if(width!=img.width || height!=img.height)  
00254     throw Fatal_error("The two images have different sizes");
00255   else  {
00256     for(int i=0;i<getSize();i++)
00257       pixels[0][i] = pixels[0][i] * img.pixels[0][i];
00258     return *this;
00259   }
00260 }
00261 
00262 template< class T > void Image< T >::pad(int w, int h, PADDING_TYPE p)
00263 {
00264   Image< T > temp = *this;
00265   if (w > 0)
00266   {
00267     makeImage(temp.width+2*w, temp.height+2*h);
00268     for (int i=h; i<temp.height+h; i++) 
00269       for (int j=w; j<temp.width+w; j++)
00270         (*this)[i][j] = temp[i-h][j-w]; 
00271     if (p == ZEROS)
00272     {
00273       for (int i = 0; i < h; i++)
00274         for (int j = w; j < getWidth()-w; j++)
00275           (*this)[i][j] = 0;
00276       for (int i = getHeight()-h; i < getHeight(); i++)
00277         for (int j = w; j < getWidth()-w; j++)
00278           (*this)[i][j] = 0;
00279       for (int i = 0; i < getHeight(); i++)
00280         for (int j = 0; j < w; j++)
00281           (*this)[i][j] = 0;
00282       for (int i = 0; i < getHeight(); i++)
00283         for (int j = getWidth()-w; j < getWidth(); j++)
00284           (*this)[i][j] = 0;
00285     }
00286     if (p == REFLECTION)
00287     {
00288       for (int i = 0; i < h; i++)
00289         for (int j = w; j < getWidth()-w; j++)
00290           (*this)[i][j] = (*this)[2*h-1-i][j];
00291       for (int i = getHeight()-h; i < getHeight(); i++)
00292         for (int j = w; j < getWidth()-w; j++)
00293           (*this)[i][j] = (*this)[2*getHeight()-2*h-1-i][j];
00294       for (int i = 0; i < getHeight(); i++)
00295         for (int j = 0; j < w; j++)
00296           (*this)[i][j] = (*this)[i][2*w-1-j];
00297       for (int i = 0; i < getHeight(); i++)
00298         for (int j = getWidth()-w; j < getWidth(); j++)
00299           (*this)[i][j] = (*this)[i][2*getWidth()-2*w-1-j];
00300     }
00301     if (p == WRAP)
00302     {
00303       for (int i = 0; i < h; i++)
00304         for (int j = w; j < getWidth()-w; j++)
00305           (*this)[i][j] = (*this)[getHeight()-2*h+i][j];
00306       for (int i = getHeight()-h; i < getHeight(); i++)
00307         for (int j = w; j < getWidth()-w; j++)
00308           (*this)[i][j] = (*this)[2*h-getHeight()+i][j];
00309       for (int i = 0; i < getHeight(); i++)
00310         for (int j = 0; j < w; j++)
00311           (*this)[i][j] = (*this)[i][getWidth()-2*w+j];
00312       for (int i = 0; i < getHeight(); i++)
00313         for (int j = getWidth()-w; j < getWidth(); j++)
00314           (*this)[i][j] = (*this)[i][2*w-getWidth()+j];
00315     }
00316   }
00317 }
00318 
00319 template< class T > void Image< T >::crop(int x1, int y1, int x2, int y2)
00320 {
00321   Image< T > temp = *this;
00322   int offset_x1 = x2 > x1 ? x1 : x2;
00323   offset_x1 = offset_x1 > 0 ? offset_x1 : 0;
00324   int offset_y1 = y2 > y1 ? y1 : y2;
00325   offset_y1 = offset_y1 > 0 ? offset_y1 : 0;
00326 
00327   int offset_x2 = x2 < x1 ? x1 : x2;
00328   offset_x2 = offset_x2 < temp.width ? offset_x2 : temp.width;
00329   int offset_y2 = y2 < y1 ? y1 : y2;
00330   offset_y2 = offset_y2 < temp.height ? offset_y2 : temp.height;
00331   makeImage((offset_x2 - offset_x1), (offset_y2 - offset_y1));
00332 
00333   for (int i=0; i<(offset_y2 - offset_y1); i++) 
00334     for (int j=0; j<(offset_x2 - offset_x1); j++)
00335       pixels[i][j] = temp[i + offset_y1][j + offset_x1];
00336 }
00337 
00338 template< class T > void Image< T >::makeEvenSized(void) 
00339 {
00340   Image< T > temp = *this;
00341   if ((width%2 == 1) || (height%2 == 1)) {
00342     makeImage(temp.width+temp.width%2,temp.height+temp.height%2);
00343     for(int i=0;i<temp.height;i++)
00344       for(int j=0;j<temp.width;j++)
00345         pixels[i][j] = temp[i][j];
00346     for(int i=0;i<temp.height;i++)
00347       pixels[i][width-1] = temp[i][temp.width-1];
00348     for(int j=0;j<temp.width;j++)
00349       pixels[height-1][j] = temp[temp.height-1][j];
00350     pixels[height-1][width-1] = pixels[height-1][width-2];
00351   }
00352 }
00353 
00354 template< class T > void Image< T >::closeWindow() 
00355 {
00356   if(pid) {
00357     kill(pid, SIGUSR1); //sigusr
00358     waitpid(pid, NULL, 0);
00359     pid = 0;
00360   }
00361 }          
00362   
00363 
00364 
00365