Move the sources to trunk
[opencv] / utils / cvinfo / cvinfo.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
22 //   * Redistribution's in binary form must reproduce the above copyright notice,
23 //     this list of conditions and the following disclaimer in the documentation
24 //     and/or other materials provided with the distribution.
25 //
26 //   * The name of Intel Corporation may not be used to endorse or promote products
27 //     derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <windows.h>
46 #include <io.h>
47 #include <ctype.h>
48 #include <assert.h>
49 #include <time.h>
50
51 #define PROC_PX     0
52 #define PROC_M5     (1<<23) /* mmx */
53 #define PROC_M6     ((1<<15)|(1<<23)) /* cmov + mmx */
54 #define PROC_A6     ((1<<25)|PROC_M6) /* --||-- + xmm */
55 #define PROC_W7     ((1<<26)|PROC_A6) /* --||-- + emm */
56 #define PROC_M7     -1
57
58 #if _MSC_VER >= 1300
59 #pragma warning( disable: 4996 )
60 #endif
61
62 /*
63    determine processor type
64 */
65 static int
66 get_processor_type( void )
67 {
68     int proc_type;
69
70 #ifdef WIN64
71     proc_type = PROC_M7;
72 #else
73     proc_type = PROC_PX;
74     SYSTEM_INFO sys;
75     GetSystemInfo( &sys );
76
77     if( sys.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL &&
78         sys.dwProcessorType == PROCESSOR_INTEL_PENTIUM )
79     {
80         int version = 0, features = 0, family = 0;
81
82     #if _MSC_VER >= 1200 || defined __ICL || defined __BORLANDC__
83
84         __asm
85         {
86             push ebx
87             push esi
88             push edi
89             mov  eax, 1
90
91     #ifndef __BORLANDC__
92             _emit 0x0f
93             _emit 0xa2
94     #else
95             db 0fh
96             db 0a2h
97     #endif
98             pop edi
99             pop esi
100             pop ebx
101             mov version, eax
102             mov features, edx
103         }
104
105     #elif defined __GNUC__
106
107         __asm__ __volatile__
108         (
109             "push %%ebx\n\t"    
110             "push %%esi\n\t"
111             "push %%edi\n\t"
112             "movl $1, %%eax\n\t"
113             "cpuid\n\t"
114             "movl %%eax, %0\n\t"
115             "movl %%edx, %1\n\t"
116             "pop %%edi\n\t"
117             "pop %%esi\n\t"
118             "pop %%ebx\n\t"
119             : "=a" (version),
120               "=d" (features)
121             :
122         );
123
124     #endif
125
126         family = (version >> 8) & 15;
127         if( family >= 5 && (features & PROC_M6) != 0 ) /* Pentium II or higher */
128         {
129             proc_type = features & PROC_W7;
130         }
131     }
132 #endif
133
134     return proc_type;
135 }
136
137
138 static const char*
139 get_flavor( const char* name )
140 {
141     const char* ptr = strrchr( name, '.' );
142     char buffer[3];
143     assert( ptr != 0 );
144
145     strncpy( buffer, ptr - 2, 2 );
146     buffer[0] = (char)toupper(buffer[0]);
147     buffer[1] = (char)toupper(buffer[1]);
148     buffer[2] = '\0';
149
150     if( !strcmp( buffer, "PL" ))
151         return "Switcher";
152     if( !strcmp( buffer, "W7" ))
153         return "PIV-optimized";
154     else if( !strcmp( buffer, "A6" ))
155         return "PIII-optimized";
156     else if( !strcmp( buffer, "M6" ))
157         return "PII-optimized";
158     else if( !strcmp( buffer, "M5" ))
159         return "Pentium MMX-optimized";
160     else if( !strcmp( buffer, "P6" ))
161         return "Pentium Pro-optimized";
162     else if( !strcmp( buffer, "P5" ))
163         return "Pentium-optimized";
164     else if( !strcmp( buffer, "PX" ))
165         return "Generic IA32";
166     else if( !strcmp( buffer, "IX" ))
167         return "Generic IA64";
168     else if( !strcmp( buffer, "I7" ))
169         return "Itanium-optimized";
170     else 
171         return "UNKNOWN";
172 }
173
174 static const char*
175 tryLoadOpenCV( const char* name )
176 {
177     const char* version = 0;
178     HINSTANCE dll = LoadLibrary( name );
179
180     if( dll )
181     {
182         if( GetProcAddress( dll, "cvAccMask" ) != 0 ) // alpha 3 had cvAccMask function
183             version = "alpha 3.x";
184         else if( GetProcAddress( dll, "cvmAdd" ) != 0 ) // till beta 2.x OpenCV had separate cvm* functions
185             version = "beta 1.5 (a.k.a. 0.0.7)";
186         else if( GetProcAddress( dll, "cvHoughLinesP" ) != 0 )
187             version = "beta 2.x (a.k.a. 0.9.3)"; // beta 2 had separate functions for different variations of Hough transform
188         else if( GetProcAddress( dll, "cvEigenProjection" ) != 0 )
189             version = "beta 3 (a.k.a 0.9.4) or beta 3.1 (a.k.a 0.9.5)"; // beta 3.x had cvEigenProjection and related functions
190         else if( GetProcAddress( dll, "cvHoughCircles" ) == 0 )
191             version = "beta 4.x (a.k.a. 0.9.5 or 0.9.6)";
192         else if( GetProcAddress( dll, "cvWatershed" ) == 0 )
193             version = "beta 5.x (a.k.a. 0.9.7)";
194         else if( GetProcAddress( dll, "cvInpaint" ) == 0 )
195             version = "1.0rc1 (a.k.a. 0.9.9)";
196         else
197             version = "1.0 or later";
198             
199         FreeLibrary( dll );
200     }
201
202     return version;
203 }
204
205 typedef struct _IPLLibVersion
206 {
207     int major; /*e.g. 2 */
208     int minor; /*e.g. 0 */
209     int build; /*e.g. 1 */
210     const char* Name; /*"ipl6l.lib","iplm5.dll"*/
211     const char* Version; /*e.g."v2.00" */
212     const char* InternalVersion; /*e.g. "[2.00.01.023,01/01/99]" */
213     const char* BuildDate;/*e.g. "Jan199"*/
214     const char* CallConv;
215 }
216 IPLLibVersion;
217
218 typedef const IPLLibVersion* (__stdcall* IplGetLibVersion)(void);
219
220 static char*
221 load_file( const char* name, int* _size )
222 {
223     FILE* f = fopen( name, "rb" );
224     int size = 0;
225     char* buffer = 0;
226
227     if( f )
228     {
229         fseek( f, 0, SEEK_END );
230         size = ftell( f );
231         fseek( f, 0, SEEK_SET );
232
233         buffer = (char*)malloc( size );
234         if( fread( buffer, 1, size, f ) != (unsigned)size )
235         {
236             free( buffer );
237             buffer = 0;
238             size = 0;
239         }
240         fclose( f );
241     }
242
243     if( _size )
244         *_size = size;
245
246     return buffer;
247 }
248
249
250 static int
251 find_signature( char* buffer, int size, const char* signature )
252 {
253     char* ptr = buffer;
254     int sig_length = (int)strlen(signature);
255     
256     while( ptr < buffer + size )
257     {
258         ptr = (char*)memchr( ptr, signature[0], buffer + size - ptr );
259         if( !ptr || buffer + size - ptr < sig_length )
260         {
261             ptr = 0;
262             break;
263         }
264         
265         if( !memcmp( ptr, signature, sig_length )) // found!
266             break;
267         ptr++;
268     }
269
270     return ptr != 0;
271 }
272
273
274 // convert date from string "/mm/dd/yyyy" or "mm/dd/yy" to time_t.
275 static time_t date( const char* str )
276 {
277     tm t;
278     int month, day, year;
279     
280     if( sscanf( str, "%d/%d/%d", &month, &day, &year ) != 3 )
281         return 0;
282
283     memset( &t, 0, sizeof(t));
284
285     t.tm_mday = day;
286     t.tm_mon = month - 1;
287     t.tm_year = year - (year > 100 ? 1900 : 0);
288
289     return mktime( &t );
290 }
291
292
293 static const char*
294 tryLoadIPL( const char* name )
295 {
296     //time_t  ipl_2_1_date = date("01/01/2000");
297     //time_t  ipl_2_2_date = date("01/20/2000");
298     //time_t  ipl_2_5_date = date("10/09/2000");
299
300     HINSTANCE dll;
301     const char* version = 0;
302     const char* dotptr = strrchr( name, '.' );
303     assert( dotptr != 0 );
304     if( dotptr[-1] == 'l' || dotptr[-1] == 'L' ) // switcher
305     {
306         int size = 0;
307         char* buffer = load_file( name, &size );
308
309         if( find_signature( buffer, size, "IPLW7.DLL" ))
310             version = "2.5 or later";
311         else if( find_signature( buffer, size, "iplNoiseImage" ))
312             version = "2.2";
313         else
314             version = "2.1 or earlier";
315
316         free( buffer );
317         return version;
318     }
319     else
320     {
321         dll = LoadLibrary( name );
322
323         if( dll ) // if it is not just a switcher, we can use iplGetLibVersion
324         {
325             IplGetLibVersion getLibVersion =
326                 (IplGetLibVersion)GetProcAddress(dll, "iplGetLibVersion");
327
328             if( getLibVersion )
329                 version = getLibVersion()->InternalVersion;
330             else
331                 version = "[ERROR - iplGetLibVersion could not be found]";
332         }
333         else
334             version = "[ERROR - dll could not be loaded]";
335     }
336
337     return version;
338 }
339
340
341 static const char*
342 tryLoadIppCV( const char* /*name*/, _finddata_t* finddata )
343 {
344     //
345     // IppCV and OptCV: functionality is approximately the same,
346     // so the function checks modification time of the DLL to determine its version.
347     //
348     time_t  ippcv_alpha_3_4 = date("01/01/2001");
349     time_t  ippcv_beta_1_5 = date("06/01/2000");
350     time_t  ippcv_beta_2 = date("01/10/2000");
351
352     if( finddata->time_write < ippcv_alpha_3_4 )
353         return "alpha 3.4";
354     else if( finddata->time_write < ippcv_beta_1_5 )
355         return "beta 1.5";
356     else if( finddata->time_write < ippcv_beta_2 )
357         return "beta 2";
358     else
359         return "beta 2+";
360 }
361
362
363 void scan_folder( char* folder, int length )
364 {
365     const char* cv_names[] = { "cv", "cv096", "cv097", "cv099", "cv100", 0 };
366
367     _finddata_t finddata;
368 #ifdef WIN64
369     intptr_t
370 #else
371     int
372 #endif
373         search_id;
374     int i;
375     const char* version = 0;
376     
377     if( folder[length - 1] != '/' && folder[length - 1] != '\\' )
378
379     {
380         folder[length] = '\\';
381         folder[++length] = '0';
382     }
383
384     for( i = 0; cv_names[i] != 0; i++ )
385     {
386         // find OpenCV
387         sprintf( folder + length, "%s.dll", cv_names[i] );
388         version = tryLoadOpenCV( folder );
389     
390         if( version != 0 )
391         {
392             printf("%s:\n\t OpenCV version %s\n", folder, version );
393         }
394
395         sprintf( folder + length, "%sd.dll", cv_names[i] );
396         version = tryLoadOpenCV( folder );
397     
398         if( version != 0 )
399         {
400             printf("%s:\n\t OpenCV (Debug) version %s\n", folder, version );
401         }
402     }
403
404     // find IPL
405     strcpy( folder + length, "ipl*.dll" );
406     search_id = _findfirst( folder, &finddata );
407
408     if( search_id >= 0 )
409     {
410         do
411         {
412             strcpy( folder + length, finddata.name );
413             version = tryLoadIPL( folder );
414
415             if( version != 0 )
416             {
417                 printf("%s:\n\t IPL %s version %s\n", folder, get_flavor( folder ),
418                         version );
419             }
420         }
421         while( _findnext( search_id, &finddata ) >= 0 );
422     }
423
424     // find IppCV
425     strcpy( folder + length, "ippcv*.dll" );
426     search_id = _findfirst( folder, &finddata );
427
428     if( search_id >= 0 )
429     {
430         do
431         {
432             strcpy( folder + length, finddata.name );
433             version = tryLoadIppCV( folder, &finddata );
434
435             if( version != 0 )
436             {
437                 printf("%s:\n\t IppCV %s version %s\n", folder, get_flavor( folder ),
438                         version );
439             }
440         }
441         while( _findnext( search_id, &finddata ) >= 0 );
442     }
443
444     // find OptCV
445     strcpy( folder + length, "optcv*.dll" );
446     search_id = _findfirst( folder, &finddata );
447
448     if( search_id >= 0 )
449     {
450         do
451         {
452             strcpy( folder + length, finddata.name );
453             version = tryLoadIppCV( folder, &finddata );
454
455             if( version != 0 )
456             {
457                 printf("%s:\n\t IppCV %s version %s\n", folder, get_flavor( folder ),
458                         version );
459             }
460         }
461         while( _findnext( search_id, &finddata ) >= 0 );
462     }
463 }
464
465 int main( void )
466 {
467     char* path = getenv( "PATH" );
468     char* folder_start = path;
469     char  folder[1024];
470     int   proc_type = get_processor_type();
471
472     printf("Processor: %s or compatible\n", proc_type == PROC_M7 ? "EM64T-compatible" :
473                                             proc_type == PROC_W7 ? "Pentium IV" :
474                                             proc_type == PROC_A6 ? "Pentium III" :
475                                             proc_type == PROC_M6 ? "Pentium II" :
476                                             "Generic IA32 processor"  );
477
478     for( ; *path != '\0'; path++ )
479     {
480         if( *path == ';' )
481         {
482             int length = (int)(path - folder_start);
483             strncpy( folder, folder_start, length );
484             folder[length] = '\0';
485             //printf( "%s\n", buffer );
486             scan_folder( folder, length );
487             folder_start = path + 1;
488         }
489     }
490    
491     return 0;
492 }
493
494 /* End of file. */