subroutine CONVOL(ITYPE,BUF1,BUF2,BUF3,alpha,beta,BUF4,INIT) C C EMULATES Comtal convolver algorithm C called by using several switches and args -- all goes to same C computaional code but each has own method of calculating C the KERNEL coeffs. C C type = 0 for unsharp masking algorithm C 1 for isotropic alpha , beta algorithm C use /CO:a or /CO:a:b to envoke C type = 2 explicit kernel load /KE:a:b:c:d:e:f:g:h:i C type = 3 despiking filter use /DS:percent C special case-- if any element is zero dont include in sum C adjust total to compesate for zeros in 3x3 kernel,ie dont C average in zero data its non-exsistant. C C byte BUF1(512),BUF2(512),BUF3(512),BUF4(512) integer alpha,beta,ZEROS dimension alpha(9) !special for when all 9 kernel params real KERNEL(3,3) real K !kernel coeffs C C these funny varibles aatempt to emulate the COMTAL hardware C convolver parameter registers ,thats why their so weird data NC /0/ !common scale factor data NE /0/ !edge scale factor data S /0./ !input switch to scale resultant C C if( INIT .ne. 0 )goto 1049 C test initial call or not , only at initial do we build KERNEL C C C use type to determine KERNEL selection C if( ITYPE .ne. 0 )goto 100 C C C build KERNEL ICONS = alpha(1) if( alpha(1) .le. 0 .or. alpha(1) .gt. 512 )ICONS = 256 C compute values for center and all edge elements for unsharp C masking , edges = -1 and cneter = lambda -1 C normalize all so no division done during computataion C C K = -x * (1/3) * (1/512) + (1/9) K = ICONS * (1./3.) * (1./512.) + (1./9.) K = K * ( -8.0 ) sign = 1. if( K .lt. 0.0 )sign = -1. R2 = K !save K*8 K = ABS(K) R0 = 1.0 - R2 !compute (1-8*K) goto 5 C C skip this junk we dont need NC NE we have floating point code C NC = 0 NE = 0 4 if( R0 .lt. 1.0 )goto 5 NC = NC +1 !bump power of 2 R0 = R0 / 2. !drop R0 down if( NC .lt. 3 ) goto 4 C 5 KERNEL(2,2) = R0 !save R0 as kernel value R0 = K / 8.0 !get k*8 to K for R0 goto 9 C C skip this code we have flt pt dont need to scale it C R1 = 0.0 NCTMP = NC 6 if( NCTMP .eq. 0 ) goto 7 R0 = R0 / 2.0 NCTMP = NCTMP - 1 goto 6 7 if( R0 .ge. 1.0 )goto 8 if( R0 .gt. .5 )goto 8 NE = NE + 1 R0 = R0 * 2.0 if ( NE .lt. 3 ) goto 7 8 continue C C assign coded kernel values here C 9 continue R0 = sign * R0 C reset to proper sign 20 KERNEL(1,1) = R0 KERNEL(1,3) = R0 KERNEL(3,1) = R0 KERNEL(3,3) = R0 C KERNEL(1,2) = R0 KERNEL(2,1) = R0 KERNEL(2,3) = R0 KERNEL(3,2) = R0 C goto 1000 C go apply KERNEL to 3 lines C C******************************************************************** 100 continue if( ITYPE .ne. 1 )goto 200 C C ISOTROPIC alpha(1) -- beta filter C C build KERNEL acons = 0.0 if( alpha(1) .eq. 0 )goto 120 acons = 1./alpha(1) C 120 KERNEL(1,1) = acons KERNEL(1,3) = acons KERNEL(3,1) = acons KERNEL(3,3) = acons C bcons = 0.0 if( beta .eq. 0 )goto 130 bcons = 1./beta C 130 KERNEL(1,2) = bcons KERNEL(2,1) = bcons KERNEL(2,3) = bcons KERNEL(3,2) = bcons C KERNEL(2,2) = 1. goto 1000 C ********************************************************** C 200 continue if( ITYPE .ne. 2 ) goto 300 C C C here user has specified /KE:a:b:c:d:e:f:g:h:i C all nine params explicitly, good for testing & specials C do 250 j=1,3 do 250 i=1,3 250 KERNEL(i,j) = alpha((i-1)*3+j) C goto 1000 C C 300 continue C C user has requested DESPIKER -- compute avg of 8 nearest neighbors C and compare with the center pixel. If differ by more than n% then C replace center value with the average of 8 nearest neighbors . C PERCNT = alpha(1) * .01 C do 350 j=1,3 do 350 i=1,3 350 KERNEL(i,j) = 1.0 C KERNEL(2,2) = 0.0 C set cneter to zero goto 1000 C C ************************************************************** C C Normalize all coeffs so all less than 1. C 1000 continue C sum = 0. C do 1040 j=1,3 do 1040 i=1,3 1040 sum = KERNEL(i,j) + sum C summ the weights of the coeffs IF( SUM .EQ. 0.0 )GOTO 1046 C do 1045 j=1,3 do 1045 i=1,3 1045 KERNEL(i,j) = KERNEL(i,j) / abs(sum) C normalize coeffs by dividing by absolute value of sum C 1046 INIT = 1 C once kernel coefs set dont recompute C C ************************************************************* C now apply filter just built C 1049 continue do 1100 i=1,512 C TMP = 0. ZEROS = 0 !nuber of zero data values in 3x3 input data C do 1050 j=1,3 ielem = i-2+j if(ielem .le. 0)ielem=1 if(ielem .gt. 512)ielem=512 IWORD = BUF1(IELEM) C GET UNSIGNED POSITIVE BYTE if(IWORD.eq.0)ZEROS=ZEROS+1 !inc count of null data TMP=TMP+ (KERNEL(1,j)) * ( IWORD .and. "377 ) IWORD = BUF2(IELEM) C GET UNSIGNED POSITIVE BYTE if(IWORD.eq.0 .and. j.ne.2 )ZEROS=ZEROS+1 !inc TMP=TMP+ (KERNEL(2,j)) * ( IWORD .and. "377 ) IWORD = BUF3(IELEM) C GET UNSIGNED POSITIVE BYTE if(IWORD.eq.0)ZEROS=ZEROS+1 !inc count of null data TMP=TMP+ (KERNEL(3,j)) * ( IWORD .and. "377 ) 1050 continue C C C C now store byte away if( TMP .gt. 255.)TMP = 255. if( TMP .lt. 0.)TMP = 0. if( ITYPE .ne. 3 )goto 1090 C C if user has despiking filter then compare avg of 8 nearest neighbors C with the center value. CENTER = BUF2(i) .and. "377 C value of center element C if(ZEROS .ge. 8)goto 1060 !if all are zero keep center TMP = TMP * (8. / (8.-ZEROS)) !scaleup to account for null data if(TMP .gt. 255.)TMP=255. !keep withina byte C if( abs(TMP-CENTER)/TMP .gt. PERCNT )goto 1090 C 1060 TMP = CENTER C if ratio is not out of range then store back in the original pt. C 1090 BUF4(i) = TMP C 1100 continue return end