{-# LANGUAGE BangPatterns #-}-- | Functions specialised for arrays of dimension 2.moduleData.Array.Repa.Specialised.Dim2(isInside2,isOutside2,clampToBorder2,makeBordered2)whereimportData.Array.Repa.IndeximportData.Array.Repa.BaseimportData.Array.Repa.Repr.PartitionedimportData.Array.Repa.Repr.Undefined-- | Check if an index lies inside the given extent.-- As opposed to `inRange` from "Data.Array.Repa.Index",-- this is a short-circuited test that checks that lowest dimension first.isInside2::DIM2-- ^ Extent of array.->DIM2-- ^ Index to check.->Bool{-# INLINE isInside2 #-}isInside2ex=not.isOutside2ex-- | Check if an index lies outside the given extent.-- As opposed to `inRange` from "Data.Array.Repa.Index",-- this is a short-circuited test that checks the lowest dimension first.isOutside2::DIM2-- ^ Extent of array.->DIM2-- ^ Index to check.->Bool{-# INLINE isOutside2 #-}isOutside2(_:.yLen:.xLen)(_:.yy:.xx)|xx<0=True|xx>=xLen=True|yy<0=True|yy>=yLen=True|otherwise=False-- | Given the extent of an array, clamp the components of an index so they-- lie within the given array. Outlying indices are clamped to the index-- of the nearest border element.clampToBorder2::DIM2-- ^ Extent of array.->DIM2-- ^ Index to clamp.->DIM2{-# INLINE clampToBorder2 #-}clampToBorder2(_:.yLen:.xLen)(sh:.j:.i)=clampXjiwhere{-# INLINE clampX #-}clampX!y!x|x<0=clampYy0|x>=xLen=clampYy(xLen-1)|otherwise=clampYyx{-# INLINE clampY #-}clampY!y!x|y<0=sh:.0:.x|y>=yLen=sh:.(yLen-1):.x|otherwise=sh:.y:.x-- | Make a 2D partitioned array from two others, one to produce the elements-- in the internal region, and one to produce elements in the border region.-- The two arrays must have the same extent.-- The border must be the same width on all sides.--makeBordered2::(Reprr1a,Reprr2a)=>DIM2-- ^ Extent of array.->Int-- ^ Width of border.->Arrayr1DIM2a-- ^ Array for internal elements.->Arrayr2DIM2a-- ^ Array for border elements.->Array(Pr1(Pr2(Pr2(Pr2(Pr2X)))))DIM2a{-# INLINE makeBordered2 #-}makeBordered2sh@(_:.aHeight:.aWidth)bWidtharrInternalarrBorder=checkDims`seq`let-- minimum and maximum indicies of values in the inner part of the image.!inX=bWidth!inY=bWidth!inW=aWidth-2*bWidth!inH=aHeight-2*bWidthinInternal(Z:.y:.x)=x>=inX&&x<(inX+inW)&&y>=inY&&y<(inY+inH){-# INLINE inInternal #-}inBorder=not.inInternal{-# INLINE inBorder #-}in-- internal regionAPartsh(Range(Z:.inY:.inX)(Z:.inH:.inW)inInternal)arrInternal-- border regions$APartsh(Range(Z:.0:.0)(Z:.bWidth:.aWidth)inBorder)arrBorder$APartsh(Range(Z:.inY+inH:.0)(Z:.bWidth:.aWidth)inBorder)arrBorder$APartsh(Range(Z:.inY:.0)(Z:.inH:.bWidth)inBorder)arrBorder$APartsh(Range(Z:.inY:.inX+inW)(Z:.inH:.bWidth)inBorder)arrBorder$AUndefinedshwherecheckDims=if(extentarrInternal)==(extentarrBorder)then()elseerror"makeBordered2: internal and border arrays have different extents"{-# NOINLINE checkDims #-}-- NOINLINE because we don't want the branch in the core code.