never executed always true always false
1 {-# LANGUAGE QuasiQuotes #-}
2 {-# LANGUAGE TemplateHaskell #-}
3
4 module OpenCV.ImgCodecs
5 ( ImreadMode(..)
6 , imdecode
7 , imdecodeM
8
9 , OutputFormat(..)
10 , JpegParams(..), defaultJpegParams
11 , PngStrategy(..)
12 , PngParams(..), defaultPngParams
13 , imencode
14 , imencodeM
15 ) where
16
17 import "base" Control.Exception ( mask_ )
18 import "base" Data.Int ( Int32 )
19 import "base" Foreign.C.String ( withCString )
20 import "base" Foreign.C.Types
21 import "base" Foreign.Marshal.Alloc ( alloca )
22 import "base" Foreign.Ptr ( Ptr, nullPtr, castPtr )
23 import "base" Foreign.Storable ( peek )
24 import "base" System.IO.Unsafe ( unsafePerformIO )
25 import "bytestring" Data.ByteString ( ByteString )
26 import qualified "bytestring" Data.ByteString.Unsafe as BU
27 import qualified "inline-c" Language.C.Inline as C
28 import qualified "inline-c-cpp" Language.C.Inline.Cpp as C
29 import "primitive" Control.Monad.Primitive ( PrimMonad, PrimState )
30 import "this" OpenCV.Core.Types.Mat
31 import "this" OpenCV.Internal.C.Inline ( openCvCtx )
32 import "this" OpenCV.Internal.C.Types
33 import "this" OpenCV.Internal.Core.Types.Mat
34 import "this" OpenCV.Internal.Exception
35 import "this" OpenCV.Internal.ImgCodecs
36 import "this" OpenCV.Internal.Mutable
37 import "this" OpenCV.TypeLevel
38 import "transformers" Control.Monad.Trans.Except
39
40
41 --------------------------------------------------------------------------------
42
43 C.context openCvCtx
44
45 C.include "<vector>"
46 C.include "opencv2/core.hpp"
47 C.include "opencv2/imgcodecs.hpp"
48 C.using "namespace cv"
49
50
51 --------------------------------------------------------------------------------
52
53 -- | Reads an image from a buffer in memory.
54 --
55 -- The function reads an image from the specified buffer in the
56 -- memory. If the buffer is too short or contains invalid data, the
57 -- empty matrix/image is returned.
58 --
59 -- <http://docs.opencv.org/3.0-last-rst/modules/imgcodecs/doc/reading_and_writing_images.html#imdecode OpenCV Sphinx doc>
60 imdecode
61 :: ImreadMode
62 -> ByteString
63 -> Mat ('S ['D, 'D]) 'D 'D
64 imdecode imreadMode hbuf = unsafeCoerceMat $ unsafePerformIO $ fromPtr
65 [C.block|Mat * {
66 cv::_InputArray cbuf = cv::_InputArray($bs-ptr:hbuf, $bs-len:hbuf);
67 return new cv::Mat(cv::imdecode(cbuf, $(int32_t c'imreadMode)));
68 }|]
69 where
70 c'imreadMode = marshalImreadMode imreadMode
71
72 imdecodeM
73 :: (PrimMonad m)
74 => ImreadMode
75 -> ByteString
76 -> m (Mut (Mat ('S ['D, 'D]) 'D 'D) (PrimState m))
77 imdecodeM imreadMode hbuf = unsafeThaw $ imdecode imreadMode hbuf
78
79 --------------------------------------------------------------------------------
80
81 -- | Encodes an image into a memory buffer.
82 --
83 -- __WARNING:__ This function is not thread safe!
84 --
85 -- <http://docs.opencv.org/3.0-last-rst/modules/imgcodecs/doc/reading_and_writing_images.html#imencode OpenCV Sphinx doc>
86 imencode
87 :: OutputFormat
88 -> Mat shape channels depth
89 -> CvExcept ByteString
90 imencode format mat = unsafeWrapException $
91 withPtr mat $ \matPtr ->
92 withCString ext $ \extPtr ->
93 alloca $ \(bufPtrPtr :: Ptr (Ptr CUChar)) ->
94 alloca $ \(vecPtrPtr :: Ptr (Ptr ())) ->
95 alloca $ \(c'bufSizePtr :: Ptr Int32) -> mask_ $ do
96 ptrException <- [cvExcept|
97 const int * const paramsPtr = $vec-ptr:(int * params);
98 std::vector<uchar> * vec = new std::vector<uchar>();
99 *$(void * * vecPtrPtr) = reinterpret_cast<void *>(vec);
100 std::vector<int> params(paramsPtr, paramsPtr + $vec-len:params);
101 cv::imencode( $(char * extPtr)
102 , *$(Mat * matPtr)
103 , *vec
104 , params
105 );
106 *$(int32_t * c'bufSizePtr) = vec->size();
107 *$(unsigned char * * bufPtrPtr) = &((*vec)[0]);
108 |]
109 vecPtr <- peek vecPtrPtr
110 if ptrException /= nullPtr
111 then do
112 freeVec vecPtr
113 Left . BindingException <$> fromPtr (pure ptrException)
114 else do
115 bufSize <- peek c'bufSizePtr
116 bufPtr <- peek bufPtrPtr
117 bs <- BU.unsafePackCStringFinalizer
118 (castPtr bufPtr)
119 (fromIntegral bufSize)
120 (freeVec vecPtr)
121 pure $ Right bs
122 where
123 (ext, params) = marshalOutputFormat format
124
125 freeVec :: Ptr () -> IO ()
126 freeVec vecPtr = [C.exp|void { delete reinterpret_cast< std::vector<uchar> * >($(void * vecPtr)) }|]
127
128 -- | Encodes an image into a memory buffer.
129 --
130 -- See 'imencode'
131 imencodeM
132 :: (PrimMonad m)
133 => OutputFormat
134 -> Mut (Mat shape channels depth) (PrimState m)
135 -> CvExceptT m ByteString
136 imencodeM format matM =
137 ExceptT . pure . runExcept =<< (imencode format <$> unsafeFreeze matM)