# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc. include include define AVG 1 # operation = arithmetic average define SUM 2 # operation = arithmetic sum # change to (lrdx) in future $for (lrd) # BLKAVG -- Block average or sum on n-dimensional images. # For example, block averaging by a factor of 2 means that pixels 1 and 2 # are averaged to produce the first output pixel, 3 and 4 are averaged to # produce the second output pixel, and so on. Remainder pixels at the end # of a line, col, etc. are averaged correctly. procedure blkav$t (im1, im2, blkfac, option) pointer im1 # input image pointer im2 # output image int blkfac[IM_MAXDIM] # blocking factors int option # block operation (average, sum, ...) int num_oblks[IM_MAXDIM], i, count, ndim, dim, nlines_in_sum, nfull_blkx int junk, num_ilines, num_olines, oline long blkin_s[IM_MAXDIM], blkin_e[IM_MAXDIM] long vin_s[IM_MAXDIM], vin_e[IM_MAXDIM], vout[IM_MAXDIM] $if (datatype != l) PIXEL sum $else real sum $endif pointer sp, accum_ptr, iline_ptr, oline_ptr int blkcomp(), imggs$t(), impnl$t() errchk imggs$t(), impnl$t() begin call smark (sp) call salloc (accum_ptr, IM_LEN(im1, 1), TY_PIXEL) # Initialize; input and output vectors, block counters. ndim = IM_NDIM(im1) nfull_blkx = IM_LEN(im1, 1) / blkfac[1] blkin_s[1] = long(1) blkin_e[1] = long(IM_LEN(im1, 1)) vin_s[1] = blkin_s[1] vin_e[1] = blkin_e[1] do i = 1, ndim { num_oblks[i] = (IM_LEN(im1,i) + blkfac[i] - 1) / blkfac[i] IM_LEN(im2, i) = num_oblks[i] } num_olines = 1 do i = 2, ndim num_olines = num_olines * num_oblks[i] call amovkl (long(1), vout, IM_MAXDIM) # For each sequential output-image line, ... do oline = 1, num_olines { call aclr$t (Mem$t[accum_ptr], IM_LEN(im1, 1)) nlines_in_sum = 0 # Compute block vector; initialize dim>1 input vector. num_ilines = blkcomp (im1, blkfac, vout, blkin_s, blkin_e, vin_s, vin_e) # Output pointer; note impnl$t returns vout for NEXT output line. junk = impnl$t (im2, oline_ptr, vout) # For all input lines mapping to current output line, ... do i = 1, num_ilines { # Get line from input image. iline_ptr = imggs$t (im1, vin_s, vin_e, ndim) # Increment general section input vector between block bounds. do dim = 2, ndim { if (vin_s[dim] < blkin_e[dim]) { vin_s[dim] = vin_s[dim] + 1 vin_e[dim] = vin_s[dim] break } else { vin_s[dim] = blkin_s[dim] vin_e[dim] = vin_s[dim] } } # Accumulate line into block sum. Keep track of no. of # lines in sum so that we can compute block average later. call aadd$t (Mem$t[iline_ptr], Mem$t[accum_ptr], Mem$t[accum_ptr], IM_LEN(im1,1)) nlines_in_sum = nlines_in_sum + 1 } # We now have a templine of sums; average/sum into output buffer # first the full blocks using a vop. if (option == AVG) call abav$t (Mem$t[accum_ptr], Mem$t[oline_ptr], nfull_blkx, blkfac[1]) else call absu$t (Mem$t[accum_ptr], Mem$t[oline_ptr], nfull_blkx, blkfac[1]) # Now average/sum the final partial block in x, if any. if (nfull_blkx < num_oblks[1]) { sum = 0$f count = 0 do i = nfull_blkx * blkfac[1] + 1, IM_LEN(im1,1) { sum = sum + Mem$t[accum_ptr+i-1] count = count + 1 } if (option == AVG) Mem$t[oline_ptr+num_oblks[1]-1] = sum / count else Mem$t[oline_ptr+num_oblks[1]-1] = sum } # Block average into output line from the sum of all lines block # averaged in X. if (option == AVG) call adivk$t (Mem$t[oline_ptr], PIXEL(nlines_in_sum), Mem$t[oline_ptr], num_oblks[1]) } call sfree (sp) end $endfor