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