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