Mercurial > hg > wm
comparison Meerwald/dwt.c @ 0:be303a3f5ea8
import
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> | 
|---|---|
| date | Sun, 12 Aug 2007 13:14:34 +0200 | 
| parents | |
| children | acb6967ee76d | 
   comparison
  equal
  deleted
  inserted
  replaced
| -1:000000000000 | 0:be303a3f5ea8 | 
|---|---|
| 1 #include "wm.h" | |
| 2 #include "dwt.h" | |
| 3 | |
| 4 char filter_file[MAXPATHLEN] = ""; | |
| 5 AllFilters dwt_allfilters; | |
| 6 FilterGH *dwt_filters = NULL; | |
| 7 int dwt_method; | |
| 8 int dwt_cols; | |
| 9 int dwt_rows; | |
| 10 int dwt_levels; | |
| 11 int dwt_filter; | |
| 12 | |
| 13 void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method) { | |
| 14 int i; | |
| 15 | |
| 16 if (strcmp(filter_file, filter_name)) { | |
| 17 if (filter_name) | |
| 18 strcpy(filter_file, filter_name); | |
| 19 else | |
| 20 strcpy(filter_file, "filter.dat"); | |
| 21 /* memory leak here - there is no function unload_filters() */ | |
| 22 dwt_allfilters = load_filters(filter_file); | |
| 23 if (!dwt_allfilters) { | |
| 24 fprintf(stderr, "init_dwt(): unable to open filter definition file %s\n", filter_file); | |
| 25 return; | |
| 26 } | |
| 27 } | |
| 28 | |
| 29 #ifdef DEBUG | |
| 30 if (level <= 0 || level > rint(log(MIN(cols, rows))/log(2.0)) - 2) { | |
| 31 fprintf(stderr, "init_dwt(): level parameter does not match image width/height\n"); | |
| 32 return; | |
| 33 } | |
| 34 #endif | |
| 35 | |
| 36 if (dwt_filters && level != dwt_levels) { | |
| 37 free(dwt_filters); | |
| 38 dwt_filters = NULL; | |
| 39 } | |
| 40 | |
| 41 dwt_levels = level; | |
| 42 | |
| 43 if (!dwt_filters) | |
| 44 dwt_filters = calloc(level + 1, sizeof(FilterGH)); | |
| 45 | |
| 46 for (i = 0; i < level + 1; i++) | |
| 47 dwt_filters[i] = (dwt_allfilters->filter)[filter]; | |
| 48 | |
| 49 dwt_filter = filter; | |
| 50 dwt_method = method; | |
| 51 dwt_cols = cols; | |
| 52 dwt_rows = rows; | |
| 53 } | |
| 54 | |
| 55 Image_tree fdwt(gray **pixels) { | |
| 56 Image image; | |
| 57 Image_tree tree; | |
| 58 int i, j; | |
| 59 | |
| 60 image = new_image(dwt_cols, dwt_rows); | |
| 61 | |
| 62 for (i = 0; i < dwt_rows; i++) | |
| 63 for (j = 0; j < dwt_cols; j++) | |
| 64 set_pixel(image, j, i, pixels[i][j]); | |
| 65 | |
| 66 tree = wavelettransform(image, dwt_levels, dwt_filters, dwt_method); | |
| 67 free_image(image); | |
| 68 | |
| 69 return tree; | |
| 70 } | |
| 71 | |
| 72 Image_tree fdwt_wp(gray **pixels) { | |
| 73 Image image; | |
| 74 Image_tree tree; | |
| 75 int i, j; | |
| 76 | |
| 77 image = new_image(dwt_cols, dwt_rows); | |
| 78 | |
| 79 for (i = 0; i < dwt_rows; i++) | |
| 80 for (j = 0; j < dwt_cols; j++) | |
| 81 set_pixel(image, j, i, pixels[i][j]); | |
| 82 | |
| 83 tree = wavelettransform_wp(image, dwt_levels, dwt_filters, dwt_method); | |
| 84 free_image(image); | |
| 85 | |
| 86 return tree; | |
| 87 } | |
| 88 | |
| 89 void idwt(Image_tree dwts, gray **pixels) { | |
| 90 Image image; | |
| 91 int i, j; | |
| 92 | |
| 93 image = inv_transform(dwts, dwt_filters, dwt_method + 1); | |
| 94 | |
| 95 for (i = 0; i < dwt_rows; i++) | |
| 96 for (j = 0; j < dwt_cols; j++) | |
| 97 pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); | |
| 98 | |
| 99 free_image(image); | |
| 100 } | |
| 101 | |
| 102 void idwt_wp(Image_tree dwts, gray **pixels) { | |
| 103 Image image; | |
| 104 int i, j; | |
| 105 | |
| 106 image = inv_transform(dwts, dwt_filters, dwt_method + 1); | |
| 107 | |
| 108 for (i = 0; i < dwt_rows; i++) | |
| 109 for (j = 0; j < dwt_cols; j++) | |
| 110 pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); | |
| 111 | |
| 112 free_image(image); | |
| 113 } | |
| 114 | |
| 115 int gen_pollen_filter(double *filter, double alpha, double beta, int which) { | |
| 116 int i, j, k, filterlength; | |
| 117 double tf[6]; | |
| 118 | |
| 119 /* parameter alpha, beta have to be in range -Pi .. Pi */ | |
| 120 if (alpha < -M_PI || alpha >= M_PI) { | |
| 121 fprintf(stderr, "alpha %f out of range\n", alpha); | |
| 122 return -1; | |
| 123 } | |
| 124 | |
| 125 if (beta < -M_PI || beta >= M_PI) { | |
| 126 fprintf(stderr, "beta %f out of range\n", beta); | |
| 127 return -1; | |
| 128 } | |
| 129 | |
| 130 /* generate Pollen filter coefficients, see http://www.dfw.net/~cody for details */ | |
| 131 tf[0] = ((1.0 + cos(alpha) + sin(alpha)) * (1.0 - cos(beta) - sin(beta)) + 2.0 * sin(beta) * cos(alpha)) / 4.0; | |
| 132 tf[1] = ((1.0 - cos(alpha) + sin(alpha)) * (1.0 + cos(beta) - sin(beta)) - 2.0 * sin(beta) * cos(alpha)) / 4.0; | |
| 133 tf[2] = (1.0 + cos(alpha - beta) + sin(alpha - beta)) / 2.0; | |
| 134 tf[3] = (1.0 + cos(alpha - beta) - sin(alpha - beta)) / 2.0; | |
| 135 tf[4] = 1.0 - tf[0] - tf[2]; | |
| 136 tf[5] = 1.0 - tf[1] - tf[3]; | |
| 137 | |
| 138 /* set close-to-zero filter coefficients to zero */ | |
| 139 for (i = 0; i < 6; i++) | |
| 140 if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; | |
| 141 | |
| 142 /* find the first non-zero wavelet coefficient */ | |
| 143 i = 0; | |
| 144 while (tf[i] == 0.0) i++; | |
| 145 | |
| 146 /* find the last non-zero wavelet coefficient */ | |
| 147 j = 5; | |
| 148 while (tf[j] == 0.0) j--; | |
| 149 | |
| 150 filterlength = j - i + 1; | |
| 151 for (k = 0; k < filterlength; k++) | |
| 152 switch (which) { | |
| 153 case FILTERH: | |
| 154 filter[k] = tf[j--] / 2.0; | |
| 155 break; | |
| 156 case FILTERG: | |
| 157 filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i++] / 2.0; | |
| 158 break; | |
| 159 case FILTERHi: | |
| 160 filter[k] = tf[j--]; | |
| 161 break; | |
| 162 case FILTERGi: | |
| 163 filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i++]; | |
| 164 break; | |
| 165 default: | |
| 166 return -1; | |
| 167 } | |
| 168 | |
| 169 while (k < 6) | |
| 170 filter[k++] = 0.0; | |
| 171 | |
| 172 return filterlength; | |
| 173 } | |
| 174 | |
| 175 void dwt_pollen_filter(double alpha, double beta) { | |
| 176 FilterGH filter; | |
| 177 int i; | |
| 178 | |
| 179 filter = malloc(sizeof(struct FilterGHStruct)); | |
| 180 #ifdef DEBUG | |
| 181 if (!filter) { | |
| 182 fprintf(stderr, "dwt_pollen_filter(): malloc failed()\n"); | |
| 183 return; | |
| 184 } | |
| 185 #endif | |
| 186 | |
| 187 filter->type = FTOther; | |
| 188 filter->name = "pollen"; | |
| 189 | |
| 190 filter->g = new_filter(6); | |
| 191 filter->g->type = FTSymm; | |
| 192 filter->g->hipass = 1; | |
| 193 filter->g->len = gen_pollen_filter(filter->g->data, alpha, beta, FILTERG); | |
| 194 filter->g->start = -filter->g->len / 2; | |
| 195 filter->g->end = filter->g->len / 2 - 1; | |
| 196 | |
| 197 filter->h = new_filter(6); | |
| 198 filter->h->type = FTSymm; | |
| 199 filter->h->hipass = 0; | |
| 200 filter->h->len = gen_pollen_filter(filter->h->data, alpha, beta, FILTERH); | |
| 201 filter->h->start = -filter->h->len / 2; | |
| 202 filter->h->end = filter->h->len / 2 - 1; | |
| 203 | |
| 204 filter->gi = new_filter(6); | |
| 205 filter->gi->type = FTSymm; | |
| 206 filter->gi->hipass = 1; | |
| 207 filter->gi->len = gen_pollen_filter(filter->gi->data, alpha, beta, FILTERGi); | |
| 208 filter->gi->start = -filter->gi->len / 2; | |
| 209 filter->gi->end = filter->gi->len / 2 - 1; | |
| 210 | |
| 211 filter->hi = new_filter(6); | |
| 212 filter->hi->type = FTSymm; | |
| 213 filter->hi->hipass = 0; | |
| 214 filter->hi->len = gen_pollen_filter(filter->hi->data, alpha, beta, FILTERHi); | |
| 215 filter->hi->start = -filter->hi->len / 2; | |
| 216 filter->hi->end = filter->hi->len / 2 - 1; | |
| 217 | |
| 218 #ifdef DEBUG | |
| 219 if (dwt_levels <= 0) { | |
| 220 fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); | |
| 221 return; | |
| 222 } | |
| 223 #endif | |
| 224 | |
| 225 #ifdef DEBUG | |
| 226 if (!dwt_filters) { | |
| 227 fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); | |
| 228 return; | |
| 229 } | |
| 230 #endif | |
| 231 | |
| 232 for (i = 0; i < dwt_levels + 1; i++) | |
| 233 dwt_filters[i] = filter; | |
| 234 } | |
| 235 | |
| 236 int gen_param_filter(double *filter, int n, double alpha[], int which) { | |
| 237 int i, j, k, filterlength; | |
| 238 double *tf, *t; | |
| 239 | |
| 240 tf = malloc(2 * (n + 1) * sizeof(double)); | |
| 241 t = malloc(2 * (n + 1) * sizeof(double)); | |
| 242 if (!tf) { | |
| 243 fprintf(stderr, "gen_param_filter(): malloc() failed\n"); | |
| 244 return -1; | |
| 245 } | |
| 246 | |
| 247 tf[0] = 1.0 / sqrt(2.0); | |
| 248 tf[1] = 1.0 / sqrt(2.0); | |
| 249 | |
| 250 for (k = 0; k < n; k++) { | |
| 251 for (i = 0; i < 2 * (k + 2); i++) { | |
| 252 | |
| 253 #define H(X) (((X) < 0 || (X) >= 2 * (k + 1)) ? 0.0 : tf[X]) | |
| 254 | |
| 255 t[i] = 0.5 * (H(i - 2) + H(i) + | |
| 256 cos(alpha[k]) * (H(i - 2) - H(i)) + | |
| 257 (i & 1 ? -1.0 : 1.0) * sin(alpha[k]) * (H(2 * (k + 2) - i - 1) - H(2 * (k + 2) - i - 3))); | |
| 258 } | |
| 259 for (i = 0; i < 2 * (k + 2); i++) tf[i] = t[i]; | |
| 260 } | |
| 261 | |
| 262 /* set close-to-zero filter coefficients to zero */ | |
| 263 for (i = 0; i < 2 * (n + 1) ; i++) | |
| 264 if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; | |
| 265 | |
| 266 /* find the first non-zero wavelet coefficient */ | |
| 267 i = 0; | |
| 268 while (tf[i] == 0.0) i++; | |
| 269 | |
| 270 /* find the last non-zero wavelet coefficient */ | |
| 271 j = 2 * (n + 1) - 1; | |
| 272 while (tf[j] == 0.0) j--; | |
| 273 | |
| 274 filterlength = j - i + 1; | |
| 275 for (k = 0; k < filterlength; k++) | |
| 276 switch (which) { | |
| 277 case FILTERG: | |
| 278 case FILTERGi: | |
| 279 filter[k] = (double) (((i+1 & 0x01) * 2) - 1) * tf[i++]; | |
| 280 break; | |
| 281 case FILTERH: | |
| 282 case FILTERHi: | |
| 283 filter[k] = tf[j--]; | |
| 284 break; | |
| 285 default: | |
| 286 return -1; | |
| 287 } | |
| 288 | |
| 289 while (k < 2 * (n + 1)) | |
| 290 filter[k++] = 0.0; | |
| 291 | |
| 292 return filterlength; | |
| 293 } | |
| 294 | |
| 295 void dwt_param_filter(double alpha[], int n) { | |
| 296 FilterGH filter; | |
| 297 int i; | |
| 298 | |
| 299 filter = malloc(sizeof(struct FilterGHStruct)); | |
| 300 #ifdef DEBUG | |
| 301 if (!filter) { | |
| 302 fprintf(stderr, "dwt_param_filter(): malloc failed()\n"); | |
| 303 return; | |
| 304 } | |
| 305 #endif | |
| 306 | |
| 307 filter->type = FTOrtho; | |
| 308 filter->name = "param"; | |
| 309 | |
| 310 filter->g = new_filter(2 * (n + 1)); | |
| 311 filter->g->type = FTSymm; | |
| 312 filter->g->hipass = 1; | |
| 313 filter->g->len = gen_param_filter(filter->g->data, n, alpha, FILTERG); | |
| 314 filter->g->start = -filter->g->len / 2; | |
| 315 filter->g->end = filter->g->len / 2 - 1; | |
| 316 | |
| 317 filter->h = new_filter(2 * (n + 1)); | |
| 318 filter->h->type = FTSymm; | |
| 319 filter->h->hipass = 0; | |
| 320 filter->h->len = gen_param_filter(filter->h->data, n, alpha, FILTERH); | |
| 321 filter->h->start = -filter->h->len / 2; | |
| 322 filter->h->end = filter->h->len / 2 - 1; | |
| 323 | |
| 324 #ifdef DEBUG | |
| 325 if (dwt_levels <= 0) { | |
| 326 fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); | |
| 327 return; | |
| 328 } | |
| 329 #endif | |
| 330 | |
| 331 #ifdef DEBUG | |
| 332 if (!dwt_filters) { | |
| 333 fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); | |
| 334 return; | |
| 335 } | |
| 336 #endif | |
| 337 | |
| 338 for (i = 0; i < dwt_levels + 1; i++) | |
| 339 dwt_filters[i] = filter; | |
| 340 } | |
| 341 | |
| 342 void done_dwt() { | |
| 343 } | 
