content: {-# LANGUAGE ForeignFunctionInterface #-}
  module Grenade.Layers.Internal.Pad (
      pad
    , crop
    ) where
  
  import qualified Data.Vector.Storable as U ( unsafeToForeignPtr0, unsafeFromForeignPtr0 )
  
  import           Foreign ( mallocForeignPtrArray, withForeignPtr )
  import           Foreign.Ptr ( Ptr )
  
  import           Numeric.LinearAlgebra ( flatten, Matrix )
  import qualified Numeric.LinearAlgebra.Devel as U
  
  import           System.IO.Unsafe ( unsafePerformIO )
  
  pad :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Matrix Double -> Matrix Double
  pad channels padLeft padTop padRight padBottom rows cols rows' cols' m
   = let outMatSize      = rows' * cols' * channels
         vec             = flatten m
     in unsafePerformIO $ do
       outPtr        <- mallocForeignPtrArray outMatSize
       let (inPtr, _) = U.unsafeToForeignPtr0 vec
  
       withForeignPtr inPtr $ \inPtr' ->
         withForeignPtr outPtr $ \outPtr' ->
           pad_cpu inPtr' channels rows cols padLeft padTop padRight padBottom outPtr'
  
       let matVec = U.unsafeFromForeignPtr0 outPtr outMatSize
       return (U.matrixFromVector U.RowMajor (rows' * channels) cols' matVec)
  {-# INLINE pad #-}
  
  foreign import ccall unsafe
      pad_cpu
        :: Ptr Double -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Ptr Double -> IO ()
  
  crop :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Matrix Double -> Matrix Double
  crop channels padLeft padTop padRight padBottom rows cols _ _ m
   = let outMatSize      = rows * cols * channels
         vec             = flatten m
     in unsafePerformIO $ do
       outPtr        <- mallocForeignPtrArray outMatSize
       let (inPtr, _) = U.unsafeToForeignPtr0 vec
  
       withForeignPtr inPtr $ \inPtr' ->
         withForeignPtr outPtr $ \outPtr' ->
           crop_cpu inPtr' channels rows cols padLeft padTop padRight padBottom outPtr'
  
       let matVec = U.unsafeFromForeignPtr0 outPtr outMatSize
       return (U.matrixFromVector U.RowMajor (rows * channels) cols matVec)
  
  foreign import ccall unsafe
      crop_cpu
        :: Ptr Double -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Ptr Double -> IO ()
  