00001 #include "Image.h"
00002 #include <math.h>
00003
00004 #ifdef WIN32
00005 #define M_PI 3.14159265358979323846
00006 #endif
00007
00008 void ImageGrey::scale_down(unsigned int min_x,
00009 unsigned int min_y,
00010 unsigned int max_x,
00011 unsigned int max_y,
00012 unsigned int new_sx,
00013 unsigned int new_sy,
00014 float *new_image)
00015 {
00022 unsigned int cnt_x ;
00023 unsigned int cnt_y ;
00024 unsigned int cnt_x2 ;
00025 unsigned int cnt_y2 ;
00026 unsigned int x_range ;
00027 unsigned int y_range ;
00028 int x_start ;
00029 unsigned int x_end ;
00030 int y_start ;
00031 unsigned int y_end ;
00032 float x_div ;
00033 float y_div ;
00034 float *out_ptr ;
00035 float x_cent ;
00036 float y_cent ;
00037 float tot_w ;
00038 float dx ;
00039 float dy ;
00040 float x_sd ;
00041 float y_sd ;
00042 float x_var ;
00043 float y_var ;
00044 float w ;
00045 float denom ;
00046
00047 out_ptr = new_image ;
00048 x_range = max_x - min_x + 1 ;
00049 y_range = max_y - min_y + 1 ;
00050 x_div = (float)x_range / (float)new_sx ;
00051 y_div = (float)y_range / (float)new_sy ;
00052 x_sd = x_div / 2.0 ;
00053 y_sd = y_div / 2.0 ;
00054 x_var = x_sd*x_sd ;
00055 y_var = y_sd*y_sd ;
00056
00057 denom = 2*M_PI * sqrt(x_var*y_var) ;
00058
00059 y_cent = y_sd ;
00060 for(cnt_y=0 ; cnt_y<new_sy ; cnt_y++, y_cent+=y_div){
00061 x_cent = x_sd ;
00062 for(cnt_x=0 ; cnt_x<new_sx ; cnt_x++, out_ptr++,x_cent+=x_div){
00063
00064
00065 *out_ptr = 0 ;
00066 tot_w = 0 ;
00067 x_start = (int)(x_cent - 2*x_sd) ;
00068 if(x_start<0) x_start = 0 ;
00069 x_end = (unsigned int)(x_cent + 2*x_sd + 0.5) ;
00070 if(x_end>x_range-1) x_end = x_range-1 ;
00071
00072 y_start = (int)(y_cent - 2*y_sd) ;
00073 if(y_start<0) y_start = 0 ;
00074 y_end = (unsigned int)(y_cent + 2*y_sd + 0.5) ;
00075 if(y_end>y_range-1) y_end = y_range-1 ;
00076
00077
00078 for(cnt_y2=y_start ; cnt_y2<=y_end ; cnt_y2++){
00079 for(cnt_x2=x_start ; cnt_x2<=x_end ; cnt_x2++){
00080
00081
00082
00083
00084
00085 dx = x_cent - (float)cnt_x2 ;
00086 dx *= dx / x_var ;
00087 dy = y_cent - (float)cnt_y2 ;
00088 dy *= dy / y_var ;
00089 w = exp(-0.5*(dx+dy)) / denom ;
00090 tot_w += w ;
00091 *out_ptr += brightness[cnt_x2+min_x +
00092 (cnt_y2+min_y) * width] *
00093 w ;
00094 }
00095 }
00096 *out_ptr /= tot_w ;
00097 }
00098 }
00099 }
00100
00101 void ImageGrey::scale_down(unsigned int min_x,
00102 unsigned int min_y,
00103 unsigned int max_x,
00104 unsigned int max_y,
00105 unsigned int new_sx,
00106 unsigned int new_sy,
00107 double *new_image)
00108 {
00115 unsigned int cnt_x ;
00116 unsigned int cnt_y ;
00117 unsigned int cnt_x2 ;
00118 unsigned int cnt_y2 ;
00119 unsigned int x_range ;
00120 unsigned int y_range ;
00121 int x_start ;
00122 unsigned int x_end ;
00123 int y_start ;
00124 unsigned int y_end ;
00125 double x_div ;
00126 double y_div ;
00127 double *out_ptr ;
00128 double x_cent ;
00129 double y_cent ;
00130 double tot_w ;
00131 double dx ;
00132 double dy ;
00133 double x_sd ;
00134 double y_sd ;
00135 double x_var ;
00136 double y_var ;
00137 double w ;
00138 double denom ;
00139
00140 out_ptr = new_image ;
00141 x_range = max_x - min_x + 1 ;
00142 y_range = max_y - min_y + 1 ;
00143 x_div = (double)x_range / (double)new_sx ;
00144 y_div = (double)y_range / (double)new_sy ;
00145 x_sd = x_div / 2.0 ;
00146 y_sd = y_div / 2.0 ;
00147 x_var = x_sd*x_sd ;
00148 y_var = y_sd*y_sd ;
00149
00150
00151 denom = 2*M_PI * sqrt(x_var*y_var) ;
00152
00153 y_cent = y_sd ;
00154 for(cnt_y=0 ; cnt_y<new_sy ; cnt_y++, y_cent+=y_div){
00155 x_cent = x_sd ;
00156 for(cnt_x=0 ; cnt_x<new_sx ; cnt_x++, out_ptr++,x_cent+=x_div){
00157
00158
00159 *out_ptr = 0 ;
00160 tot_w = 0 ;
00161 x_start = (int)(x_cent - 2*x_sd) ;
00162 if(x_start<0) x_start = 0 ;
00163 x_end = (unsigned int)(x_cent + 2*x_sd + 0.5) ;
00164 if(x_end>x_range-1) x_end = x_range-1 ;
00165
00166 y_start = (int)(y_cent - 2*y_sd) ;
00167 if(y_start<0) y_start = 0 ;
00168 y_end = (unsigned int)(y_cent + 2*y_sd + 0.5) ;
00169 if(y_end>y_range-1) y_end = y_range-1 ;
00170
00171
00172 for(cnt_y2=y_start ; cnt_y2<=y_end ; cnt_y2++){
00173 for(cnt_x2=x_start ; cnt_x2<=x_end ; cnt_x2++){
00174
00175
00176
00177
00178
00179 dx = x_cent - (double)cnt_x2 ;
00180 dx *= dx / x_var ;
00181 dy = y_cent - (double)cnt_y2 ;
00182 dy *= dy / y_var ;
00183 w = exp(-0.5*(dx+dy)) / denom ;
00184 tot_w += w ;
00185 *out_ptr += brightness[cnt_x2+min_x +
00186 (cnt_y2+min_y) * width] *
00187 w ;
00188 }
00189 }
00190 *out_ptr /= tot_w ;
00191 }
00192 }
00193 }
00194
00195 void ImageGrey::quick_scale_down(unsigned int min_x,
00196 unsigned int min_y,
00197 unsigned int max_x,
00198 unsigned int max_y,
00199 unsigned int new_sx,
00200 unsigned int new_sy,
00201 double *new_image)
00202 {
00203 unsigned int cnt_x ;
00204 unsigned int cnt_y ;
00205 double *out_ptr = new_image;
00206 double dx ;
00207 double dy ;
00208
00209 dx = (max_x - min_x)/ (double) new_sx ;
00210 dy = (max_y - min_y)/ (double) new_sy ;
00211
00212 for(cnt_y=0 ; cnt_y<new_sy ; cnt_y++){
00213 for(cnt_x=0 ; cnt_x<new_sx ; cnt_x++, out_ptr++){
00214 *out_ptr = brightness[(int)(min_x - 0.5 + cnt_x*dx) +
00215 ((int)(min_y - 0.5 + cnt_y*dy))*width];
00216 }
00217 }
00218 }
00219
00220