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