Move the sources to trunk
[opencv] / interfaces / ipp / dllmain.c
1 /* /////////////////////////////////////////////////////////////////////////////
2 //
3 //                  INTEL CORPORATION PROPRIETARY INFORMATION
4 //     This software is supplied under the terms of a license agreement or
5 //     nondisclosure agreement with Intel Corporation and may not be copied
6 //     or disclosed except in accordance with the terms of that agreement.
7 //          Copyright(c) 1999-2004 Intel Corporation. All Rights Reserved.
8 //
9 */
10
11 static const char* SET_LIB_ERR = "Set ipp library error";
12
13 #if defined( _WIN32 )
14   #define STRICT
15   #define WIN32_LEAN_AND_MEAN
16   #include <windows.h>
17 #elif defined( linux )
18 #endif  /* _WIN32 */
19
20 /* Describe Intel CPUs and libraries */
21 typedef enum{CPU_PX=0, CPU_A6, CPU_W7, CPU_T7, CPU_NOMORE} cpu_enum;
22 typedef enum{LIB_PX=0, LIB_A6, LIB_W7, LIB_T7, LIB_NOMORE} lib_enum;
23
24 typedef unsigned char uchar;
25 typedef unsigned short ushort;
26 typedef __int64 int64;
27
28 #include "ippcore.h"
29
30 #if IPP < 500
31 #define ippGetCpuType ippCoreGetCpuType
32 #endif
33
34 static cpu_enum GetProcessorId()
35 {
36    switch ( ippGetCpuType() ) {
37       case ippCpuPP:
38       case ippCpuPMX:
39       case ippCpuPPR:  
40       case ippCpuPII:   return CPU_PX;
41       case ippCpuITP:   return CPU_A6;
42       case ippCpuITP2:  return CPU_A6;
43       case ippCpuPIII:  return CPU_A6;
44       case ippCpuP4:
45       case ippCpuCentrino:
46       case ippCpuP4HT:  return CPU_W7;
47       case ippCpuEM64T: return CPU_T7;
48       case ippCpuP4HT2: return CPU_T7;
49       default: return CPU_PX;
50    }
51 }
52
53 #undef IPPAPI
54
55 #define IPPAPI(type,name,arg)
56 #include "ipp.h"
57
58
59 /* New cpu can use some libraries for old cpu */
60 static const lib_enum libUsage[][LIB_NOMORE+1] = {
61      /*  LIB_T7, LIB_W7, LIB_A6, LIB_PX, LIB_NOMORE */
62 /*PX*/ {                 LIB_PX, LIB_NOMORE },
63 /*A6*/ {         LIB_A6, LIB_PX, LIB_NOMORE },
64 /*W7*/ { LIB_W7, LIB_A6, LIB_PX, LIB_NOMORE },
65 /*T7*/ { LIB_T7, LIB_W7, LIB_A6, LIB_PX, LIB_NOMORE }
66 };
67
68 #if !defined (PX) && !defined (A6) && !defined (W7) && !defined (T7)
69   #error Are not defined the CPUs, following are allowed: PX, A6, W7, T7
70 #endif
71
72 #ifdef __cplusplus
73 extern "C" {
74 #endif
75 #ifdef PX
76   #undef  IPPAPI
77   #define IPPAPI(type,name,arg) extern type __stdcall px_##name arg;
78   #define PX_NAME(name) (FARPROC)px_##name
79   #include "opencvipp_funclist.h"
80 #else
81   #define PX_NAME(name) NULL
82 #endif
83
84 #ifdef A6
85   #undef  IPPAPI
86   #define IPPAPI(type,name,arg) extern type __stdcall a6_##name arg;
87   #define A6_NAME(name) (FARPROC)a6_##name
88   #include "opencvipp_funclist.h"
89 #else
90   #define A6_NAME(name) NULL
91 #endif
92
93 #ifdef W7
94   #undef  IPPAPI
95   #define IPPAPI(type,name,arg) extern type __stdcall w7_##name arg;
96   #define W7_NAME(name) (FARPROC)w7_##name
97   #include "opencvipp_funclist.h"
98 #else
99   #define W7_NAME(name) NULL
100 #endif
101
102 #ifdef T7
103   #undef  IPPAPI
104   #define IPPAPI(type,name,arg) extern type __stdcall t7_##name arg;
105   #define T7_NAME(name) (FARPROC)t7_##name
106   #include "opencvipp_funclist.h"
107 #else
108   #define T7_NAME(name) NULL
109 #endif
110 #ifdef __cplusplus
111 }
112 #endif
113
114 #ifdef __cplusplus
115 #define IPP_EXTERN_C extern "C"
116 #else
117 #define IPP_EXTERN_C
118 #endif
119
120 #undef  IPPAPI
121 #define IPPAPI(type,name,arg) \
122     static FARPROC d##name; \
123     IPP_EXTERN_C __declspec(naked dllexport) void __stdcall name arg { __asm {jmp d##name } }
124 #include "opencvipp_funclist.h"
125
126
127 typedef struct _USER_Desc_t {
128     FARPROC*            WorkAddr;
129     FARPROC FuncAddr[CPU_NOMORE];
130 } USER_Desc_t;
131
132 static USER_Desc_t AddressBook[] = {
133 #undef  IPPAPI
134 #define IPPAPI(type,name,arg) &d##name, \
135     PX_NAME(name), A6_NAME(name), W7_NAME(name), T7_NAME(name),
136 #include "opencvipp_funclist.h"
137 };
138
139 /* how large is the table of the functions */
140 static int sFuncCount  = sizeof( AddressBook ) / sizeof( AddressBook[0] );
141
142 /* fill ipp function address book in correspondence to the target cpu */
143 static BOOL SetLib( lib_enum lib )
144 {
145    int i = 0;
146    for ( i=0; i<sFuncCount; i++ )
147       if( NULL == AddressBook[i].FuncAddr[lib] )
148          return FALSE;
149       else
150         *(AddressBook[i].WorkAddr) = AddressBook[i].FuncAddr[lib];
151    return TRUE;
152 }
153
154 static BOOL setCpuSpecificLib()
155 {
156    char buf[256] = "";
157    cpu_enum cpu = GetProcessorId();
158    if( sFuncCount > 0 && cpu >= CPU_PX && cpu < CPU_NOMORE ) {
159
160       const lib_enum* libs = libUsage[ cpu ];
161       while( *libs < LIB_NOMORE )
162          if( SetLib( *libs++ ) ) return TRUE;     /* SUCCESS EXIT */
163    }
164    /* if not found, then failed with error message */
165    lstrcpy( buf, " No ipp matching to CPU was found during the Waterfall" );
166    MessageBeep( MB_ICONSTOP );
167    MessageBox( 0, buf, SET_LIB_ERR, MB_ICONSTOP | MB_OK );
168    return FALSE;
169 }
170
171
172 BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason,
173                     LPVOID lpvReserved )
174 {
175     switch( fdwReason ) {
176       case DLL_PROCESS_ATTACH: if( !setCpuSpecificLib() )return FALSE;
177
178     default:
179         hinstDLL;
180         lpvReserved;
181         break;
182     }
183     return TRUE;
184 }
185
186 /* //////////////////////// End of file "dllmain.c" ///////////////////////// */