{-# LANGUAGE ScopedTypeVariables #-}
-- | Minimal operations on small vector types.
module Codec.FFmpeg.Internal.Linear where
import Foreign.C.Types
import Foreign.Ptr (castPtr)
import Foreign.Storable

-- | A two-component vector
data V2 a = V2 !a !a

-- | A three-component vector
data V3 a = V3 !a !a !a

instance Functor V3 where
  fmap :: (a -> b) -> V3 a -> V3 b
fmap f :: a -> b
f (V3 x :: a
x y :: a
y z :: a
z) = b -> b -> b -> V3 b
forall a. a -> a -> a -> V3 a
V3 (a -> b
f a
x) (a -> b
f a
y) (a -> b
f a
z)

instance Storable a => Storable (V3 a) where
  sizeOf :: V3 a -> Int
sizeOf _ = 3 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined::a)
  alignment :: V3 a -> Int
alignment _ = a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined::a)
  peek :: Ptr (V3 a) -> IO (V3 a)
peek ptr :: Ptr (V3 a)
ptr = let ptr' :: Ptr b
ptr' = Ptr (V3 a) -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr (V3 a)
ptr
             in a -> a -> a -> V3 a
forall a. a -> a -> a -> V3 a
V3 (a -> a -> a -> V3 a) -> IO a -> IO (a -> a -> V3 a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
forall b. Ptr b
ptr' IO (a -> a -> V3 a) -> IO a -> IO (a -> V3 a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
forall b. Ptr b
ptr' 1 IO (a -> V3 a) -> IO a -> IO (V3 a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
forall b. Ptr b
ptr' 2
  poke :: Ptr (V3 a) -> V3 a -> IO ()
poke ptr :: Ptr (V3 a)
ptr (V3 x :: a
x y :: a
y z :: a
z) = let ptr' :: Ptr b
ptr' = Ptr (V3 a) -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr (V3 a)
ptr
                        in do Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
forall b. Ptr b
ptr' a
x
                              Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
forall b. Ptr b
ptr' 1 a
y
                              Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
forall b. Ptr b
ptr' 2 a
z

-- | Quadrance between two 3D points.
qd :: V3 CInt -> V3 CInt -> CInt
qd :: V3 CInt -> V3 CInt -> CInt
qd (V3 x1 :: CInt
x1 y1 :: CInt
y1 z1 :: CInt
z1) (V3 x2 :: CInt
x2 y2 :: CInt
y2 z2 :: CInt
z2) = let dx :: CInt
dx = CInt
x2 CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
- CInt
x1
                                     dy :: CInt
dy = CInt
y2 CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
- CInt
y1
                                     dz :: CInt
dz = CInt
z2 CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
- CInt
z1
                                 in CInt
dx CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
* CInt
dx CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
+ CInt
dy CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
* CInt
dy CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
+ CInt
dz CInt -> CInt -> CInt
forall a. Num a => a -> a -> a
* CInt
dz

-- | A four-component vector
data V4 a = V4 !a !a !a !a

instance Functor V4 where
  fmap :: (a -> b) -> V4 a -> V4 b
fmap f :: a -> b
f (V4 x :: a
x y :: a
y z :: a
z w :: a
w) = b -> b -> b -> b -> V4 b
forall a. a -> a -> a -> a -> V4 a
V4 (a -> b
f a
x) (a -> b
f a
y) (a -> b
f a
z) (a -> b
f a
w)

instance Storable a => Storable (V4 a) where
  sizeOf :: V4 a -> Int
sizeOf _ = 4 Int -> Int -> Int
forall a. Num a => a -> a -> a
* a -> Int
forall a. Storable a => a -> Int
sizeOf (a
forall a. HasCallStack => a
undefined::a)
  alignment :: V4 a -> Int
alignment _ = a -> Int
forall a. Storable a => a -> Int
alignment (a
forall a. HasCallStack => a
undefined::a)
  peek :: Ptr (V4 a) -> IO (V4 a)
peek ptr :: Ptr (V4 a)
ptr = let ptr' :: Ptr b
ptr' = Ptr (V4 a) -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr (V4 a)
ptr
             in a -> a -> a -> a -> V4 a
forall a. a -> a -> a -> a -> V4 a
V4 (a -> a -> a -> a -> V4 a) -> IO a -> IO (a -> a -> a -> V4 a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr a -> IO a
forall a. Storable a => Ptr a -> IO a
peek Ptr a
forall b. Ptr b
ptr' IO (a -> a -> a -> V4 a) -> IO a -> IO (a -> a -> V4 a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
forall b. Ptr b
ptr' 1
                   IO (a -> a -> V4 a) -> IO a -> IO (a -> V4 a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
forall b. Ptr b
ptr' 2 IO (a -> V4 a) -> IO a -> IO (V4 a)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr a -> Int -> IO a
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr a
forall b. Ptr b
ptr' 3
  poke :: Ptr (V4 a) -> V4 a -> IO ()
poke ptr :: Ptr (V4 a)
ptr (V4 x :: a
x y :: a
y z :: a
z w :: a
w) = let ptr' :: Ptr b
ptr' = Ptr (V4 a) -> Ptr b
forall a b. Ptr a -> Ptr b
castPtr Ptr (V4 a)
ptr
                          in do Ptr a -> a -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr a
forall b. Ptr b
ptr' a
x
                                Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
forall b. Ptr b
ptr' 1 a
y
                                Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
forall b. Ptr b
ptr' 2 a
z
                                Ptr a -> Int -> a -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr a
forall b. Ptr b
ptr' 3 a
w