00001
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
00015
00016
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
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
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);
00358 waitpid(pid, NULL, 0);
00359 pid = 0;
00360 }
00361 }
00362
00363
00364
00365