16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************/
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*                         Dynamic detection and loading of IPP modules                 */
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************/
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cxcore.h"
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined _MSC_VER && _MSC_VER >= 1200
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#pragma warning( disable: 4115 )        /* type definition in () */
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined _MSC_VER && defined WIN64 && !defined EM64T
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#pragma optimize( "", off )
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 || defined WIN64
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <windows.h>
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <dlfcn.h>
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <sys/time.h>
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <string.h>
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <stdio.h>
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include <ctype.h>
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_GENERIC             0
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_SHIFT               10
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_ARCH_MASK           ((1 << CV_PROC_SHIFT) - 1)
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_IA32_GENERIC        1
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_IA32_WITH_MMX       (CV_PROC_IA32_GENERIC|(2 << CV_PROC_SHIFT))
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_IA32_WITH_SSE       (CV_PROC_IA32_GENERIC|(3 << CV_PROC_SHIFT))
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_IA32_WITH_SSE2      (CV_PROC_IA32_GENERIC|(4 << CV_PROC_SHIFT))
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_IA64                2
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_PROC_EM64T               3
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_GET_PROC_ARCH(model)     ((model) & CV_PROC_ARCH_MASK)
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvProcessorInfo
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int model;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int count;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double frequency; // clocks per microsecond
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvProcessorInfo;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef MASM_INLINE_ASSEMBLY
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 && !defined  WIN64
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined _MSC_VER
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MASM_INLINE_ASSEMBLY 1
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif defined __BORLANDC__
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if __BORLANDC__ >= 0x560
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define MASM_INLINE_ASSEMBLY 1
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   determine processor type
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvInitProcessorInfo( CvProcessorInfo* cpu_info )
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( cpu_info, 0, sizeof(*cpu_info) );
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->model = CV_PROC_GENERIC;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 || defined WIN64
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifndef PROCESSOR_ARCHITECTURE_AMD64
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define PROCESSOR_ARCHITECTURE_AMD64 9
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    SYSTEM_INFO sys;
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    LARGE_INTEGER freq;
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    GetSystemInfo( &sys );
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( sys.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL &&
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        sys.dwProcessorType == PROCESSOR_INTEL_PENTIUM && sys.wProcessorLevel >= 6 )
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int version = 0, features = 0, family = 0;
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int id = 0;
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        HKEY key = 0;
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cpu_info->count = (int)sys.dwNumberOfProcessors;
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        unsigned long val = 0, sz = sizeof(val);
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\SYSTEM\\CentralProcessor\\0\\",
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            0, KEY_QUERY_VALUE, &key ) >= 0 )
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( RegQueryValueEx( key, "~MHz", 0, 0, (uchar*)&val, &sz ) >= 0 )
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cpu_info->frequency = (double)val;
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            RegCloseKey( key );
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef MASM_INLINE_ASSEMBLY
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __asm
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* use CPUID to determine the features supported */
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pushfd
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mov   eax, 1
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            push  ebx
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            push  esi
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            push  edi
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __BORLANDC__
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            db 0fh
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            db 0a2h
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _emit 0x0f
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _emit 0xa2
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pop   edi
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pop   esi
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            pop   ebx
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mov   version, eax
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mov   features, edx
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            popfd
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif defined WIN32 && __GNUC__ > 2
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        asm volatile
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "movl $1,%%eax\n\t"
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ".byte 0x0f; .byte 0xa2\n\t"
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "movl %%eax, %0\n\t"
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "movl %%edx, %1\n\t"
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            : "=r"(version), "=r" (features)
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            :
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            : "%ebx", "%esi", "%edi"
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        );
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            static const char cpuid_code[] =
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                "\x53\x56\x57\xb8\x01\x00\x00\x00\x0f\xa2\x5f\x5e\x5b\xc3";
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            typedef int64 (CV_CDECL * func_ptr)(void);
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            func_ptr cpuid = (func_ptr)(void*)cpuid_code;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int64 cpuid_val = cpuid();
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            version = (int)cpuid_val;
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            features = (int)(cpuid_val >> 32);
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CPUID_M6     ((1<<15)|(1<<23))  /* cmov + MMX */
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CPUID_A6     ((1<<25)|ICV_CPUID_M6) /* <all above> + SSE */
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #define ICV_CPUID_W7     ((1<<26)|ICV_CPUID_A6) /* <all above> + SSE2 */
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        family = (version >> 8) & 15;
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( family >= 6 && (features & ICV_CPUID_M6) != 0 ) /* Pentium II or higher */
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            id = features & ICV_CPUID_W7;
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cpu_info->model = id == ICV_CPUID_W7 ? CV_PROC_IA32_WITH_SSE2 :
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          id == ICV_CPUID_A6 ? CV_PROC_IA32_WITH_SSE :
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          id == ICV_CPUID_M6 ? CV_PROC_IA32_WITH_MMX :
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          CV_PROC_IA32_GENERIC;
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined EM64T
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sys.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cpu_info->model = CV_PROC_EM64T;
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif defined WIN64
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sys.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64 )
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cpu_info->model = CV_PROC_IA64;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( QueryPerformanceFrequency( &freq ) )
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cpu_info->frequency = (double)freq.QuadPart;
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->frequency = 1;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef __x86_64__
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->model = CV_PROC_EM64T;
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif defined __ia64__
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->model = CV_PROC_IA64;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif !defined __i386__
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->model = CV_PROC_GENERIC;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cpu_info->model = CV_PROC_IA32_GENERIC;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // reading /proc/cpuinfo file (proc file system must be supported)
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    FILE *file = fopen( "/proc/cpuinfo", "r" );
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( file )
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        char buffer[1024];
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int max_size = sizeof(buffer)-1;
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for(;;)
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const char* ptr = fgets( buffer, max_size, file );
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !ptr )
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( strncmp( buffer, "flags", 5 ) == 0 )
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( strstr( buffer, "mmx" ) && strstr( buffer, "cmov" ))
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cpu_info->model = CV_PROC_IA32_WITH_MMX;
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( strstr( buffer, "xmm" ) || strstr( buffer, "sse" ))
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cpu_info->model = CV_PROC_IA32_WITH_SSE;
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( strstr( buffer, "emm" ))
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cpu_info->model = CV_PROC_IA32_WITH_SSE2;
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( strncmp( buffer, "cpu MHz", 7 ) == 0 )
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                char* pos = strchr( buffer, ':' );
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( pos )
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cpu_info->frequency = strtod( pos + 1, &pos );
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        fclose( file );
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_GET_PROC_ARCH(cpu_info->model) != CV_PROC_IA32_GENERIC )
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cpu_info->frequency = 1;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( cpu_info->frequency > 1 );
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_INLINE const CvProcessorInfo*
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvGetProcessorInfo()
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvProcessorInfo cpu_info;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int init_cpu_info = 0;
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !init_cpu_info )
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvInitProcessorInfo( &cpu_info );
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        init_cpu_info = 1;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return &cpu_info;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************/
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*                               Make functions descriptions                            */
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************/
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef IPCVAPI_EX
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define IPCVAPI_EX(type,func_name,names,modules,arg) \
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    { (void**)&func_name##_p, (void*)(size_t)-1, names, modules, 0 },
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef IPCVAPI_C_EX
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define IPCVAPI_C_EX(type,func_name,names,modules,arg) \
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    { (void**)&func_name##_p, (void*)(size_t)-1, names, modules, 0 },
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvPluginFuncInfo cxcore_ipp_tab[] =
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef _CXCORE_IPP_H_
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cxipp.h"
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#undef _CXCORE_IPP_H_
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {0, 0, 0, 0, 0}
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   determine processor type, load appropriate dll and
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   initialize all function pointers
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 || defined WIN64
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_PREFIX ""
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_SUFFIX ".dll"
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_PREFIX "lib"
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_SUFFIX ".so"
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define LoadLibrary(name) dlopen(name, RTLD_LAZY)
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define FreeLibrary(name) dlclose(name)
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define GetProcAddress dlsym
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef void* HMODULE;
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if 0 /*def _DEBUG*/
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_DEBUG_FLAG "d"
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define DLL_DEBUG_FLAG ""
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define VERBOSE_LOADING 0
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if VERBOSE_LOADING
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_PRINTF(args)  printf args; fflush(stdout)
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_PRINTF(args)
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef struct CvPluginInfo
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const char* basename;
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    HMODULE handle;
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    char name[100];
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvPluginInfo;
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvPluginInfo plugins[CV_PLUGIN_MAX];
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvModuleInfo cxcore_info = { 0, "cxcore", CV_VERSION, cxcore_ipp_tab };
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvModuleInfo *CvModule::first = 0, *CvModule::last = 0;
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvModule::CvModule( CvModuleInfo* _info )
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvRegisterModule( _info );
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    info = last;
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvModule::~CvModule()
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( info )
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvModuleInfo* p = first;
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; p != 0 && p->next != info; p = p->next )
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( p )
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            p->next = info->next;
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( first == info )
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            first = info->next;
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( last == info )
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            last = p;
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &info );
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        info = 0;
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvUpdatePluginFuncTab( CvPluginFuncInfo* func_tab )
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, loaded_functions = 0;
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 1. reset pointers
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; func_tab[i].func_addr != 0; i++ )
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( func_tab[i].default_func_addr == (void*)(size_t)-1 )
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            func_tab[i].default_func_addr = *func_tab[i].func_addr;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *func_tab[i].func_addr = func_tab[i].default_func_addr;
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        func_tab[i].loaded_from = 0;
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // ippopencv substitutes all the other IPP modules
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( plugins[CV_PLUGIN_OPTCV].handle != 0 )
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 2; i < CV_PLUGIN_MKL; i++ )
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            assert( plugins[i].handle == 0 );
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            plugins[i].handle = plugins[CV_PLUGIN_OPTCV].handle;
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 2. try to find corresponding functions in ipp* and reassign pointers to them
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; func_tab[i].func_addr != 0; i++ )
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #if defined _MSC_VER && _MSC_VER >= 1200
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        #pragma warning( disable: 4054 4055 ) /* converting pointers to code<->data */
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #endif
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        char name[100];
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int j = 0, idx = 0;
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( func_tab[i].loaded_from == 0 );
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( func_tab[i].search_modules )
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* addr = 0;
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const char* name_ptr = func_tab[i].func_names;
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; j < 10 && name_ptr; j++ )
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const char* name_start = name_ptr;
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const char* name_end;
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                while( !isalpha(name_start[0]) && name_start[0] != '\0' )
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    name_start++;
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !name_start[0] )
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    name_start = 0;
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                name_end = name_start ? strchr( name_start, ',' ) : 0;
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                idx = (func_tab[i].search_modules / (1<<j*4)) % CV_PLUGIN_MAX;
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( plugins[idx].handle != 0 && name_start )
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( name_end != 0 )
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        strncpy( name, name_start, name_end - name_start );
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        name[name_end - name_start] = '\0';
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        strcpy( name, name_start );
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    addr = (uchar*)GetProcAddress( plugins[idx].handle, name );
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( addr )
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                name_ptr = name_end;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( addr )
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /*#ifdef WIN32
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                while( *addr == 0xE9 )
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    addr += 5 + *((int*)(addr + 1));
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            #endif*/
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                *func_tab[i].func_addr = addr;
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                func_tab[i].loaded_from = idx; // store index of the module
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                   // that contain the loaded function
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                loaded_functions++;
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PRINTF(("%s: \t%s\n", name, plugins[idx].name ));
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            #if defined _MSC_VER && _MSC_VER >= 1200
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                #pragma warning( default: 4054 4055 )
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            #endif
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if VERBOSE_LOADING
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int not_loaded = 0;
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ICV_PRINTF(("\nTotal loaded: %d\n\n", loaded_functions ));
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    printf( "***************************************************\nNot loaded ...\n\n" );
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; func_tab[i].func_addr != 0; i++ )
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !func_tab[i].loaded_from )
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ICV_PRINTF(( "%s\n", func_tab[i].func_names ));
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            not_loaded++;
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ICV_PRINTF(("\nTotal: %d\n", not_loaded ));
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( plugins[CV_PLUGIN_OPTCV].handle != 0 )
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 2; i < CV_PLUGIN_MKL; i++ )
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            plugins[i].handle = 0;
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return loaded_functions;
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvRegisterModule( const CvModuleInfo* module )
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvModuleInfo* module_copy = 0;
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvRegisterModule" );
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    size_t name_len, version_len;
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_ASSERT( module != 0 && module->name != 0 && module->version != 0 );
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    name_len = strlen(module->name);
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    version_len = strlen(module->version);
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_CALL( module_copy = (CvModuleInfo*)cvAlloc( sizeof(*module_copy) +
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                        name_len + 1 + version_len + 1 ));
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    *module_copy = *module;
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    module_copy->name = (char*)(module_copy + 1);
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    module_copy->version = (char*)(module_copy + 1) + name_len + 1;
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memcpy( (void*)module_copy->name, module->name, name_len + 1 );
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memcpy( (void*)module_copy->version, module->version, version_len + 1 );
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    module_copy->next = 0;
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CvModule::first == 0 )
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvModule::first = module_copy;
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvModule::last->next = module_copy;
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvModule::last = module_copy;
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CvModule::first == CvModule::last )
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( cvUseOptimized(1));
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvUpdatePluginFuncTab( module_copy->func_tab ));
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cvGetErrStatus() < 0 && module_copy )
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &module_copy );
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return module_copy ? 0 : -1;
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvUseOptimized( int load_flag )
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, loaded_modules = 0, loaded_functions = 0;
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvModuleInfo* module;
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvProcessorInfo* cpu_info = icvGetProcessorInfo();
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int arch = CV_GET_PROC_ARCH(cpu_info->model);
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // TODO: implement some more elegant way
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // to find the latest and the greatest IPP/MKL libraries
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* opencv_sfx[] = { "100", "099", "097", 0 };
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* ipp_sfx_ia32[] = { "-6.1", "-6.0", "-5.3", "-5.2", "-5.1", "", 0 };
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* ipp_sfx_ia64[] = { "64-6.1", "64-6.0", "64-5.3", "64-5.2", "64-5.1", "64", 0 };
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* ipp_sfx_em64t[] = { "em64t-6.1", "em64t-6.0", "em64t-5.3", "em64t-5.2", "em64t-5.1", "em64t", 0 };
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* mkl_sfx_ia32[] = { "p4", "p3", "def", 0 };
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* mkl_sfx_ia64[] = { "i2p", "itp", 0 };
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const char* mkl_sfx_em64t[] = { "def", 0 };
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const char** ipp_suffix = arch == CV_PROC_IA64 ? ipp_sfx_ia64 :
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              arch == CV_PROC_EM64T ? ipp_sfx_em64t : ipp_sfx_ia32;
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const char** mkl_suffix = arch == CV_PROC_IA64 ? mkl_sfx_ia64 :
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                              arch == CV_PROC_EM64T ? mkl_sfx_em64t : mkl_sfx_ia32;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < CV_PLUGIN_MAX; i++ )
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        plugins[i].basename = 0;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_NONE].basename = 0;
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_NONE].name[0] = '\0';
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_OPTCV].basename = "ippopencv";
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_IPPCV].basename = "ippcv";
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_IPPI].basename = "ippi";
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_IPPS].basename = "ipps";
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_IPPVM].basename = "ippvm";
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_IPPCC].basename = "ippcc";
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    plugins[CV_PLUGIN_MKL].basename = "mkl_";
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // try to load optimized dlls
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 1; i < CV_PLUGIN_MAX; i++ )
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // unload previously loaded optimized modules
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( plugins[i].handle )
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            FreeLibrary( plugins[i].handle );
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            plugins[i].handle = 0;
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // do not load regular IPP modules if the custom merged IPP module is already found.
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( i < CV_PLUGIN_MKL && load_flag && plugins[CV_PLUGIN_OPTCV].handle != 0 )
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            continue;
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( load_flag && plugins[i].basename &&
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (arch == CV_PROC_IA32_GENERIC || arch == CV_PROC_IA64 || arch == CV_PROC_EM64T) )
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            const char** suffix = i == CV_PLUGIN_OPTCV ? opencv_sfx :
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            i < CV_PLUGIN_MKL ? ipp_suffix : mkl_suffix;
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( suffix == mkl_sfx_ia32 )
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(cpu_info->model & CV_PROC_IA32_WITH_SSE2) )
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    suffix++;
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(cpu_info->model & CV_PROC_IA32_WITH_SSE) )
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    suffix++;
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; *suffix != 0; suffix++ )
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sprintf( plugins[i].name, DLL_PREFIX "%s%s" DLL_DEBUG_FLAG DLL_SUFFIX,
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    plugins[i].basename, *suffix );
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PRINTF(("loading %s...\n", plugins[i].name ));
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                plugins[i].handle = LoadLibrary( plugins[i].name );
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( plugins[i].handle != 0 )
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ICV_PRINTF(("%s loaded\n", plugins[i].name ));
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    loaded_modules++;
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                #ifndef WIN32
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // temporary workaround for MacOSX
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sprintf( plugins[i].name, DLL_PREFIX "%s%s" DLL_DEBUG_FLAG ".dylib",
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    plugins[i].basename, *suffix );
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ICV_PRINTF(("loading %s...\n", plugins[i].name ));
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                plugins[i].handle = LoadLibrary( plugins[i].name );
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( plugins[i].handle != 0 )
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ICV_PRINTF(("%s loaded\n", plugins[i].name ));
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    loaded_modules++;
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                #endif
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( module = CvModule::first; module != 0; module = module->next )
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        loaded_functions += icvUpdatePluginFuncTab( module->func_tab );
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return loaded_functions;
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvModule cxcore_module( &cxcore_info );
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetModuleInfo( const char* name, const char **version, const char **plugin_list )
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static char joint_verinfo[1024] = "";
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static char plugin_list_buf[1024] = "";
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvGetLibraryInfo" );
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( version )
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *version = 0;
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( plugin_list )
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        *plugin_list = 0;
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvModuleInfo* module;
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( version )
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( name )
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            size_t i, name_len = strlen(name);
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( module = CvModule::first; module != 0; module = module->next )
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( strlen(module->name) == name_len )
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < name_len; i++ )
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        int c0 = toupper(module->name[i]), c1 = toupper(name[i]);
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( c0 != c1 )
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            break;
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( i == name_len )
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !module )
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsObjectNotFound, "The module is not found" );
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *version = module->version;
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            char* ptr = joint_verinfo;
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( module = CvModule::first; module != 0; module = module->next )
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sprintf( ptr, "%s: %s%s", module->name, module->version, module->next ? ", " : "" );
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += strlen(ptr);
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *version = joint_verinfo;
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( plugin_list )
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        char* ptr = plugin_list_buf;
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i;
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < CV_PLUGIN_MAX; i++ )
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( plugins[i].handle != 0 )
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sprintf( ptr, "%s, ", plugins[i].name );
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += strlen(ptr);
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ptr > plugin_list_buf )
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr[-2] = '\0';
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *plugin_list = plugin_list_buf;
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            *plugin_list = "";
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef int64 (CV_CDECL * rdtsc_func)(void);
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* helper functions for RNG initialization and accurate time measurement */
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL  int64  cvGetTickCount( void )
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const CvProcessorInfo* cpu_info = icvGetProcessorInfo();
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( cpu_info->frequency > 1 &&
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_GET_PROC_ARCH(cpu_info->model) == CV_PROC_IA32_GENERIC )
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef MASM_INLINE_ASSEMBLY
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #ifdef __BORLANDC__
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __asm db 0fh
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __asm db 31h
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #else
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __asm _emit 0x0f;
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        __asm _emit 0x31;
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    #endif
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#elif (defined __GNUC__ || defined CV_ICC) && defined __i386__
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int64 t;
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        asm volatile (".byte 0xf; .byte 0x31" /* "rdtsc" */ : "=A" (t));
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return t;
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        static const char code[] = "\x0f\x31\xc3";
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        rdtsc_func func = (rdtsc_func)(void*)code;
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return func();
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN32 || defined WIN64
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        LARGE_INTEGER counter;
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        QueryPerformanceCounter( &counter );
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return (int64)counter.QuadPart;
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        struct timeval tv;
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        struct timezone tz;
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        gettimeofday( &tv, &tz );
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return (int64)tv.tv_sec*1000000 + tv.tv_usec;
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL  double  cvGetTickFrequency()
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return icvGetProcessorInfo()->frequency;
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int icvNumThreads = 0;
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int icvNumProcs = 0;
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int cvGetNumThreads(void)
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !icvNumProcs )
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvSetNumThreads(0);
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return icvNumThreads;
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void cvSetNumThreads( int threads )
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !icvNumProcs )
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _OPENMP
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvNumProcs = omp_get_num_procs();
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvNumProcs = MIN( icvNumProcs, CV_MAX_THREADS );
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvNumProcs = 1;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _OPENMP
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( threads <= 0 )
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        threads = icvNumProcs;
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //else
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    //    threads = MIN( threads, icvNumProcs );
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvNumThreads = threads;
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvNumThreads = 1;
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int cvGetThreadNum(void)
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#ifdef _OPENMP
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return omp_get_thread_num();
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#else
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return 0;
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
817