1 /*******************************************************************************
2 * Copyright 2016-2019 Intel Corporation.
3 *
4 * This software and the related documents are Intel copyrighted materials, and
5 * your use of them is governed by the express license under which they were
6 * provided to you (License). Unless the License provides otherwise, you may not
7 * use, modify, copy, publish, distribute, disclose or transmit this software or
8 * the related documents without Intel's prior written permission.
9 *
10 * This software and the related documents are provided as is, with no express
11 * or implied warranties, other than those that are expressly stated in the
12 * License.
13 *******************************************************************************/
14
15 #if !defined( __IPP_IW_OWNI__ )
16 #define __IPP_IW_OWNI__
17
18 #include "iw_own.h"
19
20 #ifndef IW_BUILD
21 #error this is a private header
22 #endif
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 /* /////////////////////////////////////////////////////////////////////////////
29 // Base IW Image internal definitions
30 ///////////////////////////////////////////////////////////////////////////// */
31 #define OWN_ALIGN_ROW 64
32
33 #define OWN_ROI_FIT(SIZE, ROI)\
34 {\
35 if((ROI).x < 0)\
36 (ROI).x = 0;\
37 if((ROI).y < 0)\
38 (ROI).y = 0;\
39 if((ROI).x > (SIZE).width)\
40 (ROI).x = (SIZE).width;\
41 if((ROI).y > (SIZE).height)\
42 (ROI).y = (SIZE).height;\
43 if(!(ROI).width || ((ROI).width + (ROI).x) > (SIZE).width)\
44 (ROI).width = (SIZE).width - (ROI).x;\
45 if(!(ROI).height || ((ROI).height + (ROI).y) > (SIZE).height)\
46 (ROI).height = (SIZE).height - (ROI).y;\
47 }
48
49 #define OWN_GET_PURE_BORDER(BORDER) ((IwiBorderType)((BORDER)&0xF))
50 #define OWN_GET_BORDER_VAL(TYPE) ((OWN_GET_PURE_BORDER(border) == ippBorderConst && pBorderVal)?(ownCast_64f##TYPE(pBorderVal[0])):0)
51 #define OWN_GET_BORDER_VALP(TYPE, CH) ((OWN_GET_PURE_BORDER(border) == ippBorderConst && pBorderVal)?(ownCastArray_64f##TYPE(pBorderVal, borderVal, (CH))):0)
52 #define OWN_GET_BORDER_VAL2(PRECOMP, TYPE) ((OWN_GET_PURE_BORDER(border) == ippBorderConst && pBorderVal)?((PRECOMP)?*((Ipp##TYPE*)pBorderVal):(ownCast_64f##TYPE(pBorderVal[0]))):0)
53 #define OWN_GET_BORDER_VALP2(PRECOMP, TYPE, CH) ((OWN_GET_PURE_BORDER(border) == ippBorderConst && pBorderVal)?((PRECOMP)?((Ipp##TYPE*)pBorderVal):(ownCastArray_64f##TYPE(pBorderVal, borderVal, (CH)))):0)
54 #define OWN_GET_BORDER_VAL3(BORDER, ARR) ((OWN_GET_PURE_BORDER(BORDER) == ippBorderConst && (ARR))?(ARR):0)
55
56 typedef enum _OwniChCodes
57 {
58 owniC_Invalid = 0,
59 owniC1,
60 owniC1C3,
61 owniC1C4,
62 owniC3,
63 owniC3C1,
64 owniC3C4,
65 owniC4,
66 owniC4C1,
67 owniC4C3,
68 owniC4M1110,
69 owniC4M1000,
70 owniC4M1001,
71 owniC4M1RR0,
72 owniC4M1RR1
73
74 } OwniChCodes;
75
76 #define OWN_DESC_GET_CH(DESC) (((DESC)>>12)&0xF)
77 #define OWN_DESC_GET_REPL_CH(DESC) (((DESC)>>24)&0xF)
78 #define OWN_DESC_CHECK_MASK(DESC, CH) (((DESC)>>(CH))&0x1)
79 #define OWN_DESC_CHECK_REPL(DESC, CH) (((DESC)>>((CH)+16))&0x1)
80
81 /* /////////////////////////////////////////////////////////////////////////////
82 // Utility functions
83 ///////////////////////////////////////////////////////////////////////////// */
84 IW_DECL(OwniChCodes) owniChDescriptorToCode(IwiChDescriptor chDesc, int srcChannels, int dstChannels);
85
owniShiftPtrConst(const void * pPtr,IwSize step,int typeSize,int channels,IwSize x,IwSize y)86 static IW_INLINE const void* owniShiftPtrConst(const void *pPtr, IwSize step, int typeSize, int channels, IwSize x, IwSize y)
87 {
88 return (((Ipp8u*)pPtr) + step*y + typeSize*channels*x);
89 }
90
owniShiftPtrArrConst(const void * const pSrcPtr[],const void * pDstPtr[],IwSize step[],int pixelSize[],int planes,IwSize x,IwSize y)91 static IW_INLINE void owniShiftPtrArrConst(const void* const pSrcPtr[], const void* pDstPtr[], IwSize step[], int pixelSize[], int planes, IwSize x, IwSize y)
92 {
93 int i;
94 for(i = 0; i < planes; i++)
95 {
96 if(pSrcPtr[i])
97 pDstPtr[i] = owniShiftPtrConst(pSrcPtr[i], step[i], pixelSize[i], 1, x, y);
98 }
99 }
100
owniShiftPtr(const void * pPtr,IwSize step,int typeSize,int channels,IwSize x,IwSize y)101 static IW_INLINE void* owniShiftPtr(const void *pPtr, IwSize step, int typeSize, int channels, IwSize x, IwSize y)
102 {
103 return (((Ipp8u*)pPtr) + step*y + typeSize*channels*x);
104 }
105
owniShiftPtrArr(void * const pSrcPtr[],void * pDstPtr[],IwSize step[],int pixelSize[],int planes,IwSize x,IwSize y)106 static IW_INLINE void owniShiftPtrArr(void* const pSrcPtr[], void* pDstPtr[], IwSize step[], int pixelSize[], int planes, IwSize x, IwSize y)
107 {
108 int i;
109 for(i = 0; i < planes; i++)
110 {
111 if(pSrcPtr[i])
112 pDstPtr[i] = owniShiftPtr(pSrcPtr[i], step[i], pixelSize[i], 1, x, y);
113 }
114 }
115
owniAlignStep(IwSize step,int align)116 static IW_INLINE IwSize owniAlignStep(IwSize step, int align)
117 {
118 return (step + (align - 1)) & -align;
119 }
120
owniGetMinSize(const IwiSize * pFirst,const IwiSize * pSecond)121 static IW_INLINE IwiSize owniGetMinSize(const IwiSize *pFirst, const IwiSize *pSecond)
122 {
123 IwiSize size;
124 size.width = IPP_MIN(pFirst->width, pSecond->width);
125 size.height = IPP_MIN(pFirst->height, pSecond->height);
126 return size;
127 }
owniGetMinSizeFromRect(const IwiRoi * pFirst,const IwiRoi * pSecond)128 static IW_INLINE IwiSize owniGetMinSizeFromRect(const IwiRoi *pFirst, const IwiRoi *pSecond)
129 {
130 IwiSize size;
131 size.width = IPP_MIN(pFirst->width, pSecond->width);
132 size.height = IPP_MIN(pFirst->height, pSecond->height);
133 return size;
134 }
135
owniCheckImageRead(const IwiImage * pImage)136 static IW_INLINE IppStatus owniCheckImageRead(const IwiImage *pImage)
137 {
138 if(!pImage)
139 return ippStsNullPtrErr;
140 if(!pImage->m_size.width || !pImage->m_size.height)
141 return ippStsNoOperation;
142 if(!pImage->m_ptrConst)
143 return ippStsNullPtrErr;
144 return ippStsNoErr;
145 }
146
owniCheckImageWrite(const IwiImage * pImage)147 static IW_INLINE IppStatus owniCheckImageWrite(const IwiImage *pImage)
148 {
149 if(!pImage)
150 return ippStsNullPtrErr;
151 if(!pImage->m_size.width || !pImage->m_size.height)
152 return ippStsNoOperation;
153 if(!pImage->m_ptr)
154 return ippStsNullPtrErr;
155 return ippStsNoErr;
156 }
157
owniCheckBorderValidity(IwiBorderType border)158 static IW_INLINE int owniCheckBorderValidity(IwiBorderType border)
159 {
160 // Create bit-mask for all valid values
161 #if IPP_VERSION_COMPLEX >= 20170002
162 static const int validMask = ippBorderInMem|ippBorderFirstStageInMem|ippBorderRepl|ippBorderWrap|ippBorderMirror|ippBorderMirrorR|ippBorderDefault|ippBorderConst|ippBorderTransp;
163 #else
164 static const int validMask = ippBorderInMem|ippBorderRepl|ippBorderWrap|ippBorderMirror|ippBorderMirrorR|ippBorderDefault|ippBorderConst|ippBorderTransp;
165 #endif
166
167 // Check if fully in memory
168 if(!((border&ippBorderInMem) == ippBorderInMem))
169 {
170 // If border is only partially in memory it must have extrapolation type for non-in-memory parts
171 if(!OWN_GET_PURE_BORDER(border))
172 return 0;
173 }
174
175 // Check for invalid bits
176 if(border&(~validMask))
177 return 0;
178 else
179 return 1;
180 }
181
owniSuggestThreadsNum(int maxThreads,const IwiImage * pImage,double multiplier)182 static IW_INLINE int owniSuggestThreadsNum(int maxThreads, const IwiImage *pImage, double multiplier)
183 {
184 if(pImage->m_size.height > maxThreads)
185 {
186 size_t opMemory = (int)(pImage->m_step*pImage->m_size.height*multiplier);
187 int l2cache = 0;
188 if(ippGetL2CacheSize(&l2cache) < 0 || !l2cache)
189 l2cache = 100000;
190
191 return IPP_MAX(1, (IPP_MIN((int)(opMemory/(l2cache*0.6)), maxThreads)));
192 }
193 return 1;
194 }
195
owniBorderSizeIsNegative(const IwiBorderSize * pBorderSize)196 static IW_INLINE int owniBorderSizeIsNegative(const IwiBorderSize *pBorderSize)
197 {
198 if(pBorderSize->left < 0 || pBorderSize->top < 0 || pBorderSize->right < 0 || pBorderSize->bottom < 0)
199 return 1;
200 return 0;
201 }
202
owniBorderSizeSaturate(IwiBorderSize * pBorderSize)203 static IW_INLINE void owniBorderSizeSaturate(IwiBorderSize *pBorderSize)
204 {
205 if(pBorderSize->left < 0)
206 pBorderSize->left = 0;
207 if(pBorderSize->top < 0)
208 pBorderSize->top = 0;
209 if(pBorderSize->right < 0)
210 pBorderSize->right = 0;
211 if(pBorderSize->bottom < 0)
212 pBorderSize->bottom = 0;
213 }
214
215 /* /////////////////////////////////////////////////////////////////////////////
216 // Long types compatibility checkers
217 ///////////////////////////////////////////////////////////////////////////// */
owniLongCompatCheckPoint(IppiPointL pointL,IppiPoint * pPoint)218 static IW_INLINE IppStatus owniLongCompatCheckPoint(IppiPointL pointL, IppiPoint *pPoint)
219 {
220 #if defined (_M_AMD64) || defined (__x86_64__)
221 if(OWN_IS_EXCEED_INT(pointL.x) || OWN_IS_EXCEED_INT(pointL.y))
222 return ippStsSizeErr;
223 else
224 #endif
225 if(pPoint)
226 {
227 pPoint->x = (int)pointL.x;
228 pPoint->y = (int)pointL.y;
229 }
230 return ippStsNoErr;
231 }
232
owniLongCompatCheckSize(IwiSize sizeL,IppiSize * pSize)233 static IW_INLINE IppStatus owniLongCompatCheckSize(IwiSize sizeL, IppiSize *pSize)
234 {
235 #if defined (_M_AMD64) || defined (__x86_64__)
236 if(OWN_IS_EXCEED_INT(sizeL.width) || OWN_IS_EXCEED_INT(sizeL.height))
237 return ippStsSizeErr;
238 else
239 #endif
240 if(pSize)
241 {
242 pSize->width = (int)sizeL.width;
243 pSize->height = (int)sizeL.height;
244 }
245 return ippStsNoErr;
246 }
247
248 /* /////////////////////////////////////////////////////////////////////////////
249 // OWN ROI manipulation
250 ///////////////////////////////////////////////////////////////////////////// */
251 IW_DECL(IwiSize) owniSuggestTileSize_k2(const IwiImage *pImage, IwiSize kernelSize, double multiplier);
owniSuggestTileSize_k1(const IwiImage * pImage,IwSize kernelLen,double multiplier)252 static IW_INLINE IwiSize owniSuggestTileSize_k1(const IwiImage *pImage, IwSize kernelLen, double multiplier)
253 {
254 IwiSize kernelSize;
255 kernelSize.width = kernelLen;
256 kernelSize.height = kernelLen;
257 return owniSuggestTileSize_k2(pImage, kernelSize, multiplier);
258 }
owniSuggestTileSize_k0(const IwiImage * pImage,double multiplier)259 static IW_INLINE IwiSize owniSuggestTileSize_k0(const IwiImage *pImage, double multiplier)
260 {
261 IwiSize kernelSize = {1, 1};
262 return owniSuggestTileSize_k2(pImage, kernelSize, multiplier);
263 }
264
265 IW_DECL(int) owniTile_BoundToSize(IwiRoi *pRoi, IwiSize *pMinSize);
266 IW_DECL(int) owniTile_CorrectBordersOverlap(IwiRoi *pRoi, IwiSize *pMinSize, const IwiBorderType *pBorder, const IwiBorderSize *pBorderSize, const IwiBorderSize *pBorderSizeAcc, const IwiSize *pSrcImageSize);
267 IW_DECL(void) owniTile_GetTileBorder(IwiBorderType *pBorder, const IwiRoi *pRoi, const IwiBorderSize *pBorderSize, const IwiSize *pSrcImageSize);
268 IW_DECL(IppStatus) owniTilePipeline_ProcBorder(const IwiTile *pTile, IwiImage *pSrcImage, IwiBorderType *pBorder, const Ipp64f *pBorderVal);
269
270 #ifdef __cplusplus
271 }
272 #endif
273
274 #endif
275