1//
2//  PRDFTLowPass.m
3//  PRICE
4//
5//  Created by Riccardo Mottola on Sat Sep 13 2003.
6//  Copyright (c) 2003-2009 Carduus. All rights reserved.
7//
8// This application is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
9// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10
11#import "PRDFTLowPass.h"
12#import "PRDFTFilter.h"
13#import "FFT.h"
14#include "math.h"
15
16@implementation PRDFTLowPass
17
18- (PRImage *)filterImage:(PRImage *)image with:(NSArray *)parameters progressPanel:(PRCProgress *)progressPanel
19{
20    BOOL autoRange;
21    float bandPassFreq;
22    float bandStopFreq;
23
24    autoRange = [[parameters objectAtIndex:0] boolValue];
25    bandPassFreq = [[parameters objectAtIndex:1] floatValue];
26    bandStopFreq = [[parameters objectAtIndex:2] floatValue];
27    return [self transformImage:image :autoRange :bandPassFreq :bandStopFreq :progressPanel];
28}
29
30- (NSString *)actionName
31{
32    return @"DFT Low Pass";
33}
34
35- (PRImage *)transformImage:(PRImage *)srcImage :(BOOL)autoRange :(float) BPFreq :(float) BSFreq :(PRCProgress *)prPanel
36{
37    PRDFTFilter  *filter;
38    double       **Fa;
39    unsigned int i, j;
40    unsigned int w, h;
41    unsigned int bitNum;
42    unsigned int num;
43    unsigned int halfNum;
44    PRImage      *destImage;
45    float        radius;
46
47    progressSteps = 0;
48    totalProgressSteps = 5;
49    progPanel = prPanel;
50
51    /* get source image associated information */
52    if (progPanel != nil)
53    {
54        [self setActivity:@"Get image size"];
55        [self advanceProgress];
56    }
57    w = [srcImage width];
58    h = [srcImage height];
59
60    /* we set the image square to the nearest power of two on the longer side */
61    if (w > h)
62        bitNum = binaryLog(w);
63    else
64        bitNum = binaryLog(h);
65    num = binpow(bitNum);
66
67    /* calculate the half comprising the zero */
68    halfNum = (num >> 1);
69    NSLog(@"halfNum %d", halfNum);
70
71    /* allocate filter  matrix */
72    Fa = (double**)calloc(num, sizeof(double*));
73    for (i = 0; i < num; i++)
74    {
75        Fa[i] = (double*)calloc(num, sizeof(double));
76        if (!Fa[i])
77        {
78            printf("out of memory allocating float matrix?\n");
79            return srcImage;
80        }
81        memset(Fa[i], '\000', num);
82    }
83
84    /* calculate the filter */
85    NSLog(@"BP %f, BS %f", BPFreq, BSFreq);
86    /* top left quadrant */
87    for (i = 0; i <= halfNum; i++)
88        for (j = 0; j <= halfNum; j++)
89        {
90            radius = sqrt(i*i + j*j) / halfNum;
91            if (radius < BPFreq)
92            {
93                Fa[i][j] = 1;
94            } else if (radius < BSFreq)
95            {
96                Fa[i][j] = 0.5*(cos(M_PI*(radius-BPFreq)/(BSFreq-BPFreq))+1);
97            }
98        }
99
100    /* top right quadrant */
101    for (i = 0; i < halfNum; i++)
102        for (j = 0; j < halfNum-1; j++)
103            Fa[i][num - j - 1] = Fa[i][j];
104    /* bottom left quadrant */
105    for (i = 0; i < halfNum-1; i++)
106        for (j = 0; j < halfNum; j++)
107            Fa[num - i - 1][j] = Fa[i][j];
108    /* bottom right quadrant */
109    for (i = 0; i < halfNum-1; i++)
110        for (j = 0; j < halfNum-1; j++)
111            Fa[num - i - 1][num - j - 1] = Fa[i][j];
112
113
114    if (progPanel != nil)
115    {
116        [self setActivity:@"run the filter"];
117        [self advanceProgress];
118    }
119
120    /* instantiate the filter */
121    filter = [[PRDFTFilter alloc] init];
122
123    /* run it */
124    destImage = [[filter filterImage :srcImage :Fa :NULL :num :autoRange :self] retain];
125
126    /* release filter */
127    [filter release];
128
129    /* now we free our filter matrix */
130    for (i = 0; i < num; i++)
131        free(Fa[i]);
132    free(Fa);
133
134    if (progPanel != nil)
135    {
136        [self setActivity:@"Done"];
137        [self showProgress];
138    }
139    [destImage autorelease];
140    return destImage;
141}
142
143
144@end
145