diff --git a/default.nix b/default.nix index 15b4ff6a..3dc4c983 100644 --- a/default.nix +++ b/default.nix @@ -1,7 +1,7 @@ -{ nixpkgs ? import ./nixpkgs.nix, enableOpencv4 ? false +{ nixpkgs ? import ./nixpkgs.nix , system ? builtins.currentSystem }: import nixpkgs { inherit system; - overlays = [ (import ./overlay.nix enableOpencv4) ]; + overlays = [ (import ./overlay.nix) ]; } diff --git a/doc/ExampleExtractor.hs b/doc/ExampleExtractor.hs index 6ab9af45..6ec3ffc4 100644 --- a/doc/ExampleExtractor.hs +++ b/doc/ExampleExtractor.hs @@ -35,7 +35,7 @@ import qualified "bytestring" Data.ByteString as B import qualified "bytestring" Data.ByteString.Lazy as BL import "template-haskell" Language.Haskell.TH import "template-haskell" Language.Haskell.TH.Syntax -import "this" Language.Haskell.Meta.Syntax.Translate ( toDecs ) +import "haskell-src-meta" Language.Haskell.Meta.Syntax.Translate ( toDecs ) #if !MIN_VERSION_base(4,11,0) import "base" Data.Monoid @@ -269,7 +269,7 @@ mkRenderExampleImages renderTargets = [d| where doRender :: Exp doRender = - DoE $ do + DoE Nothing $ do rt <- renderTargets let sym = VarE $ rtSymbolName rt fp = LitE $ StringL $ "examples/" <> rtDestination rt diff --git a/doc/Language/Haskell/Meta/Syntax/Translate.hs b/doc/Language/Haskell/Meta/Syntax/Translate.hs deleted file mode 100644 index e6854dff..00000000 --- a/doc/Language/Haskell/Meta/Syntax/Translate.hs +++ /dev/null @@ -1,657 +0,0 @@ -{-# LANGUAGE CPP, TemplateHaskell, TypeSynonymInstances, FlexibleInstances #-} - -{- | - Module : Language.Haskell.Meta.Syntax.Translate - Copyright : (c) Matt Morrow 2008 - License : BSD3 - Maintainer : Matt Morrow - Stability : experimental - Portability : portable (template-haskell) --} - -module Language.Haskell.Meta.Syntax.Translate ( - module Language.Haskell.Meta.Syntax.Translate -) where - -import Data.Char (ord, isUpper) -import Data.Typeable -import Data.List (foldl', nub, (\\)) -import Language.Haskell.TH.Syntax -import qualified Language.Haskell.Exts.SrcLoc as Hs -import qualified Language.Haskell.Exts.Syntax as Hs - ------------------------------------------------------------------------------ - - -class ToName a where toName :: a -> Name -class ToNames a where toNames :: a -> [Name] -class ToLit a where toLit :: a -> Lit -class ToType a where toType :: a -> Type -class ToPat a where toPat :: a -> Pat -class ToExp a where toExp :: a -> Exp -class ToDecs a where toDecs :: a -> [Dec] -class ToDec a where toDec :: a -> Dec -class ToStmt a where toStmt :: a -> Stmt -class ToLoc a where toLoc :: a -> Loc -class ToCxt a where toCxt :: a -> Cxt -class ToPred a where toPred :: a -> Pred -class ToTyVars a where toTyVars :: a -> [TyVarBndr] -class ToMaybeKind a where toMaybeKind :: a -> Maybe Kind -class ToInjectivityAnn a where toInjectivityAnn :: a -> InjectivityAnn - --- for error messages -moduleName = "Language.Haskell.Meta.Syntax.Translate" - --- When to use each of these isn't always clear: prefer 'todo' if unsure. -noTH :: (Functor f, Show (f ())) => String -> f e -> a -noTH fun thing = error . concat $ [moduleName, ".", fun, - ": template-haskell has no representation for: ", show (fmap (const ()) thing)] - -noTHyet :: (Functor f, Show (f ())) => String -> String -> f e -> a -noTHyet fun minVersion thing = error . concat $ [moduleName, ".", fun, - ": template-haskell-", VERSION_template_haskell, " (< ", minVersion, ")", - " has no representation for: ", show (fmap (const ()) thing)] - -todo :: (Functor f, Show (f ())) => String -> f e -> a -todo fun thing = error . concat $ [moduleName, ".", fun, - ": not implemented: ", show (fmap (const ()) thing)] - -nonsense :: (Functor f, Show (f ())) => String -> String -> f e -> a -nonsense fun inparticular thing = error . concat $ [moduleName, ".", fun, - ": nonsensical: ", inparticular, ": ", show (fmap (const ()) thing)] - ------------------------------------------------------------------------------ - - -instance ToExp Lit where - toExp = LitE -instance (ToExp a) => ToExp [a] where - toExp = ListE . fmap toExp -instance (ToExp a, ToExp b) => ToExp (a,b) where - toExp (a,b) = TupE [toExp a, toExp b] -instance (ToExp a, ToExp b, ToExp c) => ToExp (a,b,c) where - toExp (a,b,c) = TupE [toExp a, toExp b, toExp c] -instance (ToExp a, ToExp b, ToExp c, ToExp d) => ToExp (a,b,c,d) where - toExp (a,b,c,d) = TupE [toExp a, toExp b, toExp c, toExp d] - - -instance ToPat Lit where - toPat = LitP -instance (ToPat a) => ToPat [a] where - toPat = ListP . fmap toPat -instance (ToPat a, ToPat b) => ToPat (a,b) where - toPat (a,b) = TupP [toPat a, toPat b] -instance (ToPat a, ToPat b, ToPat c) => ToPat (a,b,c) where - toPat (a,b,c) = TupP [toPat a, toPat b, toPat c] -instance (ToPat a, ToPat b, ToPat c, ToPat d) => ToPat (a,b,c,d) where - toPat (a,b,c,d) = TupP [toPat a, toPat b, toPat c, toPat d] - - -instance ToLit Char where - toLit = CharL -instance ToLit String where - toLit = StringL -instance ToLit Integer where - toLit = IntegerL -instance ToLit Int where - toLit = IntegerL . toInteger -instance ToLit Float where - toLit = RationalL . toRational -instance ToLit Double where - toLit = RationalL . toRational - - ------------------------------------------------------------------------------ - - --- * ToName {String,HsName,Module,HsSpecialCon,HsQName} - - -instance ToName String where - toName = mkName - -instance ToName (Hs.Name l) where - toName (Hs.Ident _ s) = toName s - toName (Hs.Symbol _ s) = toName s - -instance ToName (Hs.SpecialCon l) where - toName (Hs.UnitCon _) = '() - toName (Hs.ListCon _) = '[] - toName (Hs.FunCon _) = ''(->) - toName (Hs.TupleCon _ _ n) - | n<2 = '() - | otherwise = - let x = maybe [] (++".") (nameModule '(,)) - in mkName . concat $ x : ["(",replicate (n-1) ',',")"] - toName (Hs.Cons _) = '(:) - - -instance ToName (Hs.QName l) where --- toName (Hs.Qual (Hs.Module []) n) = toName n - toName (Hs.Qual _ (Hs.ModuleName _ []) n) = toName n - toName (Hs.Qual _ (Hs.ModuleName _ m) n) = - let m' = show . toName $ m - n' = show . toName $ n - in toName . concat $ [m',".",n'] - toName (Hs.UnQual _ n) = toName n - toName (Hs.Special _ s) = toName s - -#if MIN_VERSION_haskell_src_exts(1,20,1) -instance ToName (Hs.MaybePromotedName l) where - toName (Hs.PromotedName _ qn) = toName qn - toName (Hs.UnpromotedName _ qn) = toName qn -#endif - -instance ToName (Hs.Op l) where - toName (Hs.VarOp _ n) = toName n - toName (Hs.ConOp _ n) = toName n - - ------------------------------------------------------------------------------ - --- * ToLit HsLiteral - - -instance ToLit (Hs.Literal l) where - toLit (Hs.Char _ a _) = CharL a - toLit (Hs.String _ a _) = StringL a - toLit (Hs.Int _ a _) = IntegerL a - toLit (Hs.Frac _ a _) = RationalL a - toLit l@Hs.PrimChar{} = noTH "toLit" l - toLit (Hs.PrimString _ a _) = StringPrimL (map toWord8 a) - where - toWord8 = fromIntegral . ord - toLit (Hs.PrimInt _ a _) = IntPrimL a - toLit (Hs.PrimFloat _ a _) = FloatPrimL a - toLit (Hs.PrimDouble _ a _) = DoublePrimL a - toLit (Hs.PrimWord _ a _) = WordPrimL a - - ------------------------------------------------------------------------------ - --- * ToPat HsPat - - -instance ToPat (Hs.Pat l) where - toPat (Hs.PVar _ n) - = VarP (toName n) - toPat (Hs.PLit _ (Hs.Signless _) l) - = LitP (toLit l) - toPat (Hs.PLit _ (Hs.Negative _) l) = LitP $ case toLit l of - IntegerL z -> IntegerL (negate z) - RationalL q -> RationalL (negate q) - IntPrimL z' -> IntPrimL (negate z') - FloatPrimL r' -> FloatPrimL (negate r') - DoublePrimL r'' -> DoublePrimL (negate r'') - _ -> nonsense "toPat" "negating wrong kind of literal" l - toPat (Hs.PInfixApp _ p n q) = UInfixP (toPat p) (toName n) (toPat q) - toPat (Hs.PApp _ n ps) = ConP (toName n) (fmap toPat ps) - toPat (Hs.PTuple _ Hs.Boxed ps) = TupP (fmap toPat ps) - toPat (Hs.PTuple _ Hs.Unboxed ps) = UnboxedTupP (fmap toPat ps) - toPat (Hs.PList _ ps) = ListP (fmap toPat ps) - toPat (Hs.PParen _ p) = ParensP (toPat p) - toPat (Hs.PRec _ n pfs) = let toFieldPat (Hs.PFieldPat _ n p) = (toName n, toPat p) - in RecP (toName n) (fmap toFieldPat pfs) - toPat (Hs.PAsPat _ n p) = AsP (toName n) (toPat p) - toPat (Hs.PWildCard _) = WildP - toPat (Hs.PIrrPat _ p) = TildeP (toPat p) - toPat (Hs.PatTypeSig _ p t) = SigP (toPat p) (toType t) - toPat (Hs.PViewPat _ e p) = ViewP (toExp e) (toPat p) - -- regular pattern - toPat p@Hs.PRPat{} = noTH "toPat" p - -- XML stuff - toPat p@Hs.PXTag{} = noTH "toPat" p - toPat p@Hs.PXETag{} = noTH "toPat" p - toPat p@Hs.PXPcdata{} = noTH "toPat" p - toPat p@Hs.PXPatTag{} = noTH "toPat" p - toPat (Hs.PBangPat _ p) = BangP (toPat p) - toPat p = todo "toPat" p - ------------------------------------------------------------------------------ - --- * ToExp HsExp - -instance ToExp (Hs.QOp l) where - toExp (Hs.QVarOp _ n) = VarE (toName n) - toExp (Hs.QConOp _ n) = ConE (toName n) - -toFieldExp :: Hs.FieldUpdate l -> FieldExp -toFieldExp (Hs.FieldUpdate _ n e) = (toName n, toExp e) - - - - -instance ToExp (Hs.Exp l) where - toExp (Hs.Var _ n) = VarE (toName n) - toExp e@Hs.IPVar{} = noTH "toExp" e - toExp (Hs.Con _ n) = ConE (toName n) - toExp (Hs.Lit _ l) = LitE (toLit l) - toExp (Hs.InfixApp _ e o f) = UInfixE (toExp e) (toExp o) (toExp f) - toExp (Hs.App _ e f) = AppE (toExp e) (toExp f) - toExp (Hs.NegApp _ e) = AppE (VarE 'negate) (toExp e) - toExp (Hs.Lambda _ ps e) = LamE (fmap toPat ps) (toExp e) - toExp (Hs.Let _ bs e) = LetE (toDecs bs) (toExp e) - toExp (Hs.If _ a b c) = CondE (toExp a) (toExp b) (toExp c) - toExp (Hs.MultiIf _ ifs) = MultiIfE (map toGuard ifs) - toExp (Hs.Case _ e alts) = CaseE (toExp e) (map toMatch alts) - toExp (Hs.Do _ ss) = DoE (map toStmt ss) - toExp e@(Hs.MDo _ _) = noTH "toExp" e - toExp (Hs.Tuple _ Hs.Boxed xs) = TupE (fmap toExp xs) - toExp (Hs.Tuple _ Hs.Unboxed xs) = UnboxedTupE (fmap toExp xs) - toExp e@Hs.TupleSection{} = noTH "toExp" e - toExp (Hs.List _ xs) = ListE (fmap toExp xs) - toExp (Hs.Paren _ e) = ParensE (toExp e) - toExp (Hs.LeftSection _ e o) = InfixE (Just . toExp $ e) (toExp o) Nothing - toExp (Hs.RightSection _ o f) = InfixE Nothing (toExp o) (Just . toExp $ f) - toExp (Hs.RecConstr _ n xs) = RecConE (toName n) (fmap toFieldExp xs) - toExp (Hs.RecUpdate _ e xs) = RecUpdE (toExp e) (fmap toFieldExp xs) - toExp (Hs.EnumFrom _ e) = ArithSeqE $ FromR (toExp e) - toExp (Hs.EnumFromTo _ e f) = ArithSeqE $ FromToR (toExp e) (toExp f) - toExp (Hs.EnumFromThen _ e f) = ArithSeqE $ FromThenR (toExp e) (toExp f) - toExp (Hs.EnumFromThenTo _ e f g) = ArithSeqE $ FromThenToR (toExp e) (toExp f) (toExp g) - toExp (Hs.ListComp _ e ss) = CompE $ map convert ss ++ [NoBindS (toExp e)] - where - convert (Hs.QualStmt _ st) = toStmt st - convert s = noTH "toExp ListComp" s - toExp (Hs.ExpTypeSig _ e t) = SigE (toExp e) (toType t) - toExp e = todo "toExp" e - - -toMatch :: Hs.Alt l -> Match -toMatch (Hs.Alt _ p rhs ds) = Match (toPat p) (toBody rhs) (toDecs ds) - -toBody :: Hs.Rhs l -> Body -toBody (Hs.UnGuardedRhs _ e) = NormalB $ toExp e -toBody (Hs.GuardedRhss _ rhss) = GuardedB $ map toGuard rhss - -toGuard (Hs.GuardedRhs _ stmts e) = (g, toExp e) - where - g = case map toStmt stmts of - [NoBindS x] -> NormalG x - xs -> PatG xs - -instance ToDecs a => ToDecs (Maybe a) where - toDecs Nothing = [] - toDecs (Just a) = toDecs a - -instance ToDecs (Hs.Binds l) where - toDecs (Hs.BDecls _ ds) = toDecs ds - toDecs a@(Hs.IPBinds {}) = noTH "ToDecs Hs.Binds" a - -instance ToDecs (Hs.ClassDecl l) where - toDecs (Hs.ClsDecl _ d) = toDecs d - toDecs x = todo "classDecl" x - ------------------------------------------------------------------------------ - --- * ToLoc SrcLoc - -instance ToLoc Hs.SrcLoc where - toLoc (Hs.SrcLoc fn l c) = - Loc fn [] [] (l,c) (-1,-1) - ------------------------------------------------------------------------------ - --- * ToType HsType - -instance ToName (Hs.TyVarBind l) where - toName (Hs.KindedVar _ n _) = toName n - toName (Hs.UnkindedVar _ n) = toName n - -instance ToName Name where - toName = id - -instance ToName TyVarBndr where - toName (PlainTV n) = n - toName (KindedTV n _) = n - -toKind :: Hs.Kind l -> Kind -toKind = toType - -toTyVar :: Hs.TyVarBind l -> TyVarBndr -toTyVar (Hs.KindedVar _ n k) = KindedTV (toName n) (toKind k) -toTyVar (Hs.UnkindedVar _ n) = PlainTV (toName n) - -instance ToType (Hs.Type l) where - toType (Hs.TyStar _) = StarT - toType (Hs.TyForall _ tvbM cxt t) = ForallT (maybe [] (fmap toTyVar) tvbM) (toCxt cxt) (toType t) - toType (Hs.TyFun _ a b) = toType a .->. toType b - toType (Hs.TyList _ t) = ListT `AppT` toType t - toType (Hs.TyTuple _ b ts) = foldAppT (tuple . length $ ts) (fmap toType ts) - where - tuple = case b of - Hs.Boxed -> TupleT - Hs.Unboxed -> UnboxedTupleT - toType (Hs.TyApp _ a b) = AppT (toType a) (toType b) - toType (Hs.TyVar _ n) = VarT (toName n) - toType (Hs.TyCon _ qn) = ConT (toName qn) - toType (Hs.TyParen _ t) = toType t - -- XXX: need to wrap the name in parens! - toType (Hs.TyInfix _ a o b) = AppT (AppT (ConT (toName o)) (toType a)) (toType b) - toType (Hs.TyKind _ t k) = SigT (toType t) (toKind k) - toType (Hs.TyPromoted _ p) = - case p of - Hs.PromotedInteger _ i _ -> LitT $ NumTyLit i - Hs.PromotedString _ _ s -> LitT $ StrTyLit s - Hs.PromotedCon _ _q n -> PromotedT (toName n) - Hs.PromotedList _ _q ts -> foldr (\t pl -> PromotedConsT `AppT` toType t `AppT` pl) PromotedNilT ts - Hs.PromotedTuple _ ts -> foldr (\t pt -> pt `AppT` toType t) (PromotedTupleT $ length ts) ts - Hs.PromotedUnit _ -> PromotedT ''() - toType (Hs.TyEquals _ t1 t2) = EqualityT `AppT` toType t1 `AppT` toType t2 - toType t@(Hs.TySplice _ _) = noTH "toType" t - toType t@Hs.TyBang{} = - nonsense "toType" "type cannot have strictness annotations in this context" t - toType t@(Hs.TyWildCard _ _) = noTH "toType" t - toType t = todo "toType" t - -toStrictType :: Hs.Type l -> StrictType -toStrictType (Hs.TyBang _ s u t) = (Bang (toUnpack u) (toStrict s), toType t) - where - toStrict (Hs.LazyTy _) = SourceLazy - toStrict (Hs.BangedTy _) = SourceStrict - toStrict (Hs.NoStrictAnnot _) = NoSourceStrictness - toUnpack (Hs.Unpack _) = SourceUnpack - toUnpack (Hs.NoUnpack _) = SourceNoUnpack - toUnpack (Hs.NoUnpackPragma _) = NoSourceUnpackedness -toStrictType x = (Bang NoSourceUnpackedness NoSourceStrictness, toType x) - - -(.->.) :: Type -> Type -> Type -a .->. b = AppT (AppT ArrowT a) b - -instance ToPred (Hs.Asst l) where - toPred (Hs.ClassA _ n ts) = foldl' AppT (ConT (toName n)) (fmap toType ts) - toPred (Hs.InfixA _ t1 n t2) = foldl' AppT (ConT (toName n)) (fmap toType [t1,t2]) - toPred (Hs.EqualP _ t1 t2) = foldl' AppT EqualityT (fmap toType [t1,t2]) - toPred (Hs.ParenA _ asst) = toPred asst - toPred a@Hs.AppA{} = todo "toCxt" a - toPred a@Hs.WildCardA{} = todo "toCxt" a - toPred a@Hs.IParam{} = noTH "toCxt" a - toPred p = todo "toPred" p - -instance ToCxt (Hs.Deriving l) where -#if MIN_VERSION_haskell_src_exts(1,20,1) - toCxt (Hs.Deriving _ _ rule) = toCxt rule -#else - toCxt (Hs.Deriving _ rule) = toCxt rule -#endif - -instance ToCxt [Hs.InstRule l] where - toCxt = concatMap toCxt - -instance ToCxt a => ToCxt (Maybe a) where - toCxt Nothing = [] - toCxt (Just a) = toCxt a - -foldAppT :: Type -> [Type] -> Type -foldAppT t ts = foldl' AppT t ts - ------------------------------------------------------------------------------ - --- * ToStmt HsStmt - -instance ToStmt (Hs.Stmt l) where - toStmt (Hs.Generator _ p e) = BindS (toPat p) (toExp e) - toStmt (Hs.Qualifier _ e) = NoBindS (toExp e) - toStmt a@(Hs.LetStmt _ bnds) = LetS (toDecs bnds) - toStmt s@Hs.RecStmt{} = noTH "toStmt" s - - ------------------------------------------------------------------------------ - --- * ToDec HsDecl - -instance ToDec (Hs.Decl l) where - toDec (Hs.TypeDecl _ h t) - = TySynD (toName h) (toTyVars h) (toType t) - - toDec a@(Hs.DataDecl _ dOrN cxt h qcds qns) - = case dOrN of - Hs.DataType _ -> DataD (toCxt cxt) - (toName h) - (toTyVars h) - Nothing - (fmap qualConDeclToCon qcds) - [] -- TODO (BvD): convert the deriving clause. - Hs.NewType _ -> let qcd = case qcds of - [x] -> x - _ -> nonsense "toDec" ("newtype with " ++ - "wrong number of constructors") a - in NewtypeD (toCxt cxt) - (toName h) - (toTyVars h) - Nothing - (qualConDeclToCon qcd) - [] -- TODO (BvD): convert the deriving clause. - - -- This type-signature conversion is just wrong. - -- Type variables need to be dealt with. /Jonas - toDec a@(Hs.TypeSig _ ns t) - -- XXXXXXXXXXXXXX: oh crap, we can't return a [Dec] from this class! - = let xs = fmap (flip SigD (toType t) . toName) ns - in case xs of x:_ -> x; [] -> error "toDec: malformed TypeSig!" - - toDec (Hs.InlineConlikeSig _ act qn) = PragmaD $ - InlineP (toName qn) Inline ConLike (transAct act) - toDec (Hs.InlineSig _ b act qn) = PragmaD $ - InlineP (toName qn) inline FunLike (transAct act) - where - inline | b = Inline | otherwise = NoInline - - toDec (Hs.TypeFamDecl _ h sig inj) - = OpenTypeFamilyD $ TypeFamilyHead (toName h) - (toTyVars h) - (maybe NoSig KindSig . toMaybeKind $ sig) - (fmap toInjectivityAnn inj) - toDec (Hs.DataFamDecl _ _ h sig) - = DataFamilyD (toName h) (toTyVars h) (toMaybeKind sig) - - toDec a@(Hs.FunBind _ mtchs) = hsMatchesToFunD mtchs - toDec (Hs.PatBind _ p rhs bnds) = ValD (toPat p) - (hsRhsToBody rhs) - (toDecs bnds) - - toDec i@(Hs.InstDecl _ (Just overlap) _ _) = - noTH "toDec" (fmap (const ()) overlap, i) - - -- the 'vars' bit seems to be for: instance forall a. C (T a) where ... - -- TH's own parser seems to flat-out ignore them, and honestly I can't see - -- that it's obviously wrong to do so. - toDec (Hs.InstDecl _ Nothing irule ids) = InstanceD - Nothing - (toCxt irule) - (toType irule) - (toDecs ids) - - toDec (Hs.ClassDecl _ cxt h fds decls) = ClassD - (toCxt cxt) - (toName h) - (toTyVars h) - (fmap toFunDep fds) - (toDecs decls) - where - toFunDep (Hs.FunDep _ ls rs) = FunDep (fmap toName ls) (fmap toName rs) - - toDec x = todo "toDec" x - -instance ToMaybeKind (Hs.ResultSig l) where - toMaybeKind (Hs.KindSig _ k) = Just $ toKind k - toMaybeKind (Hs.TyVarSig _ _) = Nothing - -instance ToMaybeKind a => ToMaybeKind (Maybe a) where - toMaybeKind Nothing = Nothing - toMaybeKind (Just a) = toMaybeKind a - -instance ToInjectivityAnn (Hs.InjectivityInfo l) where - toInjectivityAnn (Hs.InjectivityInfo _ n ns) = InjectivityAnn (toName n) (fmap toName ns) - -transAct :: Maybe (Hs.Activation l) -> Phases -transAct Nothing = AllPhases -transAct (Just (Hs.ActiveFrom _ n)) = FromPhase n -transAct (Just (Hs.ActiveUntil _ n)) = BeforePhase n - -instance ToName (Hs.DeclHead l) where - toName (Hs.DHead _ n) = toName n - toName (Hs.DHInfix _ _ n) = toName n - toName (Hs.DHParen _ h) = toName h - toName (Hs.DHApp _ h _) = toName h - -instance ToTyVars (Hs.DeclHead l) where - toTyVars (Hs.DHead _ _) = [] - toTyVars (Hs.DHParen _ h) = toTyVars h - toTyVars (Hs.DHInfix _ tvb _) = [toTyVar tvb] - toTyVars (Hs.DHApp _ h tvb) = toTyVars h ++ [toTyVar tvb] - -instance ToNames a => ToNames (Maybe a) where - toNames Nothing = [] - toNames (Just a) = toNames a - -instance ToNames (Hs.Deriving l) where -#if MIN_VERSION_haskell_src_exts(1,20,1) - toNames (Hs.Deriving _ _ irules) = concatMap toNames irules -#else - toNames (Hs.Deriving _ irules) = concatMap toNames irules -#endif -instance ToNames (Hs.InstRule l) where - toNames (Hs.IParen _ irule) = toNames irule - toNames (Hs.IRule _ _mtvbs _mcxt mihd) = toNames mihd -instance ToNames (Hs.InstHead l) where - toNames (Hs.IHCon _ n) = [toName n] - toNames (Hs.IHInfix _ _ n) = [toName n] - toNames (Hs.IHParen _ h) = toNames h - toNames (Hs.IHApp _ h _) = toNames h - -instance ToCxt (Hs.InstRule l) where - toCxt (Hs.IRule _ _ cxt _) = toCxt cxt - toCxt (Hs.IParen _ irule) = toCxt irule - -instance ToCxt (Hs.Context l) where - toCxt x = case x of - Hs.CxEmpty _ -> [] - Hs.CxSingle _ x' -> [toPred x'] - Hs.CxTuple _ xs -> fmap toPred xs - -instance ToType (Hs.InstRule l) where - toType (Hs.IRule _ _ _ h) = toType h - toType (Hs.IParen _ irule) = toType irule - -instance ToType (Hs.InstHead l) where - toType (Hs.IHCon _ qn) = toType qn - toType (Hs.IHInfix _ typ qn) = AppT (toType typ) (toType qn) - toType (Hs.IHParen _ hd) = toType hd - toType (Hs.IHApp _ hd typ) = AppT (toType hd) (toType typ) - -qualConDeclToCon :: Hs.QualConDecl l -> Con -qualConDeclToCon (Hs.QualConDecl _ Nothing Nothing cdecl) = conDeclToCon cdecl -qualConDeclToCon (Hs.QualConDecl _ ns cxt cdecl) = ForallC (toTyVars ns) - (toCxt cxt) - (conDeclToCon cdecl) - -instance ToTyVars a => ToTyVars (Maybe a) where - toTyVars Nothing = [] - toTyVars (Just a) = toTyVars a - -instance ToTyVars a => ToTyVars [a] where - toTyVars = concatMap toTyVars - -instance ToTyVars (Hs.TyVarBind l) where - toTyVars tvb = [toTyVar tvb] - -instance ToType (Hs.QName l) where - toType = ConT . toName - -conDeclToCon :: Hs.ConDecl l -> Con -conDeclToCon (Hs.ConDecl _ n tys) - = NormalC (toName n) (map toStrictType tys) -conDeclToCon (Hs.RecDecl _ n fieldDecls) - = RecC (toName n) (concatMap convField fieldDecls) - where - convField :: Hs.FieldDecl l -> [VarStrictType] - convField (Hs.FieldDecl _ ns t) = - let (strict, ty) = toStrictType t - in map (\n' -> (toName n', strict, ty)) ns - - -hsMatchesToFunD :: [Hs.Match l] -> Dec -hsMatchesToFunD [] = FunD (mkName []) [] -- errorish -hsMatchesToFunD xs@(Hs.Match _ n _ _ _ : _) = FunD (toName n) (fmap hsMatchToClause xs) - - -hsMatchToClause :: Hs.Match l -> Clause -hsMatchToClause (Hs.Match _ _ ps rhs bnds) = Clause - (fmap toPat ps) - (hsRhsToBody rhs) - (toDecs bnds) - - - -hsRhsToBody :: Hs.Rhs l -> Body -hsRhsToBody (Hs.UnGuardedRhs _ e) = NormalB (toExp e) -hsRhsToBody (Hs.GuardedRhss _ hsgrhs) = let fromGuardedB (GuardedB a) = a - in GuardedB . concat - . fmap (fromGuardedB . hsGuardedRhsToBody) - $ hsgrhs - - - -hsGuardedRhsToBody :: Hs.GuardedRhs l -> Body -hsGuardedRhsToBody (Hs.GuardedRhs _ [] e) = NormalB (toExp e) -hsGuardedRhsToBody (Hs.GuardedRhs _ [s] e) = GuardedB [(hsStmtToGuard s, toExp e)] -hsGuardedRhsToBody (Hs.GuardedRhs _ ss e) = let ss' = fmap hsStmtToGuard ss - (pgs,ngs) = unzip [(p,n) - | (PatG p) <- ss' - , n@(NormalG _) <- ss'] - e' = toExp e - patg = PatG (concat pgs) - in GuardedB $ (patg,e') : zip ngs (repeat e') - - - -hsStmtToGuard :: Hs.Stmt l -> Guard -hsStmtToGuard (Hs.Generator _ p e) = PatG [BindS (toPat p) (toExp e)] -hsStmtToGuard (Hs.Qualifier _ e) = NormalG (toExp e) -hsStmtToGuard (Hs.LetStmt _ bs) = PatG [LetS (toDecs bs)] - - ------------------------------------------------------------------------------ - --- * ToDecs InstDecl -instance ToDecs (Hs.InstDecl l) where - toDecs (Hs.InsDecl _ decl) = toDecs decl - toDecs d = todo "toDec" d - --- * ToDecs HsDecl HsBinds - -instance ToDecs (Hs.Decl l) where - toDecs a@(Hs.TypeSig _ ns t) - = let xs = fmap (flip SigD (fixForall $ toType t) . toName) ns - in xs - - toDecs (Hs.InfixDecl l assoc Nothing ops) = - toDecs (Hs.InfixDecl l assoc (Just 9) ops) - toDecs (Hs.InfixDecl _ assoc (Just fixity) ops) = - map (\op -> InfixD (Fixity fixity dir) (toName op)) ops - where - dir = case assoc of - Hs.AssocNone _ -> InfixN - Hs.AssocLeft _ -> InfixL - Hs.AssocRight _ -> InfixR - - toDecs a = [toDec a] - -collectVars e = case e of - VarT n -> [PlainTV n] - AppT t1 t2 -> nub $ collectVars t1 ++ collectVars t2 - ForallT ns _ t -> collectVars t \\ ns - _ -> [] - -fixForall t@(ForallT _ _ _) = t -fixForall t = case vs of - [] -> t - _ -> ForallT vs [] t - where vs = collectVars t - -instance ToDecs a => ToDecs [a] where - toDecs a = concatMap toDecs a - ------------------------------------------------------------------------------ diff --git a/doc/images.hs b/doc/images.hs index 364a518f..9d2cd58f 100644 --- a/doc/images.hs +++ b/doc/images.hs @@ -5,9 +5,12 @@ module Main where +-- These imports are the ones used when parsing haddock examples. + import "base" Data.Functor ( void ) import "base" Data.Foldable ( for_ ) import "base" Data.Int +import "base" Data.Kind ( Type ) import "base" Data.Monoid ( (<>) ) import "base" Data.Proxy import "base" Data.Traversable diff --git a/nix/sources.json b/nix/sources.json index 957823ba..04314a22 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -12,15 +12,15 @@ "url_template": "https://github.com///archive/.tar.gz" }, "nixpkgs": { - "branch": "nixos-unstable", - "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", + "branch": "nixos-23.05", + "description": " Nix Packages collection & NixOS", "homepage": "https://github.com/NixOS/nixpkgs", "owner": "NixOS", - "repo": "nixpkgs-channels", - "rev": "8d1510abfb592339e13ce8f6db6f29c1f8b72924", - "sha256": "0i4jscq2qy2vn9kr8ix9gr8ncf9dss24y09jrqhlpcpryi4i98dc", + "repo": "nixpkgs", + "rev": "da5adce0ffaff10f6d0fee72a02a5ed9d01b52fc", + "sha256": "sha256-32EnPCaVjOiEERZ+o/2Ir7JH9pkfwJZJ27SKHNvt4yk=", "type": "tarball", - "url": "https://github.com/NixOS/nixpkgs-channels/archive/8d1510abfb592339e13ce8f6db6f29c1f8b72924.tar.gz", + "url": "https://github.com/NixOS/nixpkgs/archive/da5adce0ffaff10f6d0fee72a02a5ed9d01b52fc.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/opencv-extra-examples/src/tracker.hs b/opencv-extra-examples/src/tracker.hs index 85f65afe..04574498 100644 --- a/opencv-extra-examples/src/tracker.hs +++ b/opencv-extra-examples/src/tracker.hs @@ -49,8 +49,8 @@ main = do w <- CV.videoCaptureGetI cap VideoCapPropFrameWidth h <- CV.videoCaptureGetI cap VideoCapPropFrameHeight - let trType = BOOSTING - tr <- newTracker trType -- BOOSTING MIL KFC MEDIANFLOW TLD + let trType = KCF + tr <- newTracker trType CV.withWindow "video1" $ \w1 -> loop cap (w, h, tr, trType) w1 where @@ -77,7 +77,7 @@ main = do for_ mbTrac $ \trac -> lift $ CV.rectangle imgM - (CV.fmapRect round trac) + trac white 2 CV.LineType_8 diff --git a/opencv-extra/CHANGELOG.md b/opencv-extra/CHANGELOG.md index 808f524f..8a83b1fe 100644 --- a/opencv-extra/CHANGELOG.md +++ b/opencv-extra/CHANGELOG.md @@ -2,6 +2,39 @@ ### Changed +- OpenCV 4 requirement: + - OpenCV 3 compatibility was dropped to ease maintenance. + For example, Ubuntu 22.04 (1.5 years old as of writing) does not ship OpenCV 3. + If you want this back, please contributed it: + It will require a reasonable amount of `#if`s that can probably be added in 1 day, but would more importantly need a CI setup added so it keeps working. + - Gained a Cabal flag `enable-nonfree` to enable those modules that require the system OpenCV 4 to be compiled with the `OPENCV_ENABLE_NONFREE` option (most OpenCV installations lack this by default). + This means SIFT/SURF feature detection are not available by default. + (Side note: The SIFT patent expired in 2020, thus OpenCV 4.4 supposedly moved SIFT to the main repo, see https://opencv.org/blog/2020/07/18/opencv-4-4-0/, but this Haskell package has not been updated accordingly yet.) + Note that the authors of this Haskell package do not currently fully understand OpenCV's logic here: + On Ubuntu 22.04, OpenCV 4.5 does not include the `opencv2/xfeatures2d/nonfree.hpp` header. + But on NixOS 23.05, `opencv4` version 4.7 does include it, even though `-DOPENCV_ENABLE_NONFREE=OFF` was passed to its build, and so the code builds with the `enable-nonfree` Cabal flag in any case. + - Legacy tracker types were removed. + OpenCV has [split](https://docs.opencv.org/4.8.0/d9/df8/group__tracking.html) their API into "Tracking API" and "Legacy Tracking API. + These have incompatible `Tracker` type hierarchies: + [`cv::Tracker`](https://docs.opencv.org/4.8.0/d0/d0a/classcv_1_1Tracker.html) and + [`cv::legacy::Tracker`](https://docs.opencv.org/4.8.0/db/dfe/classcv_1_1legacy_1_1Tracker.html). + For simplicity, this Haskell binding dropped the legacy API's `TrackerType`s trackers: + - `BOOSTING` + - `MEDIANFLOW` + - `TLD` + If you need these, please let us know and ideally contribute a wrapper for them. + - `initTracker` changed its return type from `Bool` to `()` as the C++ return type is now `void` + - [3.4](https://docs.opencv.org/3.4/d0/d0a/classcv_1_1Tracker.html#a4d285747589b1bdd16d2e4f00c3255dc) + - [4.8](https://docs.opencv.org/4.8.0/d0/d0a/classcv_1_1Tracker.html#a7793a7ccf44ad5c3557ea6029a42a198) + - `initTracker` and `updateTracker` changed their initial `boundingBox` related argument types from `double` to `int`. + - This is because the C++ types changed from `Rect2d` to `Rect` (which is `Rect2i`), for example: + - [3.4](https://docs.opencv.org/3.4/d0/d0a/classcv_1_1Tracker.html#a549159bd0553e6a8de356f3866df1f18) + - [4.8](https://docs.opencv.org/4.8.0/d0/d0a/classcv_1_1Tracker.html#a92d2012f576e6c06eb2e257d110a6529) + - For example, `IsRect rect C.CDouble` to `IsRect rect Int32`. + - The `TrackerFeatureType` was extended to have the `FEATURE2D` constructor carry 2 `String` fields `detectorType` and `descriptorType`. + The previous argument-less type did not really make sense, as one cannot construct a `Feature2d` tracker feature without specifying these. + This was possible in the previous OpenCV 3 API only because its docs said `The modes available now: "HAAR"` and for all other types, including `Feature2d`, it said `The modes that will be available soon`, so that likely never worked. + This change should allow to use the many more feature types from [`Feature2D`](https://docs.opencv.org/4.8.0/d0/d13/classcv_1_1Feature2D.html). - Support versions of Glob < 0.9. diff --git a/opencv-extra/Setup.hs b/opencv-extra/Setup.hs index e2416fc4..96c2fff7 100644 --- a/opencv-extra/Setup.hs +++ b/opencv-extra/Setup.hs @@ -1,8 +1,160 @@ -import Distribution.Simple ( defaultMainArgs ) +import Distribution.Simple ( defaultMainWithHooksArgs, simpleUserHooks ) import System.Environment ( getArgs ) + +-- Source copied from: https://hackage.haskell.org/package/cabal-pkg-config-version-hook-0.1.0.1/docs/src/Distribution.PkgConfigVersionHook.html#addHook +-- TODO: Import this via `setup-depends` instead once it's on Stackage. + +import Control.Lens ((%~), (^.)) +import Control.Monad (when) +import qualified Data.Char as C +import Data.Foldable (toList) +import Data.Function ((&)) +import qualified Data.List as L +import Distribution.Simple (UserHooks (confHook)) +import Distribution.Simple.Setup (ConfigFlags, configConfigurationsFlags) +import Distribution.Types.BuildInfo.Lens (ccOptions, cppOptions, cxxOptions) +import Distribution.Types.Flag (flagName, mkFlagAssignment, mkFlagName, unFlagName) +import Distribution.Types.GenericPackageDescription.Lens + ( GenericPackageDescription, + condBenchmarks, + condExecutables, + condForeignLibs, + condLibrary, + condSubLibraries, + condTestSuites, + genPackageFlags, + ) +import System.IO (hPutStrLn, stderr) +import System.Process (readProcess) +import qualified Text.ParserCombinators.ReadP as P +import Prelude hiding (log) + +-- | Hook into Cabal to provide pkg-config metadata. Can be applied multiple +-- times to support multiple packages. +addHook :: Settings -> UserHooks -> UserHooks +addHook settings hooks = hooks {confHook = composeConfHook settings (confHook hooks)} + +-- | How the metadata for a pkg-config package should be made available to the +-- cabal file. +data Settings = Settings + { -- | Name of the package; used for querying pkg-config. + pkgConfigName :: String, + -- | Name to use in the Haskell CPP and C/C++ preprocessor macros. + -- + -- For example, `pkgConfigName = "FOO"` will set the macros + -- + -- * @FOO_MAJOR@ + -- + -- * @FOO_MINOR@ + -- + -- * @FOO_PATCH@ + -- + -- * @FOO_IS_AT_LEAST(major, minor, patch)@ + macroName :: String, + -- | Name to use when setting flag values in the cabal file. + -- + -- Flags named with this prefix, followed by a dash, followed by a major version number, an underscore and a minor version number will be set when the detected package is at least that version. + flagPrefixName :: String + } + +-- | Derive a default 'Settings' value from just a pkg-config package name. +mkSettings :: String -> Settings +mkSettings name = + Settings + { pkgConfigName = name, + macroName = map (\c -> case c of '-' -> '_'; x -> x) name, + flagPrefixName = name + } + +-- | Extend the value of 'confHook'. It's what powers 'addHook'. +composeConfHook :: + Settings -> + ((GenericPackageDescription, a) -> ConfigFlags -> IO b) -> + (GenericPackageDescription, a) -> + Distribution.Simple.Setup.ConfigFlags -> + IO b +composeConfHook settings origHook = \(genericPackageDescription, hookedBuildInfo) confFlags -> do + (actualMajor, actualMinor, actualPatch) <- getPkgConfigPackageVersion (pkgConfigName settings) + + let defines = + [ "-D" <> macroName settings <> "_MAJOR=" <> show actualMajor, + "-D" <> macroName settings <> "_MINOR=" <> show actualMinor, + "-D" <> macroName settings <> "_PATCH=" <> show actualPatch, + "-D" <> macroName settings <> "_IS_AT_LEAST(a,b,c)=(" <> show actualMajor <> ">a||(" <> show actualMajor <> "==a&&(" <> show actualMinor <> ">b||(" <> show actualMinor <> "==b&&" <> show actualPatch <> ">=c))))" + ] + extraFlags = + [ (mkFlagName (flagPrefixName settings ++ "-" ++ show major ++ "_" ++ show minor), (actualMajor, actualMinor) >= (major, minor)) + | declaredFlag <- genericPackageDescription ^. genPackageFlags, + let rawName = unFlagName $ flagName declaredFlag, + rawVersion <- L.stripPrefix (flagPrefixName settings ++ "-") rawName & toList, + [major, minor] <- unambiguously parseFlagVersion rawVersion & toList + ] + setDefines comp x = + x + & comp . cppOptions %~ (<> defines) + & comp . ccOptions %~ (<> defines) + & comp . cxxOptions %~ (<> defines) + genericPackageDescription' = + genericPackageDescription + & setDefines (condLibrary . traverse . traverse) + & setDefines (condSubLibraries . traverse . traverse . traverse) + & setDefines (condForeignLibs . traverse . traverse . traverse) + & setDefines (condExecutables . traverse . traverse . traverse) + & setDefines (condTestSuites . traverse . traverse . traverse) + & setDefines (condBenchmarks . traverse . traverse . traverse) + + configConfigurationsFlags' = configConfigurationsFlags confFlags `mappend` mkFlagAssignment extraFlags + confFlags' = + confFlags + { configConfigurationsFlags = configConfigurationsFlags' + } + origHook (genericPackageDescription', hookedBuildInfo) confFlags' + +parseVersion :: P.ReadP [Int] +parseVersion = do + map read <$> do + P.many1 (P.satisfy C.isDigit) `P.sepBy` P.char '.' + +parseFlagVersion :: P.ReadP [Int] +parseFlagVersion = + map read <$> do + P.many1 (P.satisfy C.isDigit) `P.sepBy` P.char '_' + +unambiguously :: P.ReadP a -> String -> Maybe a +unambiguously p s = + case filter (\(_a, x) -> x == "") $ P.readP_to_S p s of + [(v, _)] -> Just v + _ -> Nothing + +getPkgConfigPackageVersion :: String -> IO (Int, Int, Int) +getPkgConfigPackageVersion pkgName = do + s <- readProcess "pkg-config" ["--modversion", pkgName] "" + case L.sortOn (\(_, remainder) -> length remainder) $ P.readP_to_S parseVersion s of + [] -> error ("Could not parse version " ++ show s ++ " returned by pkg-config for package " ++ pkgName) + (v, r) : _ -> do + when (L.dropWhile C.isSpace r /= "") $ do + log ("ignoring trailing text " ++ show r ++ " in version " ++ show s ++ " of pkg-config package " ++ pkgName) + let v' = v ++ L.repeat 0 + pure (v' L.!! 0, v' L.!! 1, v' L.!! 2) + +-- Should probably use a Cabal function? +log :: String -> IO () +log = hPutStrLn stderr + +-- End of source copied from: https://hackage.haskell.org/package/cabal-pkg-config-version-hook + +hooks = + simpleUserHooks & + addHook + (mkSettings "opencv4") + { macroName = "SETUP_HS_OPENCV4_VERSION", + flagPrefixName = "setup-hs-opencv4-version" + } + + main = do args <- getArgs let args' | "configure" `elem` args = args ++ ["--with-gcc","c++"] | otherwise = args - defaultMainArgs args' + defaultMainWithHooksArgs hooks args' diff --git a/opencv-extra/include/tracking.hpp b/opencv-extra/include/tracking.hpp index ecfcbb20..92b29de5 100644 --- a/opencv-extra/include/tracking.hpp +++ b/opencv-extra/include/tracking.hpp @@ -1,9 +1,12 @@ #ifndef __HASKELL_OPENCV_TRACKING_H__ #define __HASKELL_OPENCV_TRACKING_H__ +#include +#include + typedef cv::Ptr Ptr_Tracker; -typedef cv::Ptr Ptr_TrackerFeature; -typedef cv::Ptr Ptr_MultiTracker; -typedef cv::Ptr Ptr_MultiTrackerAlt; +typedef cv::Ptr Ptr_TrackerFeature; +typedef cv::Ptr Ptr_MultiTracker; +typedef cv::Ptr Ptr_MultiTrackerAlt; #endif /* __HASKELL_OPENCV_TRACKING_H__ */ diff --git a/opencv-extra/include/xfeatures/sift.hpp b/opencv-extra/include/xfeatures/sift.hpp index c988f16f..97b560ce 100644 --- a/opencv-extra/include/xfeatures/sift.hpp +++ b/opencv-extra/include/xfeatures/sift.hpp @@ -1,18 +1,20 @@ #ifndef __OPENCV_XFEATURES_SIFT_H__ #define __OPENCV_XFEATURES_SIFT_H__ +// Note that `opencv2/xfeatures2d.hpp` does not exist in many OpenCV installations +// because it requires the `OPENCV_ENABLE_NONFREE` option (SIFT and SURF are patented). #include "opencv2/xfeatures2d.hpp" /* This file defines some SIFT related names that are used in - src/OpenCV/XFeatures2d.hsc. + src/OpenCV/XFeatures2d.hs. The reason we need these names is that we can't directly reference their definitions because that would result in invalid syntax in either hsc2hs and inline-c. */ -typedef cv::Ptr Ptr_SIFT; +typedef cv::Ptr Ptr_SIFT; #endif /* __OPENCV_XFEATURES_SIFT_H__ */ diff --git a/opencv-extra/include/xfeatures/surf.hpp b/opencv-extra/include/xfeatures/surf.hpp index dfc1cdf9..fd8ec8b2 100644 --- a/opencv-extra/include/xfeatures/surf.hpp +++ b/opencv-extra/include/xfeatures/surf.hpp @@ -1,12 +1,14 @@ #ifndef __OPENCV_XFEATURES_SURF_H__ #define __OPENCV_XFEATURES_SURF_H__ +// Note that `opencv2/xfeatures2d.hpp` does not exist in many OpenCV installations +// because it requires the `OPENCV_ENABLE_NONFREE` option (SIFT and SURF are patented). #include "opencv2/xfeatures2d.hpp" /* This file defines some SURF related names that are used in - src/OpenCV/XFeatures2d.hsc. + src/OpenCV/XFeatures2d.hs. The reason we need these names is that we can't directly reference their definitions because that would result in invalid syntax in either hsc2hs and diff --git a/opencv-extra/opencv-extra.cabal b/opencv-extra/opencv-extra.cabal index f27c4b49..185f9037 100644 --- a/opencv-extra/opencv-extra.cabal +++ b/opencv-extra/opencv-extra.cabal @@ -38,8 +38,8 @@ source-repository head location: git://github.com/LumiGuide/haskell-opencv.git subdir: opencv-extra -flag opencv4 - description: Use OpenCV >= 4.0.0 +flag enable-nonfree + description: Builds modules that only work if the system OpenCV was built with the OPENCV_ENABLE_NONFREE option (most OpenCV installations lack this by default). default: False manual: True @@ -49,7 +49,11 @@ flag internal-documentation manual: True custom-setup - setup-depends: base, Cabal >= 1.23 + setup-depends: + base, + Cabal >= 1.23, + lens, + process library hs-source-dirs: src @@ -75,10 +79,7 @@ library ghc-options: -Wall -fwarn-incomplete-patterns -funbox-strict-fields - if flag(opencv4) - pkgconfig-depends: opencv4 >= 4.0.0 - else - pkgconfig-depends: opencv >= 3.0.0 + pkgconfig-depends: opencv4 >= 4.0.0 if flag(internal-documentation) cpp-options: -DENABLE_INTERNAL_DOCUMENTATION @@ -102,7 +103,6 @@ library OpenCV.Extra OpenCV.Extra.ArUco OpenCV.Extra.Bgsegm - OpenCV.Extra.XFeatures2d OpenCV.Extra.Tracking OpenCV.Extra.XImgProc OpenCV.Extra.XPhoto @@ -112,6 +112,12 @@ library OpenCV.Extra.Internal.C.Types OpenCV.Extra.Internal.XImgProc.Constants + if flag(enable-nonfree) + exposed-modules: + OpenCV.Extra.XFeatures2d + ghc-options: + -DHASKELL_OPENCV_ENABLE_NONFREE + default-extensions: BangPatterns DataKinds @@ -134,7 +140,6 @@ test-suite doc-images-opencv-extra main-is: images.hs other-modules: ExampleExtractor - Language.Haskell.Meta.Syntax.Translate default-language: Haskell2010 ghc-options: -Wall -fwarn-incomplete-patterns -threaded -funbox-strict-fields -rtsopts cpp-options: -DHAVE_OPENCV_EXTRA @@ -146,6 +151,7 @@ test-suite doc-images-opencv-extra , directory >= 1.2.2 , Glob >= 0.7.5 , haskell-src-exts >= 1.18.2 + , haskell-src-meta >= 0.8.3 , JuicyPixels >= 3.2.8.1 , linear >= 1.20.4 , opencv diff --git a/opencv-extra/src/OpenCV/Extra.hs b/opencv-extra/src/OpenCV/Extra.hs index 7d22d873..5ff985bd 100644 --- a/opencv-extra/src/OpenCV/Extra.hs +++ b/opencv-extra/src/OpenCV/Extra.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE CPP #-} {-# OPTIONS_GHC -fno-warn-dodgy-exports #-} module OpenCV.Extra @@ -7,7 +8,10 @@ module OpenCV.Extra import OpenCV.Extra.ArUco as Extra import OpenCV.Extra.Bgsegm as Extra import OpenCV.Extra.Tracking as Extra -import OpenCV.Extra.XFeatures2d as Extra import OpenCV.Extra.XImgProc as Extra import OpenCV.Extra.XPhoto as Extra import OpenCV.Extra.XPhoto.WhiteBalancer as Extra + +#if HASKELL_OPENCV_ENABLE_NONFREE +import OpenCV.Extra.XFeatures2d as Extra +#endif diff --git a/opencv-extra/src/OpenCV/Extra/ArUco.hsc b/opencv-extra/src/OpenCV/Extra/ArUco.hsc index 4cdfd8e4..21d1c50f 100644 --- a/opencv-extra/src/OpenCV/Extra/ArUco.hsc +++ b/opencv-extra/src/OpenCV/Extra/ArUco.hsc @@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds, QuasiQuotes, RecordWildCards, TemplateHaskell #-} +{-# LANGUAGE CPP #-} module OpenCV.Extra.ArUco ( -- * ArUco markers @@ -63,10 +64,16 @@ C.context openCvExtraCtx C.include "opencv2/aruco.hpp" C.include "opencv2/aruco/charuco.hpp" +C.include "opencv2/calib3d.hpp" C.include "opencv2/core.hpp" C.include "iostream" C.include "aruco.hpp" +-- Note [opencv-4.7-aruco-api-change]: +-- OpenCV broke its Aruco API between 4.6 and 4.7. +-- We currently support both versions using CPP `#if`s because +-- both older and newer versions are still popuplar. + C.using "namespace cv" C.using "namespace cv::aruco" C.using "namespace std" @@ -254,7 +261,7 @@ drawEstimatedPose cameraMatrix distCoeffs (rvec, tvec) image = unsafePrimToPrim withPtr rvec $ \rvecPtr -> withPtr tvec $ \tvecPtr -> [C.block| void { - drawAxis + drawFrameAxes ( *$(Mat * imagePtr) , *$(Matx33d * c'cameraMatrix) , *$(Matx51d * c'distCoeffs) @@ -454,18 +461,42 @@ createCharucoBoard squaresX squaresY squareLength markerLength dictionary = unsafePerformIO $ withPtr dictionary $ \c'dictionary -> fromPtr $ +-- See note [opencv-4.7-aruco-api-change]. +-- +-- OpenCV < 4.7 uses `CharucoBoard::create()`, newer versions +-- use the `CharucoBoard()` constructor. +-- +-- Unfortunately `inline-c` does not support C++ `#if`s, otherwise +-- this could be done a bit simpler via e.g. +-- #if (CV_VERSION_MAJOR <= 4 && CV_VERSION_MINOR < 7) +-- instead of the logic that generates the below macro from +-- our `Setup.hs` hook. +#if SETUP_HS_OPENCV4_VERSION_IS_AT_LEAST(4,7,0) [C.block| Ptr_CharucoBoard * { return - new Ptr - ( CharucoBoard::create - ( $(int c'squaresX) - , $(int c'squaresY) - , $(double c'squareLength) - , $(double c'markerLength) - , *$(Ptr_Dictionary * c'dictionary) - ) - ); + new Ptr( + new CharucoBoard + ( Size( $(int c'squaresX) , $(int c'squaresY) ) + , $(float c'squareLength) + , $(float c'markerLength) + , **$(Ptr_Dictionary * c'dictionary) + ) + ); + }|] +#else + [C.block| Ptr_CharucoBoard * { + return + new Ptr( + CharucoBoard::create + ( $(int c'squaresX) + , $(int c'squaresY) + , $(float c'squareLength) + , $(float c'markerLength) + , *$(Ptr_Dictionary * c'dictionary) + ) + ); }|] +#endif where c'squaresX = fromIntegral squaresX c'squaresY = fromIntegral squaresY @@ -538,9 +569,20 @@ getPredefinedDictionary :: PredefinedDictionaryName -> Dictionary getPredefinedDictionary name = unsafePerformIO $ fromPtr $ +-- See note [opencv-4.7-aruco-api-change]. +-- +-- In OpenCV < 4.7, `getPredefinedDictionary()` returns a `Ptr`, +-- in newer versions it returns a `Dictionary`. +#if SETUP_HS_OPENCV4_VERSION_IS_AT_LEAST(4,7,0) + [C.block| Ptr_Dictionary * { + const Dictionary dict = getPredefinedDictionary($(int32_t c'name)); + return new Ptr(makePtr(dict)); + }|] +#else [C.block| Ptr_Dictionary * { return new Ptr(getPredefinedDictionary($(int32_t c'name))); }|] +#endif where c'name :: Int32 c'name = marshalPredefinedDictionaryName name @@ -577,11 +619,23 @@ drawCharucoBoard charucoBoard width height = unsafePerformIO $ do dst <- newEmptyMat withPtr charucoBoard $ \c'board -> withPtr dst $ \dstPtr -> +-- See note [opencv-4.7-aruco-api-change]. +-- +-- In OpenCV < 4.7, `draw()` draws the board, +-- in newer versions it's `generateImage()`. +#if SETUP_HS_OPENCV4_VERSION_IS_AT_LEAST(4,7,0) + [C.block| void { + Mat & board = * $(Mat * dstPtr); + Ptr & charucoBoard = *$(Ptr_CharucoBoard * c'board); + charucoBoard->generateImage(cv::Size($(int32_t w), $(int32_t h)), board); + }|] +#else [C.block| void { Mat & board = * $(Mat * dstPtr); Ptr & charucoBoard = *$(Ptr_CharucoBoard * c'board); charucoBoard->draw(cv::Size($(int32_t w), $(int32_t h)), board); }|] +#endif pure (unsafeCoerceMat dst) where w = toInt32 width diff --git a/opencv-extra/src/OpenCV/Extra/Tracking.hs b/opencv-extra/src/OpenCV/Extra/Tracking.hs index b76f8c4f..96fce751 100644 --- a/opencv-extra/src/OpenCV/Extra/Tracking.hs +++ b/opencv-extra/src/OpenCV/Extra/Tracking.hs @@ -24,6 +24,7 @@ module OpenCV.Extra.Tracking ) where import "base" Data.Word +import "base" Data.Int (Int32) import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "base" Foreign.C.String ( withCString ) import "base" Foreign.Marshal.Utils ( toBool ) @@ -45,6 +46,7 @@ C.context openCvExtraCtx C.include "opencv2/core.hpp" C.include "opencv2/tracking.hpp" +C.include "opencv2/tracking/tracking_legacy.hpp" C.include "tracking.hpp" @@ -53,20 +55,22 @@ C.using "namespace cv" -------------------------------------------------------------------------------- data TrackerType - = BOOSTING -- ^ - | MIL -- ^ + = MIL -- ^ | KCF -- ^ - | MEDIANFLOW -- ^ - | TLD -- ^ | GOTURN -- ^ deriving (Eq, Show, Enum, Bounded) +type FEATURE2D_DetectorType = String +type FEATURE2D_DescriptorType = String + data TrackerFeatureType = HAAR -- ^ Haar Feature-based - | HOG -- ^ soon Histogram of Oriented Gradients features - | LBP -- ^ soon Local Binary Pattern features - | FEATURE2D -- ^ soon All types of Feature2D - deriving (Eq, Show, Enum, Bounded) + | HOG -- ^ Histogram of Oriented Gradients features + | LBP -- ^ Local Binary Pattern features + | FEATURE2D -- ^ All types of Feature2D + FEATURE2D_DetectorType + FEATURE2D_DescriptorType + deriving (Eq, Show) -------------------------------------------------------------------------------- @@ -87,27 +91,24 @@ newTracker -- ^ Name -> m (Tracker (PrimState m)) newTracker tType = unsafePrimToPrim $ fromPtr $ case tType of - BOOSTING -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerBoosting::create());}|] MIL -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerMIL::create());}|] KCF -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerKCF::create());}|] - MEDIANFLOW -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerMedianFlow::create());}|] - TLD -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerTLD::create());}|] GOTURN -> [CU.block|Ptr_Tracker * {return new cv::Ptr(cv::TrackerGOTURN::create());}|] initTracker - :: (PrimMonad m, IsRect rect C.CDouble) + :: (PrimMonad m, IsRect rect Int32) => Tracker (PrimState m) -> Mat ('S '[ 'D, 'D]) ('D) ('D) - -> rect C.CDouble - -> m Bool + -> rect Int32 + -> m () initTracker trk srcImg boundingBox = unsafePrimToPrim $ withPtr trk $ \trkPtr -> withPtr srcImg $ \srcPtr -> - withPtr (toRect boundingBox) $ \rectPtr -> toBool <$> - [C.block| bool { - return (*$(Ptr_Tracker * trkPtr))->init + withPtr (toRect boundingBox) $ \rectPtr -> + [C.block| void { + (*$(Ptr_Tracker * trkPtr))->init ( *$(Mat * srcPtr) - , *$(Rect2d * rectPtr) + , *$(const Rect2i * rectPtr) ); } |] @@ -116,22 +117,23 @@ updateTracker :: (PrimMonad m) => Tracker (PrimState m) -> Mat ('D) ('D) ('S Word8) - -> m (Maybe (Rect C.CDouble)) --- -> m (Maybe (Rect Int32)) + -> m (Maybe (Rect Int32)) updateTracker trk srcImg = unsafePrimToPrim $ withPtr trk $ \trkPtr -> withPtr srcImg $ \srcPtr -> withPtr rect $ \rectPtr -> do ok <- toBool <$> [C.block| bool { - return (*$(Ptr_Tracker * trkPtr))->update + Rect2i boundingBox = *$(Rect2i * rectPtr); + return (*$(Ptr_Tracker * trkPtr))->update ( *$(Mat * srcPtr) - , *$(Rect2d * rectPtr) + // , *$(Rect2i * rectPtr) + , boundingBox ); } |] pure $ if ok then Just rect else Nothing where - rect :: Rect2d + rect :: Rect2i rect = toRect HRect{hRectTopLeft = 0, hRectSize = 0} -------------------------------------------------------------------------------- @@ -144,9 +146,9 @@ type instance C (TrackerFeature s) = C'Ptr_TrackerFeature type instance C (MultiTracker s) = C'Ptr_MultiTracker type instance C (MultiTrackerAlt s) = C'Ptr_MultiTrackerAlt -mkFinalizer ReleaseDeletePtr "deleteTrackerFeature" "cv::Ptr" ''C'Ptr_TrackerFeature -mkFinalizer ReleaseDeletePtr "deleteMultiTracker" "cv::Ptr" ''C'Ptr_MultiTracker -mkFinalizer ReleaseDeletePtr "deleteMultiTrackerAlt" "cv::Ptr" ''C'Ptr_MultiTrackerAlt +mkFinalizer ReleaseDeletePtr "deleteTrackerFeature" "cv::Ptr" ''C'Ptr_TrackerFeature +mkFinalizer ReleaseDeletePtr "deleteMultiTracker" "cv::Ptr" ''C'Ptr_MultiTracker +mkFinalizer ReleaseDeletePtr "deleteMultiTrackerAlt" "cv::Ptr" ''C'Ptr_MultiTrackerAlt instance WithPtr (TrackerFeature s) where withPtr = withForeignPtr . unTrackerFeature @@ -174,7 +176,7 @@ newMultiTracker newMultiTracker = unsafePrimToPrim $ fromPtr $ [CU.block|Ptr_MultiTracker * { - return new cv::Ptr(new cv::MultiTracker()); + return new cv::Ptr(new cv::legacy::tracking::MultiTracker()); }|] -------------------------------------------------------------------------------- @@ -184,10 +186,28 @@ newTrackerFeature => TrackerFeatureType -- ^ Name -> m (TrackerFeature (PrimState m)) newTrackerFeature trackerFeatureType = - unsafePrimToPrim $ fromPtr $ - withCString (show trackerFeatureType) $ \c'trackerFeatureType -> - [CU.block|Ptr_TrackerFeature * { - cv::Ptr ftracker = - cv::TrackerFeature::create(cv::String($(const char * c'trackerFeatureType))); - return new cv::Ptr(ftracker); - }|] + unsafePrimToPrim $ fromPtr $ case trackerFeatureType of + HAAR -> + [CU.block|Ptr_TrackerFeature * { + return new cv::Ptr(new cv::detail::tracking::TrackerContribFeatureHAAR()); + }|] + HOG -> + [CU.block|Ptr_TrackerFeature * { + return new cv::Ptr(new cv::detail::tracking::TrackerFeatureHOG()); + }|] + LBP -> + [CU.block|Ptr_TrackerFeature * { + return new cv::Ptr(new cv::detail::tracking::TrackerFeatureLBP()); + }|] + FEATURE2D detectorType descriptorType -> + withCString (show detectorType) $ \c'detectorType -> + withCString (show descriptorType) $ \c'descriptorType -> + + [CU.block|Ptr_TrackerFeature * { + return new cv::Ptr( + new cv::detail::tracking::TrackerFeatureFeature2d( + cv::String($(const char * c'detectorType)), + cv::String($(const char * c'descriptorType)) + ) + ); + }|] diff --git a/opencv-extra/src/OpenCV/Extra/XFeatures2d.hs b/opencv-extra/src/OpenCV/Extra/XFeatures2d.hs index f9c9560f..379c43c7 100644 --- a/opencv-extra/src/OpenCV/Extra/XFeatures2d.hs +++ b/opencv-extra/src/OpenCV/Extra/XFeatures2d.hs @@ -47,6 +47,8 @@ import qualified "vector" Data.Vector as V C.context openCvExtraCtx C.include "opencv2/core.hpp" +-- Note that `opencv2/xfeatures2d.hpp` does not exist in many OpenCV installations +-- because it requires the `OPENCV_ENABLE_NONFREE` option (SIFT and SURF are patented). C.include "opencv2/xfeatures2d.hpp" C.include "xfeatures/surf.hpp" C.include "xfeatures/sift.hpp" @@ -216,8 +218,8 @@ surfDetectAndCompute surf img mbMask = unsafeWrapException $ do -- SIFT - Scale-Invariant Feature Transform -------------------------------------------------------------------------------- --- Internally, an Sift is a pointer to a @cv::Ptr@, which in turn points --- to an actual @cv::xfeatures2d::SIFT@ object. +-- Internally, an Sift is a pointer to a @cv::Ptr@, which in turn points +-- to an actual @cv::SIFT@ object. newtype Sift = Sift {unSift :: ForeignPtr C'Ptr_SIFT} type instance C Sift = C'Ptr_SIFT @@ -227,7 +229,7 @@ instance WithPtr Sift where mkFinalizer ReleaseDeletePtr "deleteSift" - "cv::Ptr" + "cv::Ptr" ''C'Ptr_SIFT instance FromPtr Sift where fromPtr = objFromPtr Sift deleteSift @@ -264,15 +266,15 @@ defaultSiftParams = newSift :: SiftParams -> IO Sift newSift SiftParams{..} = fromPtr [CU.block|Ptr_SIFT * { - cv::Ptr siftPtr = - cv::xfeatures2d::SIFT::create + cv::Ptr siftPtr = + cv::SIFT::create ( $(int32_t sift_nFeatures) , $(int32_t sift_nOctaveLayers) , $(double c'contrastThreshold) , $(double c'edgeThreshold) , $(double c'sigma) ); - return new cv::Ptr(siftPtr); + return new cv::Ptr(siftPtr); }|] where c'contrastThreshold = realToFrac sift_contrastThreshold @@ -326,7 +328,7 @@ siftDetectAndCompute sift img mbMask = unsafeWrapException $ do alloca $ \(numPtsPtr :: Ptr C.CSize) -> alloca $ \(arrayPtrPtr :: Ptr (Ptr (Ptr C'KeyPoint))) -> mask_ $ do ptrException <- [cvExcept| - cv::xfeatures2d::SIFT * sift = *$(Ptr_SIFT * siftPtr); + cv::SIFT * sift = *$(Ptr_SIFT * siftPtr); cv::Mat * maskPtr = $(Mat * maskPtr); std::vector keypoints = std::vector(); diff --git a/opencv/opencv.cabal b/opencv/opencv.cabal index 57bceae9..59c4e6df 100644 --- a/opencv/opencv.cabal +++ b/opencv/opencv.cabal @@ -43,11 +43,6 @@ source-repository head location: git://github.com/LumiGuide/haskell-opencv.git subdir: opencv -flag opencv4 - description: Use OpenCV >= 4.0.0 - default: False - manual: True - flag internal-documentation description: Enables documentation generation for internal modules. default: False @@ -80,13 +75,7 @@ library ghc-options: -Wall -fwarn-incomplete-patterns -funbox-strict-fields - if flag(opencv4) - cpp-options: -DOPENCV4 - ghc-options: -optc-DOPENCV4 - pkgconfig-depends: opencv4 >= 4.0.0 - else - pkgconfig-depends: opencv >= 3.0.0 - build-depends: base64-bytestring >= 1.0.0.1 + pkgconfig-depends: opencv4 >= 4.0.0 if flag(internal-documentation) cpp-options: -DENABLE_INTERNAL_DOCUMENTATION @@ -213,7 +202,6 @@ test-suite doc-images-opencv main-is: images.hs other-modules: ExampleExtractor - Language.Haskell.Meta.Syntax.Translate default-language: Haskell2010 ghc-options: -Wall -fwarn-incomplete-patterns -threaded -funbox-strict-fields -rtsopts build-depends: @@ -224,6 +212,7 @@ test-suite doc-images-opencv , directory >= 1.2.2 , Glob >= 0.7.5 , haskell-src-exts >= 1.21.0 + , haskell-src-meta >= 0.8.3 , JuicyPixels >= 3.2.8.1 , linear >= 1.20.4 , opencv diff --git a/opencv/src/OpenCV/Calib3d.hs b/opencv/src/OpenCV/Calib3d.hs index 05aabeff..02364f52 100644 --- a/opencv/src/OpenCV/Calib3d.hs +++ b/opencv/src/OpenCV/Calib3d.hs @@ -556,7 +556,7 @@ findHomographyImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 ) => Mat (ShapeT ['S height, 'D]) ('S channels) ('S depth) diff --git a/opencv/src/OpenCV/Core/ArrayOps.hs b/opencv/src/OpenCV/Core/ArrayOps.hs index 5c2de1f7..ba11b960 100644 --- a/opencv/src/OpenCV/Core/ArrayOps.hs +++ b/opencv/src/OpenCV/Core/ArrayOps.hs @@ -647,7 +647,7 @@ matSplitImg (width3 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width3 ~ ((*) width 3) ) diff --git a/opencv/src/OpenCV/Core/Types/Mat.hs b/opencv/src/OpenCV/Core/Types/Mat.hs index cff0ba94..575beb87 100644 --- a/opencv/src/OpenCV/Core/Types/Mat.hs +++ b/opencv/src/OpenCV/Core/Types/Mat.hs @@ -72,6 +72,7 @@ module OpenCV.Core.Types.Mat , ValidChannels' ) where +import "base" Data.Kind ( Type ) import "base" Control.Monad.ST ( runST ) import "base" Data.Int ( Int32 ) import "base" Data.Foldable ( for_ ) @@ -347,7 +348,7 @@ matCopyToM dstM (V2 x y) src mbSrcMask = -- |Transforms a given list of matrices of equal shape, channels, and depth, -- by folding the given function over all matrix elements at each position. -foldMat :: forall (shape :: [DS Nat]) (channels :: Nat) (depth :: *) a +foldMat :: forall (shape :: [DS Nat]) (channels :: Nat) (depth :: Type) a . ( Storable depth , Storable a , All IsStatic shape diff --git a/opencv/src/OpenCV/Core/Types/Mat/Repa.hs b/opencv/src/OpenCV/Core/Types/Mat/Repa.hs index dce1ab58..73a91674 100644 --- a/opencv/src/OpenCV/Core/Types/Mat/Repa.hs +++ b/opencv/src/OpenCV/Core/Types/Mat/Repa.hs @@ -17,6 +17,7 @@ module OpenCV.Core.Types.Mat.Repa , toRepa ) where +import "base" Data.Kind ( Type ) import "base" Data.Int import "base" Data.Proxy import "base" Data.Word @@ -57,7 +58,7 @@ C.using "namespace cv" -- | Representation tag for Repa @'Repa.Array's@ for OpenCV @'Mat's@. data M (shape :: [DS Nat]) (channels :: Nat) -type family DIM (n :: Nat) :: * where +type family DIM (n :: Nat) :: Type where DIM 0 = Repa.Z DIM n = DIM (n-1) :. Int @@ -67,9 +68,9 @@ type family DIM (n :: Nat) :: * where toRepa :: forall (shape :: [DS Nat]) (channels :: Nat) - (depth :: *) + (depth :: Type) (dims :: Nat) - (sh :: *) + (sh :: Type) . ( Storable depth , KnownNat channels , KnownNat dims diff --git a/opencv/src/OpenCV/Features2d.hs b/opencv/src/OpenCV/Features2d.hs index beb2fd0c..60df40fb 100644 --- a/opencv/src/OpenCV/Features2d.hs +++ b/opencv/src/OpenCV/Features2d.hs @@ -197,11 +197,7 @@ newOrb OrbParams{..} = fromPtr , $(int32_t orb_edgeThreshold) , $(int32_t orb_firstLevel) , $(int32_t c'WTA_K) -#ifdef OPENCV4 , cv::ORB::ScoreType($(int32_t c'scoreType)) -#else - , $(int32_t c'scoreType) -#endif , $(int32_t orb_patchSize) , $(int32_t orb_fastThreshold) ); @@ -226,7 +222,7 @@ orbDetectAndComputeImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog) => Mat (ShapeT [height, width]) ('S channels) ('S depth) orbDetectAndComputeImg = exceptError $ do @@ -654,7 +650,7 @@ bfMatcherImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog , width2 ~ (*) width 2 ) @@ -774,7 +770,7 @@ fbMatcherImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog , width2 ~ (*) width 2 ) diff --git a/opencv/src/OpenCV/ImgProc/CascadeClassifier.hs b/opencv/src/OpenCV/ImgProc/CascadeClassifier.hs index e2517be9..d107e175 100644 --- a/opencv/src/OpenCV/ImgProc/CascadeClassifier.hs +++ b/opencv/src/OpenCV/ImgProc/CascadeClassifier.hs @@ -75,7 +75,7 @@ cascadeClassifierArnold :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Arnold_small) => IO (Mat (ShapeT [height, width]) ('S channels) ('S depth)) cascadeClassifierArnold = do diff --git a/opencv/src/OpenCV/ImgProc/FeatureDetection.hs b/opencv/src/OpenCV/ImgProc/FeatureDetection.hs index 01bb34a8..eea8724f 100644 --- a/opencv/src/OpenCV/ImgProc/FeatureDetection.hs +++ b/opencv/src/OpenCV/ImgProc/FeatureDetection.hs @@ -151,7 +151,7 @@ goodFeaturesToTrackTraces :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Frog) => Mat (ShapeT [height, width]) ('S channels) ('S depth) goodFeaturesToTrackTraces = exceptError $ do @@ -272,7 +272,7 @@ houghCircleTraces :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Circles_1000x625) => Mat (ShapeT [height, width]) ('S channels) ('S depth) houghCircleTraces = exceptError $ do @@ -335,11 +335,7 @@ houghCircles dp minDist param1 param2 minRadius maxRadius src = unsafeWrapExcept cv::HoughCircles( *$(Mat * srcPtr), circles, -#ifdef OPENCV4 HOUGH_GRADIENT, -#else - CV_HOUGH_GRADIENT, -#endif $(double c'dp), $(double c'minDist), $(double c'param1), @@ -394,7 +390,7 @@ houghLinesPTraces :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Building_868x600) => Mat (ShapeT [height, width]) ('S channels) ('S depth) houghLinesPTraces = exceptError $ do diff --git a/opencv/src/OpenCV/ImgProc/GeometricImgTransform.hsc b/opencv/src/OpenCV/ImgProc/GeometricImgTransform.hsc index fd7dfa9f..49238bf6 100644 --- a/opencv/src/OpenCV/ImgProc/GeometricImgTransform.hsc +++ b/opencv/src/OpenCV/ImgProc/GeometricImgTransform.hsc @@ -91,9 +91,7 @@ C.context openCvCtx C.include "opencv2/core.hpp" C.include "opencv2/imgproc.hpp" -#ifdef OPENCV4 C.include "opencv2/calib3d.hpp" -#endif C.using "namespace cv" #include @@ -376,7 +374,7 @@ linearPolarImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Compass) => Mat ('S ['S height, 'S width]) ('S channels) ('S depth) linearPolarImg = exceptError $ @@ -454,7 +452,7 @@ logPolarImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Compass) => Mat ('S ['S height, 'S width]) ('S channels) ('S depth) logPolarImg = exceptError $ @@ -589,7 +587,7 @@ remapImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Kodak_512x341) => Mat ('S ['S height, 'S width]) ('S channels) ('S depth) remapImg = exceptError $ remap birds_512x341 transform InterLinear (BorderConstant black) @@ -673,7 +671,7 @@ undistortImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Kodak_512x341) => Mat ('S ['S height, 'S width]) ('S channels) ('S depth) undistortImg = undistort birds_512x341 intrinsics coefficients diff --git a/opencv/src/OpenCV/ImgProc/ImgFiltering.hsc b/opencv/src/OpenCV/ImgProc/ImgFiltering.hsc index ed676f60..8eeba5c4 100644 --- a/opencv/src/OpenCV/ImgProc/ImgFiltering.hsc +++ b/opencv/src/OpenCV/ImgProc/ImgFiltering.hsc @@ -149,7 +149,7 @@ bilateralFilterImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -285,7 +285,7 @@ medianBlurImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -339,7 +339,7 @@ boxBlurImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -395,7 +395,7 @@ gaussianBlurImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 ) => Mat (ShapeT ['S height, 'D]) ('S channels) ('S depth) gaussianBlurImg = exceptError $ @@ -470,7 +470,7 @@ erodeImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Lambda , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -545,7 +545,7 @@ filter2DImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -635,7 +635,7 @@ dilateImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Lambda , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) @@ -720,7 +720,7 @@ morphologyExImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ DamageMask , width2 ~ ((*) width 2) -- TODO (RvD): HSE parse error with infix type operator ) diff --git a/opencv/src/OpenCV/ImgProc/MiscImgTransform.hs b/opencv/src/OpenCV/ImgProc/MiscImgTransform.hs index 393e953d..854aa06a 100644 --- a/opencv/src/OpenCV/ImgProc/MiscImgTransform.hs +++ b/opencv/src/OpenCV/ImgProc/MiscImgTransform.hs @@ -34,6 +34,7 @@ module OpenCV.ImgProc.MiscImgTransform import "base" Data.Bits import "base" Data.Int +import "base" Data.Kind ( Type ) import "base" Data.Proxy ( Proxy(..) ) import "base" Data.Word import "base" Foreign.Marshal.Alloc ( alloca ) @@ -116,7 +117,7 @@ cvtColorImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_512x341 , width2 ~ (width + width) ) @@ -156,8 +157,8 @@ cvtColor :: forall (fromColor :: ColorCode) (shape :: DS [DS Nat]) (srcChannels :: DS Nat) (dstChannels :: DS Nat) - (srcDepth :: DS *) - (dstDepth :: DS *) + (srcDepth :: DS Type) + (dstDepth :: DS Type) m . ( ColorConversion fromColor toColor , ColorCodeMatchesChannels fromColor srcChannels @@ -198,7 +199,7 @@ floodFillImg (width2 :: Nat) (height :: Nat) (channels :: Nat) - (depth :: *) + (depth :: Type) . ( Mat (ShapeT [height, width]) ('S channels) ('S depth) ~ Kodak_768x512 , width2 ~ (width + width) ) diff --git a/opencv/src/OpenCV/ImgProc/ObjectDetection.hsc b/opencv/src/OpenCV/ImgProc/ObjectDetection.hsc index 9578a9c2..a88cd839 100644 --- a/opencv/src/OpenCV/ImgProc/ObjectDetection.hsc +++ b/opencv/src/OpenCV/ImgProc/ObjectDetection.hsc @@ -101,33 +101,12 @@ data MatchTemplateNormalisation | MatchTemplateNormed -- ^ Use normalization. deriving (Show, Eq) -#ifdef OPENCV4 #num TM_SQDIFF #num TM_SQDIFF_NORMED #num TM_CCORR #num TM_CCORR_NORMED #num TM_CCOEFF #num TM_CCOEFF_NORMED -#else -#num CV_TM_SQDIFF -#num CV_TM_SQDIFF_NORMED -#num CV_TM_CCORR -#num CV_TM_CCORR_NORMED -#num CV_TM_CCOEFF -#num CV_TM_CCOEFF_NORMED -c'TM_SQDIFF :: Num a => a -c'TM_SQDIFF_NORMED :: Num a => a -c'TM_CCORR :: Num a => a -c'TM_CCORR_NORMED :: Num a => a -c'TM_CCOEFF :: Num a => a -c'TM_CCOEFF_NORMED :: Num a => a -c'TM_SQDIFF = c'CV_TM_SQDIFF -c'TM_SQDIFF_NORMED = c'CV_TM_SQDIFF_NORMED -c'TM_CCORR = c'CV_TM_CCORR -c'TM_CCORR_NORMED = c'CV_TM_CCORR_NORMED -c'TM_CCOEFF = c'CV_TM_CCOEFF -c'TM_CCOEFF_NORMED = c'CV_TM_CCOEFF_NORMED -#endif marshalMatchTemplateMethod :: MatchTemplateMethod -> Bool -> Int32 marshalMatchTemplateMethod m n = diff --git a/opencv/src/OpenCV/ImgProc/StructuralAnalysis.hsc b/opencv/src/OpenCV/ImgProc/StructuralAnalysis.hsc index 3da5c000..a347e844 100644 --- a/opencv/src/OpenCV/ImgProc/StructuralAnalysis.hsc +++ b/opencv/src/OpenCV/ImgProc/StructuralAnalysis.hsc @@ -57,9 +57,7 @@ import qualified "vector" Data.Vector.Storable as VS #include #include "opencv2/imgproc.hpp" -#ifdef OPENCV4 #include "namespace.hpp" -#endif C.context openCvCtx @@ -109,7 +107,6 @@ data ContourApproximationMethod | ContourApproximationTC89L1 | ContourApproximationTC89KCOS -#ifdef OPENCV4 #num RETR_EXTERNAL #num RETR_LIST #num RETR_CCOMP @@ -118,32 +115,6 @@ data ContourApproximationMethod #num CHAIN_APPROX_SIMPLE #num CHAIN_APPROX_TC89_L1 #num CHAIN_APPROX_TC89_KCOS -#else -#num CV_RETR_EXTERNAL -#num CV_RETR_LIST -#num CV_RETR_CCOMP -#num CV_RETR_TREE -#num CV_CHAIN_APPROX_NONE -#num CV_CHAIN_APPROX_SIMPLE -#num CV_CHAIN_APPROX_TC89_L1 -#num CV_CHAIN_APPROX_TC89_KCOS -c'RETR_EXTERNAL :: Num a => a -c'RETR_LIST :: Num a => a -c'RETR_CCOMP :: Num a => a -c'RETR_TREE :: Num a => a -c'CHAIN_APPROX_NONE :: Num a => a -c'CHAIN_APPROX_SIMPLE :: Num a => a -c'CHAIN_APPROX_TC89_L1 :: Num a => a -c'CHAIN_APPROX_TC89_KCOS :: Num a => a -c'RETR_EXTERNAL = c'CV_RETR_EXTERNAL -c'RETR_LIST = c'CV_RETR_LIST -c'RETR_CCOMP = c'CV_RETR_CCOMP -c'RETR_TREE = c'CV_RETR_TREE -c'CHAIN_APPROX_NONE = c'CV_CHAIN_APPROX_NONE -c'CHAIN_APPROX_SIMPLE = c'CV_CHAIN_APPROX_SIMPLE -c'CHAIN_APPROX_TC89_L1 = c'CV_CHAIN_APPROX_TC89_L1 -c'CHAIN_APPROX_TC89_KCOS = c'CV_CHAIN_APPROX_TC89_KCOS -#endif marshalContourRetrievalMode :: ContourRetrievalMode -> Int32 marshalContourRetrievalMode = \case @@ -187,7 +158,7 @@ arcLength curve isClosed ); |] where - c'isClosed = fromBool isClosed + c'isClosed = fromBool isClosed :: CBool c'numCurvePoints = fromIntegral $ V.length curve {- | Calculates a contour area. @@ -226,7 +197,7 @@ contourArea contour areaOriented ContourAreaOriented -> True ContourAreaAbsoluteValue -> False c'numPoints = fromIntegral $ V.length contour - c'oriented = fromBool oriented + c'oriented = fromBool oriented :: CBool {- | Finds the convexity defects of a contour. @@ -237,7 +208,7 @@ handDefectsImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Hand) => IO (Mat ('S ['S height, 'S width]) ('S channels) ('S depth)) handDefectsImg = do @@ -341,7 +312,7 @@ handContourImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Hand) => IO (Mat ('S ['S height, 'S width]) ('S channels) ('S depth)) handContourImg = do @@ -578,4 +549,4 @@ pointPolygonTest contour pt measureDist |] where c'numPoints = fromIntegral $ V.length contour - c'measureDist = fromBool measureDist + c'measureDist = fromBool measureDist :: CBool diff --git a/opencv/src/OpenCV/Internal/C/Inline.hs b/opencv/src/OpenCV/Internal/C/Inline.hs index 4a1046e7..162d5f09 100644 --- a/opencv/src/OpenCV/Internal/C/Inline.hs +++ b/opencv/src/OpenCV/Internal/C/Inline.hs @@ -33,7 +33,7 @@ openCvCtx = C.cppCtx <> C.bsCtx <> C.vecCtx <> ctx openCvTypesTable :: C.TypesTable openCvTypesTable = M.fromList - [ ( C.TypeName "bool" , [t| C.CInt |] ) + [ ( C.TypeName "bool" , [t| C.CBool |] ) , ( C.TypeName "Exception" , [t| C'CvCppException |] ) diff --git a/opencv/src/OpenCV/Internal/C/Types.hs b/opencv/src/OpenCV/Internal/C/Types.hs index 9bf37120..fc61d022 100644 --- a/opencv/src/OpenCV/Internal/C/Types.hs +++ b/opencv/src/OpenCV/Internal/C/Types.hs @@ -6,6 +6,7 @@ module OpenCV.Internal.C.Types where +import "base" Data.Kind ( Type ) import "base" Foreign.C.Types import "base" Foreign.Ptr ( Ptr, nullPtr ) import "base" Data.Int ( Int32 ) @@ -15,11 +16,11 @@ import "this" OpenCV.Internal.Mutable -------------------------------------------------------------------------------- -data C'Matx (dimR :: Nat) (dimC :: Nat) (depth :: *) -data C'Vec (dim :: Nat) (depth :: *) -data C'Point (dim :: Nat) (depth :: *) -data C'Size (depth :: *) -data C'Rect (depth :: *) +data C'Matx (dimR :: Nat) (dimC :: Nat) (depth :: Type) +data C'Vec (dim :: Nat) (depth :: Type) +data C'Point (dim :: Nat) (depth :: Type) +data C'Size (depth :: Type) +data C'Rect (depth :: Type) type C'Matx12f = C'Matx 1 2 CFloat type C'Matx12d = C'Matx 1 2 CDouble @@ -179,7 +180,7 @@ instance CSizeOf C'Mat where cSizeOf _proxy = c'sizeof_Mat -- | Equivalent type in C -- -- Actually a proxy type in Haskell that stands for the equivalent type in C. -type family C (a :: *) :: * +type family C (a :: Type) :: Type type instance C (Maybe a) = C a diff --git a/opencv/src/OpenCV/Internal/Calib3d/Constants.hsc b/opencv/src/OpenCV/Internal/Calib3d/Constants.hsc index e319c78f..423bce6c 100644 --- a/opencv/src/OpenCV/Internal/Calib3d/Constants.hsc +++ b/opencv/src/OpenCV/Internal/Calib3d/Constants.hsc @@ -12,25 +12,10 @@ module OpenCV.Internal.Calib3d.Constants where #include "namespace.hpp" -#ifdef OPENCV4 #num FM_7POINT #num FM_8POINT #num FM_RANSAC #num FM_LMEDS -#else -#num CV_FM_7POINT -#num CV_FM_8POINT -#num CV_FM_RANSAC -#num CV_FM_LMEDS -c'FM_7POINT :: Num a => a -c'FM_8POINT :: Num a => a -c'FM_RANSAC :: Num a => a -c'FM_LMEDS :: Num a => a -c'FM_7POINT = c'CV_FM_7POINT -c'FM_8POINT = c'CV_FM_8POINT -c'FM_RANSAC = c'CV_FM_RANSAC -c'FM_LMEDS = c'CV_FM_LMEDS -#endif #num LMEDS #num RANSAC diff --git a/opencv/src/OpenCV/Internal/Core/Types/Mat.hs b/opencv/src/OpenCV/Internal/Core/Types/Mat.hs index 97919efb..7635596e 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Mat.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Mat.hs @@ -85,6 +85,7 @@ module OpenCV.Internal.Core.Types.Mat , ValidChannels' ) where +import "base" Data.Kind ( Type ) import "base" Control.Exception ( throwIO, mask_, bracket ) import "base" Control.Monad ( when ) import "base" Control.Monad.IO.Class @@ -181,7 +182,7 @@ A 1920x1080 3 channel image where each element is a single byte. -} newtype Mat (shape :: DS [DS Nat]) (channels :: DS Nat) - (depth :: DS *) + (depth :: DS Type) = Mat {unMat :: ForeignPtr (C (Mat shape channels depth))} type instance C (Mat shape channels depth) = C'Mat diff --git a/opencv/src/OpenCV/Internal/Core/Types/Mat/Depth.hs b/opencv/src/OpenCV/Internal/Core/Types/Mat/Depth.hs index 435dd761..9f717d47 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Mat/Depth.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Mat/Depth.hs @@ -13,6 +13,7 @@ module OpenCV.Internal.Core.Types.Mat.Depth , StaticDepthT ) where +import "base" Data.Kind ( Type ) import "base" Data.Int import "base" Data.Proxy import "base" Data.Word @@ -28,9 +29,6 @@ data Depth = | Depth_32S | Depth_32F | Depth_64F -#ifndef OPENCV4 - | Depth_USRTYPE1 -#endif deriving (Bounded, Enum, Eq, Show) -------------------------------------------------------------------------------- @@ -69,12 +67,12 @@ instance ToDepthDS (proxy ('S Double)) where toDepthDS _proxy = S $ toDepth (Pro -------------------------------------------------------------------------------- -type family DepthT a :: DS * where +type family DepthT a :: DS Type where DepthT Depth = 'D - DepthT (proxy (d :: *)) = 'S d - DepthT (proxy (ds :: DS *)) = ds + DepthT (proxy (d :: Type)) = 'S d + DepthT (proxy (ds :: DS Type)) = ds -type family StaticDepthT a :: * where - StaticDepthT (proxy ('S (d :: *))) = d - StaticDepthT (proxy (d :: *)) = d - StaticDepthT (d :: *) = d +type family StaticDepthT a :: Type where + StaticDepthT (proxy ('S (d :: Type))) = d + StaticDepthT (proxy (d :: Type)) = d + StaticDepthT (d :: Type) = d diff --git a/opencv/src/OpenCV/Internal/Core/Types/Mat/HMat.hs b/opencv/src/OpenCV/Internal/Core/Types/Mat/HMat.hs index 9c27fc23..68cca97e 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Mat/HMat.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Mat/HMat.hs @@ -24,9 +24,6 @@ import "base" Foreign.C.Types import "base" Foreign.Ptr ( Ptr ) import "base" Foreign.Storable ( Storable(..), peekElemOff, pokeElemOff ) import "base" System.IO.Unsafe ( unsafePerformIO ) -#ifndef OPENCV4 -import qualified "bytestring" Data.ByteString as B -#endif import "linear" Linear.Vector ( zero ) import "linear" Linear.V4 ( V4(..) ) import "this" OpenCV.Core.Types @@ -54,9 +51,6 @@ data HElems | HElems_32S !(VU.Vector Int32) | HElems_32F !(VU.Vector Float) | HElems_64F !(VU.Vector Double) -#ifndef OPENCV4 - | HElems_USRTYPE1 !(V.Vector B.ByteString) -#endif deriving (Show, Eq) hElemsDepth :: HElems -> Depth @@ -68,9 +62,6 @@ hElemsDepth = \case HElems_32S _v -> Depth_32S HElems_32F _v -> Depth_32F HElems_64F _v -> Depth_64F -#ifndef OPENCV4 - HElems_USRTYPE1 _v -> Depth_USRTYPE1 -#endif hElemsLength :: HElems -> Int hElemsLength = \case @@ -81,9 +72,6 @@ hElemsLength = \case HElems_32S v -> VG.length v HElems_32F v -> VG.length v HElems_64F v -> VG.length v -#ifndef OPENCV4 - HElems_USRTYPE1 v -> VG.length v -#endif class ToHElems a where toHElems :: VU.Vector a -> HElems @@ -121,9 +109,6 @@ matToHMat mat = unsafePerformIO $ withMatData mat $ \step dataPtr -> do Depth_32S -> HElems_32S <$> copyToVec Depth_32F -> HElems_32F <$> copyToVec Depth_64F -> HElems_64F <$> copyToVec -#ifndef OPENCV4 - Depth_USRTYPE1 -> HElems_USRTYPE1 <$> error "todo" -#endif where copyToVec :: (Storable a, VU.Unbox a) => IO (VU.Vector a) copyToVec = do @@ -159,9 +144,6 @@ hMatToMatIO (HMat shape channels elems) = do HElems_32S v -> copyFromVec v HElems_32F v -> copyFromVec v HElems_64F v -> copyFromVec v -#ifndef OPENCV4 - HElems_USRTYPE1 _v -> error "todo" -#endif where copyFromVec :: (Storable a, VU.Unbox a) => VU.Vector a -> IO () copyFromVec v = diff --git a/opencv/src/OpenCV/Internal/Core/Types/Mat/Marshal.hsc b/opencv/src/OpenCV/Internal/Core/Types/Mat/Marshal.hsc index 0dc21665..2e25feb7 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Mat/Marshal.hsc +++ b/opencv/src/OpenCV/Internal/Core/Types/Mat/Marshal.hsc @@ -32,9 +32,6 @@ import "this" OpenCV.Internal.Core.Types.Mat.Depth #num CV_32S #num CV_32F #num CV_64F -#ifndef OPENCV4 -#num CV_USRTYPE1 -#endif marshalDepth :: Depth -> Int32 marshalDepth = \case @@ -45,9 +42,6 @@ marshalDepth = \case Depth_32S -> c'CV_32S Depth_32F -> c'CV_32F Depth_64F -> c'CV_64F -#ifndef OPENCV4 - Depth_USRTYPE1 -> c'CV_USRTYPE1 -#endif unmarshalDepth :: Int32 -> Depth unmarshalDepth n @@ -58,9 +52,6 @@ unmarshalDepth n | n == c'CV_32S = Depth_32S | n == c'CV_32F = Depth_32F | n == c'CV_64F = Depth_64F -#ifndef OPENCV4 - | n == c'CV_USRTYPE1 = Depth_USRTYPE1 -#endif | otherwise = error $ "unknown depth " <> show n #num CV_CN_SHIFT diff --git a/opencv/src/OpenCV/Internal/Core/Types/Mat/ToFrom.hs b/opencv/src/OpenCV/Internal/Core/Types/Mat/ToFrom.hs index af039da1..f1d07cad 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Mat/ToFrom.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Mat/ToFrom.hs @@ -15,6 +15,7 @@ module OpenCV.Internal.Core.Types.Mat.ToFrom , FromMat(..) ) where +import "base" Data.Kind ( Type ) import "base" Data.Proxy ( Proxy(..) ) import "base" Foreign.Storable ( Storable ) import "base" GHC.TypeLits @@ -48,9 +49,9 @@ C.using "namespace cv" -------------------------------------------------------------------------------- -type family MatShape (a :: *) :: DS [DS Nat] -type family MatChannels (a :: *) :: DS Nat -type family MatDepth (a :: *) :: DS * +type family MatShape (a :: Type) :: DS [DS Nat] +type family MatChannels (a :: Type) :: DS Nat +type family MatDepth (a :: Type) :: DS Type type instance MatShape (Mat shape channels depth) = shape type instance MatChannels (Mat shape channels depth) = channels diff --git a/opencv/src/OpenCV/Internal/Core/Types/Matx.hs b/opencv/src/OpenCV/Internal/Core/Types/Matx.hs index 74ff193e..e90b5df7 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Matx.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Matx.hs @@ -12,13 +12,14 @@ module OpenCV.Internal.Core.Types.Matx , IsMatx(..) ) where +import "base" Data.Kind ( Type ) import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "base" GHC.TypeLits import "this" OpenCV.Internal.C.Types -------------------------------------------------------------------------------- -newtype Matx (dimR :: Nat) (dimC :: Nat) (depth :: *) +newtype Matx (dimR :: Nat) (dimC :: Nat) (depth :: Type) = Matx {unMatx :: ForeignPtr (C'Matx dimR dimC depth)} type instance C (Matx dimR dimC depth) = C'Matx dimR dimC depth @@ -26,13 +27,13 @@ type instance C (Matx dimR dimC depth) = C'Matx dimR dimC depth instance WithPtr (Matx dimR dimC depth) where withPtr = withForeignPtr . unMatx -type family MatxDimR (m :: * -> *) :: Nat -type family MatxDimC (m :: * -> *) :: Nat +type family MatxDimR (m :: Type -> Type) :: Nat +type family MatxDimC (m :: Type -> Type) :: Nat type instance MatxDimR (Matx dimR dimC) = dimR type instance MatxDimC (Matx dimR dimC) = dimC -class IsMatx (m :: * -> *) depth where +class IsMatx (m :: Type -> Type) depth where toMatx :: m depth -> Matx (MatxDimR m) (MatxDimC m) depth fromMatx :: Matx (MatxDimR m) (MatxDimC m) depth -> m depth diff --git a/opencv/src/OpenCV/Internal/Core/Types/Point.hs b/opencv/src/OpenCV/Internal/Core/Types/Point.hs index ea0dc48c..9a87e342 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Point.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Point.hs @@ -14,6 +14,7 @@ module OpenCV.Internal.Core.Types.Point , IsPoint3 ) where +import "base" Data.Kind ( Type ) import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "base" GHC.TypeLits import "linear" Linear ( V2, V3 ) @@ -21,7 +22,7 @@ import "this" OpenCV.Internal.C.Types -------------------------------------------------------------------------------- -newtype Point (dim :: Nat) (depth :: *) +newtype Point (dim :: Nat) (depth :: Type) = Point {unPoint :: ForeignPtr (C'Point dim depth)} type instance C (Point dim depth) = C'Point dim depth @@ -29,14 +30,14 @@ type instance C (Point dim depth) = C'Point dim depth instance WithPtr (Point dim depth) where withPtr = withForeignPtr . unPoint -type family PointDim (v :: * -> *) :: Nat +type family PointDim (v :: Type -> Type) :: Nat type instance PointDim (Point dim) = dim type instance PointDim V2 = 2 type instance PointDim V3 = 3 -class IsPoint (p :: * -> *) (depth :: *) where +class IsPoint (p :: Type -> Type) (depth :: Type) where toPoint :: p depth -> Point (PointDim p) depth fromPoint :: Point (PointDim p) depth -> p depth diff --git a/opencv/src/OpenCV/Internal/Core/Types/Rect.hs b/opencv/src/OpenCV/Internal/Core/Types/Rect.hs index 59a37899..592f8a96 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Rect.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Rect.hs @@ -17,6 +17,7 @@ module OpenCV.Internal.Core.Types.Rect , IsRect(..) ) where +import "base" Data.Kind ( Type ) import "aeson" Data.Aeson import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "linear" Linear.V2 ( V2(..) ) @@ -30,7 +31,7 @@ import "base" Data.Traversable ( Traversable ) -------------------------------------------------------------------------------- -newtype Rect (depth :: *) +newtype Rect (depth :: Type) = Rect {unRect :: ForeignPtr (C'Rect depth)} type instance C (Rect depth) = C'Rect depth @@ -44,8 +45,8 @@ data HRect a , hRectSize :: !(V2 a) } deriving (Foldable, Functor, Traversable, Show) -type family RectPoint (r :: * -> *) :: * -> * -type family RectSize (r :: * -> *) :: * -> * +type family RectPoint (r :: Type -> Type) :: Type -> Type +type family RectSize (r :: Type -> Type) :: Type -> Type type instance RectPoint Rect = Point 2 type instance RectSize Rect = Size @@ -53,7 +54,7 @@ type instance RectSize Rect = Size type instance RectPoint HRect = V2 type instance RectSize HRect = V2 -class IsRect (r :: * -> *) (depth :: *) where +class IsRect (r :: Type -> Type) (depth :: Type) where toRect :: r depth -> Rect depth fromRect :: Rect depth -> r depth diff --git a/opencv/src/OpenCV/Internal/Core/Types/Size.hs b/opencv/src/OpenCV/Internal/Core/Types/Size.hs index ebe22bdd..af1b5509 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Size.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Size.hs @@ -12,13 +12,14 @@ module OpenCV.Internal.Core.Types.Size , IsSize(..) ) where +import "base" Data.Kind ( Type ) import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "linear" Linear ( V2 ) import "this" OpenCV.Internal.C.Types -------------------------------------------------------------------------------- -newtype Size (depth :: *) +newtype Size (depth :: Type) = Size {unSize :: ForeignPtr (C'Size depth)} type instance C (Size depth) = C'Size depth @@ -26,7 +27,7 @@ type instance C (Size depth) = C'Size depth instance WithPtr (Size depth) where withPtr = withForeignPtr . unSize -class IsSize (p :: * -> *) (depth :: *) where +class IsSize (p :: Type -> Type) (depth :: Type) where toSize :: p depth -> Size depth fromSize :: Size depth -> p depth diff --git a/opencv/src/OpenCV/Internal/Core/Types/Vec.hs b/opencv/src/OpenCV/Internal/Core/Types/Vec.hs index 60cb925c..ee0a14b8 100644 --- a/opencv/src/OpenCV/Internal/Core/Types/Vec.hs +++ b/opencv/src/OpenCV/Internal/Core/Types/Vec.hs @@ -11,6 +11,7 @@ module OpenCV.Internal.Core.Types.Vec , IsVec(..) ) where +import "base" Data.Kind ( Type ) import "base" Foreign.ForeignPtr ( ForeignPtr, withForeignPtr ) import "base" GHC.TypeLits import "linear" Linear ( V2, V3, V4 ) @@ -18,7 +19,7 @@ import "this" OpenCV.Internal.C.Types -------------------------------------------------------------------------------- -newtype Vec (dim :: Nat) (depth :: *) +newtype Vec (dim :: Nat) (depth :: Type) = Vec {unVec :: ForeignPtr (C'Vec dim depth)} type instance C (Vec dim depth) = C'Vec dim depth @@ -26,7 +27,7 @@ type instance C (Vec dim depth) = C'Vec dim depth instance WithPtr (Vec dim depth) where withPtr = withForeignPtr . unVec -type family VecDim (v :: * -> *) :: Nat +type family VecDim (v :: Type -> Type) :: Nat type instance VecDim (Vec dim) = dim @@ -34,7 +35,7 @@ type instance VecDim V2 = 2 type instance VecDim V3 = 3 type instance VecDim V4 = 4 -class IsVec (v :: * -> *) (depth :: *) where +class IsVec (v :: Type -> Type) (depth :: Type) where toVec :: v depth -> Vec (VecDim v) depth fromVec :: Vec (VecDim v) depth -> v depth diff --git a/opencv/src/OpenCV/Internal/Exception.hs b/opencv/src/OpenCV/Internal/Exception.hs index 24fd0a90..26be6667 100644 --- a/opencv/src/OpenCV/Internal/Exception.hs +++ b/opencv/src/OpenCV/Internal/Exception.hs @@ -142,9 +142,6 @@ displayDepth depth = show depth ++ " (" ++ haskellDepth ++ ")" Depth_32S -> "Int32" Depth_32F -> "Float" Depth_64F -> "Double" -#ifndef OPENCV4 - Depth_USRTYPE1 -> "not supported in Haskell" -#endif newtype CvCppException = CvCppException { unCvCppException :: ForeignPtr (C CvCppException) } diff --git a/opencv/src/OpenCV/Internal/ImgProc/MiscImgTransform/ColorCodes.hs b/opencv/src/OpenCV/Internal/ImgProc/MiscImgTransform/ColorCodes.hs index 7af5b8ab..d1b3e339 100644 --- a/opencv/src/OpenCV/Internal/ImgProc/MiscImgTransform/ColorCodes.hs +++ b/opencv/src/OpenCV/Internal/ImgProc/MiscImgTransform/ColorCodes.hs @@ -11,6 +11,7 @@ module OpenCV.Internal.ImgProc.MiscImgTransform.ColorCodes where +import "base" Data.Kind ( Type ) import "base" Data.Int ( Int32 ) import "base" Data.Proxy ( Proxy(..) ) import "base" Data.Word @@ -535,7 +536,7 @@ class ColorCodeMatchesChannels (code :: ColorCode) (channels :: DS Nat) instance ColorCodeMatchesChannels code 'D instance (ColorCodeChannels code ~ channels) => ColorCodeMatchesChannels code ('S channels) -type family ColorCodeDepth (srcCode :: ColorCode) (dstCode :: ColorCode) (srcDepth :: DS *) :: DS * where +type family ColorCodeDepth (srcCode :: ColorCode) (dstCode :: ColorCode) (srcDepth :: DS Type) :: DS Type where ColorCodeDepth 'BGR 'BGRA ('S depth) = 'S depth ColorCodeDepth 'RGB 'BGRA ('S depth) = 'S depth ColorCodeDepth 'BGRA 'BGR ('S depth) = 'S depth diff --git a/opencv/src/OpenCV/Internal/ImgProc/StructuralAnalysis.hs b/opencv/src/OpenCV/Internal/ImgProc/StructuralAnalysis.hs index d1c66db0..0262d529 100644 --- a/opencv/src/OpenCV/Internal/ImgProc/StructuralAnalysis.hs +++ b/opencv/src/OpenCV/Internal/ImgProc/StructuralAnalysis.hs @@ -64,7 +64,7 @@ approxHandContourImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Hand) => IO (Mat ('S ['S height, 'S width]) ('S channels) ('S depth)) approxHandContourImg = do @@ -114,7 +114,7 @@ approxPolyDP curve epsilon isClosed approxSizePtr approxPtrPtr (toCDouble epsilon) - (fromIntegral (fromBool isClosed)) + (fromBool isClosed) -- | Internal class used to overload the 'approxPolyDP' depth. class ( FromPtr (Point 2 depth) @@ -271,7 +271,7 @@ handConvexHullImg :: forall (width :: Nat) (height :: Nat) (channels :: Nat) - (depth :: * ) + (depth :: Type ) . (Mat ('S ['S height, 'S width]) ('S channels) ('S depth) ~ Hand) => IO (Mat ('S ['S height, 'S width]) ('S channels) ('S depth)) handConvexHullImg = do @@ -322,7 +322,7 @@ convexHull points clockwise convexHull_internal (fromIntegral $ V.length points) pointsPtr - (fromIntegral (fromBool clockwise)) + (fromBool clockwise) hullPointsPtrPtr hullSizePtr where @@ -449,7 +449,7 @@ convexHullIndices points clockwise convexHullIndices_internal (fromIntegral $ V.length points) pointsPtr - (fromIntegral (fromBool clockwise)) + (fromBool clockwise) hullIndicesPtrPtr hullSizePtr where diff --git a/opencv/src/OpenCV/Internal/Mutable.hs b/opencv/src/OpenCV/Internal/Mutable.hs index 26f57dc5..c490d275 100644 --- a/opencv/src/OpenCV/Internal/Mutable.hs +++ b/opencv/src/OpenCV/Internal/Mutable.hs @@ -10,12 +10,13 @@ module OpenCV.Internal.Mutable , FreezeThaw(..) ) where +import "base" Data.Kind ( Type ) import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState ) -- | Wrapper for mutable values newtype Mut a s = Mut { unMut :: a } -type family Mutable (a :: *) :: * -> * +type family Mutable (a :: Type) :: Type -> Type class FreezeThaw a where freeze :: (PrimMonad m) => Mutable a (PrimState m) -> m a diff --git a/opencv/src/OpenCV/JSON.hs b/opencv/src/OpenCV/JSON.hs index a8c12d78..5f95699c 100644 --- a/opencv/src/OpenCV/JSON.hs +++ b/opencv/src/OpenCV/JSON.hs @@ -21,11 +21,6 @@ import "this" OpenCV.Core.Types.Mat.HMat import "this" OpenCV.TypeLevel import "transformers" Control.Monad.Trans.Except -#ifndef OPENCV4 -import qualified "base64-bytestring" Data.ByteString.Base64 as B64 ( encode, decode ) -import qualified "text" Data.Text.Encoding as TE ( encodeUtf8, decodeUtf8 ) -#endif - -------------------------------------------------------------------------------- newtype J a = J {unJ :: a} @@ -91,9 +86,6 @@ instance ToJSON HElems where HElems_32S v -> f "32S" v HElems_32F v -> f "32F" v HElems_64F v -> f "64F" v -#ifndef OPENCV4 - HElems_USRTYPE1 v -> f "USR" $ fmap (TE.decodeUtf8 . B64.encode) v -#endif where f :: (ToJSON a) => Text -> a -> Value f typ v = object [ "type" .= typ @@ -113,9 +105,6 @@ instance FromJSON HElems where "32S" -> HElems_32S <$> elems "32F" -> HElems_32F <$> elems "64F" -> HElems_64F <$> elems -#ifndef OPENCV4 - "USR" -> HElems_USRTYPE1 <$> (mapM (either fail pure . B64.decode . TE.encodeUtf8) =<< elems) -#endif _ -> fail $ "Unknown Helems type " <> T.unpack typ -------------------------------------------------------------------------------- diff --git a/opencv/src/OpenCV/Video.hsc b/opencv/src/OpenCV/Video.hsc index 39e47473..032cd44c 100644 --- a/opencv/src/OpenCV/Video.hsc +++ b/opencv/src/OpenCV/Video.hsc @@ -35,9 +35,7 @@ C.using "namespace cv" -------------------------------------------------------------------------------- -#ifdef OPENCV4 {-# DEPRECATED estimateRigidTransform "Use estimateAffine2D or estimateAffinePartial2D instead" #-} -#endif -- | Computes an optimal affine transformation between two 2D point sets -- diff --git a/overlay.nix b/overlay.nix index cf25d793..3fbab8b3 100644 --- a/overlay.nix +++ b/overlay.nix @@ -1,12 +1,8 @@ -enableOpencv4 : final : previous : with final.lib; with final.haskell.lib; +final : previous : with final.lib; with final.haskell.lib; let - handleOpencv4 = drv : if enableOpencv4 then enableCabalFlag drv "opencv4" else drv; - useOpencvHighgui = drv : overrideCabal drv (_drv: { libraryPkgconfigDepends = [ - (if enableOpencv4 - then final.opencv4_highgui - else final.opencv3_highgui) + final.opencv4_highgui ]; }); @@ -19,7 +15,7 @@ let ]); }); in { - opencv = handleOpencv4 (addBuildToolsInShell (doBenchmark (overrideCabal (super.callCabal2nix "opencv" ./opencv {}) (drv : { + opencv = addBuildToolsInShell (doBenchmark (overrideCabal (super.callCabal2nix "opencv" ./opencv {}) (drv : { src = final.runCommand "opencv-src" { files = final.lib.sourceByRegex ./opencv [ "^src$" @@ -46,9 +42,8 @@ let shellHook = '' export hardeningDisable=bindnow ''; - } // optionalAttrs enableOpencv4 { libraryPkgconfigDepends = [ final.opencv4 ]; - })))); + }))); opencv_highgui = useOpencvHighgui self.opencv; @@ -73,7 +68,7 @@ let }))).override { opencv = self.opencv_highgui; }; opencv-extra = - handleOpencv4 (addBuildToolsInShell (overrideCabal (super.callCabal2nix "opencv-extra" ./opencv-extra {}) (_drv : { + addBuildToolsInShell (overrideCabal (super.callCabal2nix "opencv-extra" ./opencv-extra {}) (_drv : { src = final.runCommand "opencv-extra-src" { files = final.lib.sourceByRegex ./opencv-extra [ "^include$" @@ -98,11 +93,9 @@ let ''; # TODO (BvD): This should be added by cabal2nix. Fix this upstream. libraryPkgconfigDepends = [ - (if enableOpencv4 - then final.opencv4 - else final.opencv3) + final.opencv4 ]; - }))); + })); opencv-extra_highgui = (useOpencvHighgui self.opencv-extra).override { opencv = self.opencv_highgui; @@ -137,9 +130,6 @@ in { haskellOverrides self super; }; - opencv3_highgui = previous.opencv3.override { - enableGtk3 = !final.stdenv.isDarwin; - }; opencv4_highgui = previous.opencv4.override { enableGtk3 = !final.stdenv.isDarwin; }; diff --git a/stack.yaml b/stack.yaml index 6ed7d4f0..1147973f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,18 +1,26 @@ -resolver: lts-14.3 +resolver: lts-20.26 # ghc-9.2.8 +# resolver: lts-20.11 # ghc-9.2.5 packages: - opencv/ - opencv-examples/ - opencv-extra/ - opencv-extra-examples/ -flags: {} -allow-newer: true -extra-lib-dirs: -- /usr/local/lib +# To test unfree modules such as SIFT and SURF: +# flags: +# opencv-extra: +# enable-nonfree: true + +allow-newer: true nix: - path: [ "nixpkgs=https://github.com/NixOS/nixpkgs/archive/8d1510abfb592339e13ce8f6db6f29c1f8b72924.tar.gz" ] - packages: [ zlib pkgconfig opencv3 ] + path: [ "nixpkgs=https://github.com/NixOS/nixpkgs/archive/da5adce0ffaff10f6d0fee72a02a5ed9d01b52fc.tar.gz" ] # nixos-22.11 with opencv4-4.7, and providing ghc-9.2.8 + # path: [ "nixpkgs=https://github.com/NixOS/nixpkgs/archive/ea4c80b39be4c09702b0cb3b42eab59e2ba4f24b.tar.gz" ] # nixos-22.11 with opencv4-4.6, and providing ghc-9.2.5 + packages: + - zlib + - gmp + - pkg-config + - opencv4 # Uncomment if you wish to use Docker integration # See README.md for further information.