From 4bc273824d654a7462638a2b8d305d05b53f873a Mon Sep 17 00:00:00 2001 From: Vahagn Khachatryan Date: Thu, 6 Dec 2012 21:43:03 +0400 Subject: [PATCH] initial check in --- .gitignore | 5 + Duffs_device.cpp | 47 + OpenMPForVC2k5/omp.h | 204 +++ SSE2_transform.cpp | 1562 ++++++++++++++++ SSE2_transform.h | 1119 ++++++++++++ SSE_cmplr_abstraction.h | 280 +++ SSE_cmplr_abstraction_GCC.h | 60 + SSE_cmplr_abstraction_MSC.h | 61 + SSE_cmplr_abstraction_MSC_backup.h | 895 +++++++++ SSE_cmplr_abstraction_MSC_pckdbl.h | 624 +++++++ SSE_cmplr_abstraction_MSC_pckfloat.h | 667 +++++++ SSE_cmplr_abstraction_MSC_pckint16.h | 618 +++++++ SSE_cmplr_abstraction_MSC_pckint32.h | 676 +++++++ SSE_cmplr_abstraction_MSC_pckint64.h | 618 +++++++ SSE_cmplr_abstraction_MSC_pckint8.h | 618 +++++++ SSE_cmplr_abstraction_other.h | 60 + SSE_transform.cpp | 43 + any_const_hides_copy_const.cpp | 35 + boost_variant_test.cpp | 23 + call_constructor.cpp | 34 + constStrType.cpp | 20 + dlload.cpp | 19 + dyn_cast.cpp | 46 + external_guard/external_guard.cpp | 18 + external_guard/external_guard_time10.h | 42 + external_guard/external_guard_time100.h | 13 + external_guard/external_guard_time1000.h | 11 + external_guard/external_guard_time10000.h | 11 + external_guard/external_guard_time100000.h | 11 + getcurrenttime.h | 329 ++++ getcurrenttime2.h | 287 +++ libgd_test/libgd_test.sln | 20 + libgd_test/libgd_test.vcproj | 200 +++ long_long_size.cpp | 10 + mergeTwoFiles/mergeTwoFiles.cpp | 40 + mergeTwoFiles/mergeTwoFiles.sln | 20 + mergeTwoFiles/mergeTwoFiles.vcproj | 225 +++ mergeTwoFiles/stdafx.cpp | 8 + mergeTwoFiles/stdafx.h | 17 + openMP_simple_test.cpp | 66 + pnginfo/pnginfo.cpp | 213 +++ pnginfo/pnginfo.vcxproj | 155 ++ pnginfo/pnginfo.vcxproj.filters | 22 + shift_size.cpp | 17 + sln/SEE_test/SEE_test.sln | 20 + sln/SEE_test/SEE_test.vcproj | 263 +++ .../WindowsApplication1.sln | 20 + .../any_const_hides_copy_const.sln | 20 + .../any_const_hides_copy_const.vcproj | 197 ++ sln/boost_variant_test/boost_variant_test.sln | 20 + .../boost_variant_test.vcproj | 199 ++ sln/openMpSimpleTest/openMpSimpleTest.sln | 23 + sln/openMpSimpleTest/openMpSimpleTest.vcproj | 290 +++ .../GeneratedFiles/Debug/moc_qstringdebug.cpp | 60 + .../GeneratedFiles/ui_qstringdebug.h | 66 + sln/qstringDebug/main.cpp | 11 + sln/qstringDebug/qstringDebug.sln | 26 + sln/qstringDebug/qstringDebug.vcproj | 343 ++++ sln/qstringDebug/qstringdebug.cpp | 14 + sln/qstringDebug/qstringdebug.h | 19 + sln/std_vs_qt/std_vs_qt.sln | 26 + sln/std_vs_qt/std_vs_qt.vcproj | 217 +++ sln/toIntTest.sln | 20 + sln/toIntTest.vcproj | 205 +++ sln/virtual_method_ptr/virtual_method_ptr.sln | 20 + .../virtual_method_ptr.vcproj | 197 ++ static_cast_vs_dynamik.cpp | 35 + std_vs_qt.cpp | 725 ++++++++ stdafx.cpp | 8 + stdafx.h | 17 + stl_vector_resize.cpp | 47 + tbb_test/main.cpp | 132 ++ tbb_test/tbb_test.sln | 26 + tbb_test/tbb_test.vcxproj | 155 ++ tbb_test/tbb_test.vcxproj.filters | 22 + temporary_objects.cpp | 41 + test.cpp | 45 + test.sln | 20 + test.vcproj | 225 +++ testConstructorCall/stdafx.cpp | 8 + testConstructorCall/stdafx.h | 17 + testConstructorCall/testConstructorCall.cpp | 52 + testConstructorCall/testConstructorCall.sln | 20 + .../testConstructorCall.vcproj | 225 +++ testDeviceIOWin32/stdafx.cpp | 8 + testDeviceIOWin32/stdafx.h | 23 + testDeviceIOWin32/testDeviceIOWin32.cpp | 699 ++++++++ testDeviceIOWin32/testDeviceIOWin32.sln | 20 + testDeviceIOWin32/testDeviceIOWin32.vcproj | 225 +++ testLong64.cpp | 19 + testMultipleDerviation/stdafx.cpp | 8 + testMultipleDerviation/stdafx.h | 19 + .../testMultipleDerviation.cpp | 124 ++ .../testMultipleDerviation.sln | 20 + .../testMultipleDerviation.vcproj | 225 +++ testOutputIterator/stdafx.cpp | 8 + testOutputIterator/stdafx.h | 17 + testOutputIterator/testOutputIterator.cpp | 37 + testOutputIterator/testOutputIterator.sln | 20 + testOutputIterator/testOutputIterator.vcproj | 225 +++ testProtectedVirtInheritence/stdafx.cpp | 8 + testProtectedVirtInheritence/stdafx.h | 17 + .../testProtectedVirtInheritence.cpp | 59 + .../testProtectedVirtInheritence.sln | 20 + .../testProtectedVirtInheritence.vcproj | 225 +++ testStaticCast.cpp | 132 ++ testTemplate/testTemplate.sln | 20 + testTemplate/testTemplate/stdafx.cpp | 8 + testTemplate/testTemplate/stdafx.h | 17 + testTemplate/testTemplate/testTemplate.cpp | 46 + testTemplate/testTemplate/testTemplate.vcproj | 225 +++ testTransform/_transform.cpp | 1582 ++++++++++++++++ testTransform/_transform.h | 1408 +++++++++++++++ testTransform/main.cpp | 570 ++++++ testTransform/sseprim.h | 198 ++ testTransform/ssetypes.h | 48 + testTransform/testTransform.sln | 20 + testTransform/testTransform.vcproj | 362 ++++ testTransform/transform.cpp | 1593 +++++++++++++++++ testTransform/transform.h | 1493 +++++++++++++++ testTransform/transform2.cpp | 845 +++++++++ testTransform/transform2.h | 912 ++++++++++ testVC_ENV_CL/stdafx.cpp | 8 + testVC_ENV_CL/stdafx.h | 17 + testVC_ENV_CL/testVC_ENV_CL.cpp | 16 + testVC_ENV_CL/testVC_ENV_CL.sln | 20 + testVC_ENV_CL/testVC_ENV_CL.vcproj | 225 +++ testX11.cpp | 215 +++ test_array_init.cpp | 26 + test_autoname_obj.cpp | 59 + test_const_arg.cpp | 52 + test_copy_elision.cpp | 77 + test_expression.cpp | 10 + test_lib/stdafx.cpp | 8 + test_lib/stdafx.h | 17 + test_lib/test_lib.cpp | 11 + test_lib/test_lib.sln | 38 + test_lib/test_lib.vcproj | 225 +++ test_lib/test_lib/stdafx.cpp | 8 + test_lib/test_lib/stdafx.h | 17 + test_lib/test_lib/test_lib.cpp | 11 + test_lib/test_lib/test_lib.sln | 38 + test_lib/test_lib/test_lib.vcproj | 225 +++ test_lib/test_lib_dyn/stdafx.cpp | 8 + test_lib/test_lib_dyn/stdafx.h | 32 + test_lib/test_lib_dyn/test_lib_dyn.cpp | 54 + test_lib/test_lib_dyn/test_lib_dyn.h | 22 + test_lib/test_lib_dyn/test_lib_dyn.vcproj | 235 +++ test_lib/test_lib_static/method1.cpp | 9 + test_lib/test_lib_static/method2.cpp | 13 + test_lib/test_lib_static/method3.cpp | 8 + test_lib/test_lib_static/obj1.cpp | 10 + test_lib/test_lib_static/obj2.cpp | 13 + test_lib/test_lib_static/obj3.cpp | 8 + .../test_lib_static/test_lib_static.vcproj | 197 ++ test_lib/test_lib_static/test_static.h | 25 + test_locale/testLocale.sln | 20 + test_locale/testLocale/testLocale.cpp | 18 + test_locale/testLocale/testLocale.vcproj | 197 ++ test_public_parent/test_public_parent.sln | 20 + .../test_public_parent/stdafx.cpp | 8 + .../test_public_parent/stdafx.h | 17 + .../test_public_parent/test_public_parent.cpp | 44 + .../test_public_parent.vcproj | 225 +++ test_rvalue_ref.cpp | 68 + test_static_double.cpp | 18 + test_static_double.h | 19 + test_static_double2.cpp | 15 + test_wfstream/test_wfstream.cpp | 20 + test_wfstream/test_wfstream.sln | 20 + test_wfstream/test_wfstream.vcproj | 197 ++ toIntTest.cpp | 552 ++++++ typedefed_operators.cpp | 29 + util/unfreeze.cpp | 49 + vector_bool_itor.cpp | 12 + virtual_inheritence.cpp | 48 + virtual_method_ptr.cpp | 81 + virtual_overriding.cpp | 42 + virtual_typo.cpp | 69 + 179 files changed, 29415 insertions(+) create mode 100644 .gitignore create mode 100644 Duffs_device.cpp create mode 100644 OpenMPForVC2k5/omp.h create mode 100644 SSE2_transform.cpp create mode 100644 SSE2_transform.h create mode 100644 SSE_cmplr_abstraction.h create mode 100644 SSE_cmplr_abstraction_GCC.h create mode 100644 SSE_cmplr_abstraction_MSC.h create mode 100644 SSE_cmplr_abstraction_MSC_backup.h create mode 100644 SSE_cmplr_abstraction_MSC_pckdbl.h create mode 100644 SSE_cmplr_abstraction_MSC_pckfloat.h create mode 100644 SSE_cmplr_abstraction_MSC_pckint16.h create mode 100644 SSE_cmplr_abstraction_MSC_pckint32.h create mode 100644 SSE_cmplr_abstraction_MSC_pckint64.h create mode 100644 SSE_cmplr_abstraction_MSC_pckint8.h create mode 100644 SSE_cmplr_abstraction_other.h create mode 100644 SSE_transform.cpp create mode 100644 any_const_hides_copy_const.cpp create mode 100644 boost_variant_test.cpp create mode 100644 call_constructor.cpp create mode 100644 constStrType.cpp create mode 100644 dlload.cpp create mode 100644 dyn_cast.cpp create mode 100644 external_guard/external_guard.cpp create mode 100644 external_guard/external_guard_time10.h create mode 100644 external_guard/external_guard_time100.h create mode 100644 external_guard/external_guard_time1000.h create mode 100644 external_guard/external_guard_time10000.h create mode 100644 external_guard/external_guard_time100000.h create mode 100644 getcurrenttime.h create mode 100644 getcurrenttime2.h create mode 100644 libgd_test/libgd_test.sln create mode 100644 libgd_test/libgd_test.vcproj create mode 100644 long_long_size.cpp create mode 100644 mergeTwoFiles/mergeTwoFiles.cpp create mode 100644 mergeTwoFiles/mergeTwoFiles.sln create mode 100644 mergeTwoFiles/mergeTwoFiles.vcproj create mode 100644 mergeTwoFiles/stdafx.cpp create mode 100644 mergeTwoFiles/stdafx.h create mode 100644 openMP_simple_test.cpp create mode 100644 pnginfo/pnginfo.cpp create mode 100644 pnginfo/pnginfo.vcxproj create mode 100644 pnginfo/pnginfo.vcxproj.filters create mode 100644 shift_size.cpp create mode 100644 sln/SEE_test/SEE_test.sln create mode 100644 sln/SEE_test/SEE_test.vcproj create mode 100644 sln/WindowsApplication1/WindowsApplication1.sln create mode 100644 sln/any_const_hides_copy_const/any_const_hides_copy_const.sln create mode 100644 sln/any_const_hides_copy_const/any_const_hides_copy_const/any_const_hides_copy_const.vcproj create mode 100644 sln/boost_variant_test/boost_variant_test.sln create mode 100644 sln/boost_variant_test/boost_variant_test.vcproj create mode 100644 sln/openMpSimpleTest/openMpSimpleTest.sln create mode 100644 sln/openMpSimpleTest/openMpSimpleTest.vcproj create mode 100644 sln/qstringDebug/GeneratedFiles/Debug/moc_qstringdebug.cpp create mode 100644 sln/qstringDebug/GeneratedFiles/ui_qstringdebug.h create mode 100644 sln/qstringDebug/main.cpp create mode 100644 sln/qstringDebug/qstringDebug.sln create mode 100644 sln/qstringDebug/qstringDebug.vcproj create mode 100644 sln/qstringDebug/qstringdebug.cpp create mode 100644 sln/qstringDebug/qstringdebug.h create mode 100644 sln/std_vs_qt/std_vs_qt.sln create mode 100644 sln/std_vs_qt/std_vs_qt.vcproj create mode 100644 sln/toIntTest.sln create mode 100644 sln/toIntTest.vcproj create mode 100644 sln/virtual_method_ptr/virtual_method_ptr.sln create mode 100644 sln/virtual_method_ptr/virtual_method_ptr.vcproj create mode 100644 static_cast_vs_dynamik.cpp create mode 100644 std_vs_qt.cpp create mode 100644 stdafx.cpp create mode 100644 stdafx.h create mode 100644 stl_vector_resize.cpp create mode 100644 tbb_test/main.cpp create mode 100644 tbb_test/tbb_test.sln create mode 100644 tbb_test/tbb_test.vcxproj create mode 100644 tbb_test/tbb_test.vcxproj.filters create mode 100644 temporary_objects.cpp create mode 100644 test.cpp create mode 100644 test.sln create mode 100644 test.vcproj create mode 100644 testConstructorCall/stdafx.cpp create mode 100644 testConstructorCall/stdafx.h create mode 100644 testConstructorCall/testConstructorCall.cpp create mode 100644 testConstructorCall/testConstructorCall.sln create mode 100644 testConstructorCall/testConstructorCall.vcproj create mode 100644 testDeviceIOWin32/stdafx.cpp create mode 100644 testDeviceIOWin32/stdafx.h create mode 100644 testDeviceIOWin32/testDeviceIOWin32.cpp create mode 100644 testDeviceIOWin32/testDeviceIOWin32.sln create mode 100644 testDeviceIOWin32/testDeviceIOWin32.vcproj create mode 100644 testLong64.cpp create mode 100644 testMultipleDerviation/stdafx.cpp create mode 100644 testMultipleDerviation/stdafx.h create mode 100644 testMultipleDerviation/testMultipleDerviation.cpp create mode 100644 testMultipleDerviation/testMultipleDerviation.sln create mode 100644 testMultipleDerviation/testMultipleDerviation.vcproj create mode 100644 testOutputIterator/stdafx.cpp create mode 100644 testOutputIterator/stdafx.h create mode 100644 testOutputIterator/testOutputIterator.cpp create mode 100644 testOutputIterator/testOutputIterator.sln create mode 100644 testOutputIterator/testOutputIterator.vcproj create mode 100644 testProtectedVirtInheritence/stdafx.cpp create mode 100644 testProtectedVirtInheritence/stdafx.h create mode 100644 testProtectedVirtInheritence/testProtectedVirtInheritence.cpp create mode 100644 testProtectedVirtInheritence/testProtectedVirtInheritence.sln create mode 100644 testProtectedVirtInheritence/testProtectedVirtInheritence.vcproj create mode 100644 testStaticCast.cpp create mode 100644 testTemplate/testTemplate.sln create mode 100644 testTemplate/testTemplate/stdafx.cpp create mode 100644 testTemplate/testTemplate/stdafx.h create mode 100644 testTemplate/testTemplate/testTemplate.cpp create mode 100644 testTemplate/testTemplate/testTemplate.vcproj create mode 100644 testTransform/_transform.cpp create mode 100644 testTransform/_transform.h create mode 100644 testTransform/main.cpp create mode 100644 testTransform/sseprim.h create mode 100644 testTransform/ssetypes.h create mode 100644 testTransform/testTransform.sln create mode 100644 testTransform/testTransform.vcproj create mode 100644 testTransform/transform.cpp create mode 100644 testTransform/transform.h create mode 100644 testTransform/transform2.cpp create mode 100644 testTransform/transform2.h create mode 100644 testVC_ENV_CL/stdafx.cpp create mode 100644 testVC_ENV_CL/stdafx.h create mode 100644 testVC_ENV_CL/testVC_ENV_CL.cpp create mode 100644 testVC_ENV_CL/testVC_ENV_CL.sln create mode 100644 testVC_ENV_CL/testVC_ENV_CL.vcproj create mode 100644 testX11.cpp create mode 100644 test_array_init.cpp create mode 100644 test_autoname_obj.cpp create mode 100644 test_const_arg.cpp create mode 100644 test_copy_elision.cpp create mode 100644 test_expression.cpp create mode 100644 test_lib/stdafx.cpp create mode 100644 test_lib/stdafx.h create mode 100644 test_lib/test_lib.cpp create mode 100644 test_lib/test_lib.sln create mode 100644 test_lib/test_lib.vcproj create mode 100644 test_lib/test_lib/stdafx.cpp create mode 100644 test_lib/test_lib/stdafx.h create mode 100644 test_lib/test_lib/test_lib.cpp create mode 100644 test_lib/test_lib/test_lib.sln create mode 100644 test_lib/test_lib/test_lib.vcproj create mode 100644 test_lib/test_lib_dyn/stdafx.cpp create mode 100644 test_lib/test_lib_dyn/stdafx.h create mode 100644 test_lib/test_lib_dyn/test_lib_dyn.cpp create mode 100644 test_lib/test_lib_dyn/test_lib_dyn.h create mode 100644 test_lib/test_lib_dyn/test_lib_dyn.vcproj create mode 100644 test_lib/test_lib_static/method1.cpp create mode 100644 test_lib/test_lib_static/method2.cpp create mode 100644 test_lib/test_lib_static/method3.cpp create mode 100644 test_lib/test_lib_static/obj1.cpp create mode 100644 test_lib/test_lib_static/obj2.cpp create mode 100644 test_lib/test_lib_static/obj3.cpp create mode 100644 test_lib/test_lib_static/test_lib_static.vcproj create mode 100644 test_lib/test_lib_static/test_static.h create mode 100644 test_locale/testLocale.sln create mode 100644 test_locale/testLocale/testLocale.cpp create mode 100644 test_locale/testLocale/testLocale.vcproj create mode 100644 test_public_parent/test_public_parent.sln create mode 100644 test_public_parent/test_public_parent/stdafx.cpp create mode 100644 test_public_parent/test_public_parent/stdafx.h create mode 100644 test_public_parent/test_public_parent/test_public_parent.cpp create mode 100644 test_public_parent/test_public_parent/test_public_parent.vcproj create mode 100644 test_rvalue_ref.cpp create mode 100644 test_static_double.cpp create mode 100644 test_static_double.h create mode 100644 test_static_double2.cpp create mode 100644 test_wfstream/test_wfstream.cpp create mode 100644 test_wfstream/test_wfstream.sln create mode 100644 test_wfstream/test_wfstream.vcproj create mode 100644 toIntTest.cpp create mode 100644 typedefed_operators.cpp create mode 100644 util/unfreeze.cpp create mode 100644 vector_bool_itor.cpp create mode 100644 virtual_inheritence.cpp create mode 100644 virtual_method_ptr.cpp create mode 100644 virtual_overriding.cpp create mode 100644 virtual_typo.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..707954b --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.o +*.obj +*.cpp~ +*.h~ + diff --git a/Duffs_device.cpp b/Duffs_device.cpp new file mode 100644 index 0000000..faed374 --- /dev/null +++ b/Duffs_device.cpp @@ -0,0 +1,47 @@ +#include +#include + +void send(short *to, const short *from, size_t count) +{ + size_t n=(count+7)/8; + switch(count%8){ + case 0: do{ *to += *from++; + case 7: *to += *from++; + case 6: *to += *from++; + case 5: *to += *from++; + case 4: *to += *from++; + case 3: *to += *from++; + case 2: *to += *from++; + case 1: *to += *from++; + }while(--n>0); + } +} + +void send2(short *to, const short *from, size_t count) +{ + int n=(count+7)/8; + switch(count%8){ + case 0: while(--n>0){ + *to += *from++; + case 7: *to += *from++; + case 6: *to += *from++; + case 5: *to += *from++; + case 4: *to += *from++; + case 3: *to += *from++; + case 2: *to += *from++; + case 1: *to += *from++; + } + } +} + +int main ( ) +{ + short a[256]; + short sum = 0; + for ( int i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) + a[i] = 1; + + send2( &sum, a, 0 ); + std::cout << sum << std::endl; + return 0; +} diff --git a/OpenMPForVC2k5/omp.h b/OpenMPForVC2k5/omp.h new file mode 100644 index 0000000..867f10a --- /dev/null +++ b/OpenMPForVC2k5/omp.h @@ -0,0 +1,204 @@ +//----------------------------------------------------------------------------- +// OpenMP runtime support library for Visual C++ +// Copyright (C) Microsoft Corporation. All rights reserved. +//----------------------------------------------------------------------------- + +// OpenMP C/C++ Version 2.0 March 2002 + +#pragma once + +#if defined(__cplusplus) +extern "C" { +#endif + +#define _OMPAPI __cdecl + +#if !defined(_OMP_LOCK_T) +#define _OMP_LOCK_T +typedef void * omp_lock_t; +#endif + +#if !defined(_OMP_NEST_LOCK_T) +#define _OMP_NEST_LOCK_T +typedef void * omp_nest_lock_t; +#endif + +#if !defined(_OPENMP) + +#if defined(_DEBUG) + #pragma comment(lib, "vcompd") +#else // _DEBUG + #pragma comment(lib, "vcomp") +#endif // _DEBUG + +#endif // _OPENMP + +#if !defined(_OPENMP_NOFORCE_MANIFEST) + + #include + + #if defined(_DEBUG) + + #if defined(_M_IX86) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_AMD64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_IA64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugOpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='ia64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #endif + + #else // _DEBUG + + #if defined(_M_IX86) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='x86' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_AMD64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='amd64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #elif defined(_M_IA64) + #pragma comment(linker,"/manifestdependency:\"type='win32' " \ + "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".OpenMP' " \ + "version='" _CRT_ASSEMBLY_VERSION "' " \ + "processorArchitecture='ia64' " \ + "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"") + #endif + + #endif // _DEBUG + +#endif // _OPENMP_NOFORCE_MANIFEST + +#if !defined(_OMPIMP) +#define _OMPIMP __declspec(dllimport) +#endif + +_OMPIMP void _OMPAPI +omp_set_num_threads( + int _Num_threads + ); + +_OMPIMP int _OMPAPI +omp_get_num_threads( + void + ); + +_OMPIMP int _OMPAPI +omp_get_max_threads( + void + ); + +_OMPIMP int _OMPAPI +omp_get_thread_num( + void + ); + +_OMPIMP int _OMPAPI +omp_get_num_procs( + void + ); + +_OMPIMP void _OMPAPI +omp_set_dynamic( + int _Dynamic_threads + ); + +_OMPIMP int _OMPAPI +omp_get_dynamic( + void + ); + +_OMPIMP int _OMPAPI +omp_in_parallel( + void + ); + +_OMPIMP void _OMPAPI +omp_set_nested( + int _Nested + ); + +_OMPIMP int _OMPAPI +omp_get_nested( + void + ); + +_OMPIMP void _OMPAPI +omp_init_lock( + omp_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_destroy_lock( + omp_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_set_lock( + omp_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_unset_lock( + omp_lock_t * _Lock + ); + +_OMPIMP int _OMPAPI +omp_test_lock( + omp_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_init_nest_lock( + omp_nest_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_destroy_nest_lock( + omp_nest_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_set_nest_lock( + omp_nest_lock_t * _Lock + ); + +_OMPIMP void _OMPAPI +omp_unset_nest_lock( + omp_nest_lock_t * _Lock + ); + +_OMPIMP int _OMPAPI +omp_test_nest_lock( + omp_nest_lock_t * _Lock + ); + +_OMPIMP double _OMPAPI +omp_get_wtime( + void + ); + +_OMPIMP double _OMPAPI +omp_get_wtick( + void + ); + +#if defined(__cplusplus) +} +#endif diff --git a/SSE2_transform.cpp b/SSE2_transform.cpp new file mode 100644 index 0000000..218c91b --- /dev/null +++ b/SSE2_transform.cpp @@ -0,0 +1,1562 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "SSE2_transform.h" + +namespace base +{ + + const stdOrientEnum inverseStdOrient[stdOrientMAX] = + { + R0, + R270, + R180, + R90, + XFlipR0, + XFlipR90, + XFlipR180, + XFlipR270 + }; + /* In Aix64 platform char is by default unsigned this causes difference in values, ensuring signed char array */ + const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2] = + { + // + /// R0: 0 degree rotation with no flip. + /// Coefficients = | 1 0| + /// | 0 1| + // + {{1, 0}, + {0, 1}}, + // + /// R90: 90 degree rotation with no flip. + /// Coefficients = | 0 1| + /// |-1 0| + // + {{0, 1}, + {-1, 0}}, + // + /// R180: 180 degree rotation with no flip. + /// Coefficients = |-1 0| + /// | 0 -1| + // + {{-1, 0}, + {0, -1}}, + // + /// R270: 270 degree rotation with no flip. + /// Coefficients = | 0 -1| + /// | 1 0| + // + {{0, -1}, + {1, 0}}, + // + /// XFlipR0: X flip followed by 0 degree rotation. + /// Coefficients = | 1 0| + /// | 0 -1| + // + {{1, 0}, + {0, -1}}, + // + /// X flip followed by 90 degree rotation. + /// Coefficients = | 0 1| + /// | 1 0| + // + {{0, 1}, + {1, 0}}, + // + /// X flip followed by 180 degree rotation. + /// Coefficients = |-1 0| + /// | 0 1| + // + {{-1, 0}, + {0, 1}}, + // + /// X flip followed by 270 degree rotation. + /// Coefficients = | 0 -1| + /// |-1 0| + // + {{0, -1}, + {-1, 0}} + }; + // + /// Matrix for multiplying standard orientations. + // + const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX] = { + // R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270 + /* R0 */ { R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270}, + /* R90 */ { R90, R180, R270, R0, XFlipR270, XFlipR0, XFlipR90, XFlipR180}, + /* R180 */ { R180, R270, R0, R90, XFlipR180, XFlipR270, XFlipR0, XFlipR90}, + /* R270 */ { R270, R0, R90, R180, XFlipR90, XFlipR180, XFlipR270, XFlipR0}, + /* XFlipR0 */ { XFlipR0, XFlipR90, XFlipR180, XFlipR270, R0, R90, R180, R270}, + /* XFlipR90 */ { XFlipR90, XFlipR180, XFlipR270, XFlipR0, R270, R0, R90, R180}, + /* XFlipR180 */ { XFlipR180, XFlipR270, XFlipR0, XFlipR90, R180, R270, R0, R90}, + /* XFlipR270 */ { XFlipR270, XFlipR0, XFlipR90, XFlipR180, R90, R180, R270, R0} + }; + + typedef pod::point (*pModifyFunDblToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunDblToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunDblToDbl)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToLong)(const transform &, pod::point); + // + /// Type definition for for transforming a rectangle of type double to + /// another rectangle of type double. + // + typedef pod::rectangle (*pModifyRectFunDblToDbl)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type long to + /// another rectangle of type long. + // + typedef pod::rectangle (*pModifyRectFunLongToLong)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type int to + /// another rectangle of type int. + // + typedef pod::rectangle (*pModifyRectFunIntToInt)(const transform &, const pod::rectangle &); + + static pModifyFunDblToShort modifyDblToShortFunTbl[transformTypeMAX]; + static pModifyFunLongToShort modifyLongToShortFunTbl[transformTypeMAX]; + static pModifyFunIntToShort modifyIntToShortFunTbl[transformTypeMAX]; + static pModifyFunDblToInt modifyDblToIntFunTbl[transformTypeMAX]; + static pModifyFunDblToDbl modifyDblToDblFunTbl[transformTypeMAX]; + static pModifyFunLongToInt modifyLongToIntFunTbl[transformTypeMAX]; + static pModifyFunIntToInt modifyIntToIntFunTbl[transformTypeMAX]; + static pModifyFunLongToLong modifyLongToLongFunTbl[transformTypeMAX]; + static pModifyRectFunLongToLong modifyRectLongToLongFunTbl[transformTypeMAX]; + static pModifyRectFunDblToDbl modifyRectDblToDblFunTbl[transformTypeMAX]; + static pModifyRectFunIntToInt modifyRectIntToIntFunTbl[transformTypeMAX]; + // + /// Modify a point using scale transform. + // + template + pod::point GXX_HIDDEN modifyScale( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + // + /// Modify a point using scale and offset transform. + // + template + pod::point GXX_HIDDEN modifyScaleOffset( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal() + T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + // + /// Modify a point using a general transform. + // + template + pod::point GXX_HIDDEN modifyGeneral( const transform & T, pod::point xy ) + { + pod::point tmp(T.getCol1()*pod::point(xy),T.getCol2()*pod::point(xy)); + tmp += T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + + template + pod::point GXX_HIDDEN modifyStd ( const transform & T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::round(d.getX()), (oC)base::round(d.getY())); + } + // + /// Modify a point using standard transform with magnification + // + template + pod::point GXX_HIDDEN modifyStdMag( const transform &T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() * T.get11() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::round(d.getX()), (oC)base::round(d.getY())); + } + // + /// Modify a point using resolution transform. + // + template + pod::point GXX_HIDDEN modifyResolution( const transform &T, pod::point xy ) + { + pod::point tmp = xy % T.getDiagonal(); + if (T.getNext()) { + if (std::tr1::is_double::value) { + pod::point tmp2 = pod::point((double)tmp.X(), + (double)tmp.Y()); + return T.getNext()->modifyDblToDbl(tmp2); + } else if (std::tr1::is_long::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToLong(tmp2); + } else if (std::tr1::is_int::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToInt(tmp2); + } else if (std::tr1::is_short::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToShort(tmp2); + } + } else + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) : + pod::point((oC)base::round(tmp.X()), + (oC)base::round(tmp.Y())); + // Should not get here or something is missing. + throw except::programError(); + return pod::point((oC)0, (oC)0); + } + // + // Modify a rectangle using scale transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScale(T,r.getLowerLeft()), + modifyScale(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using scale and offset transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleOffsetRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScaleOffset(T,r.getLowerLeft()), + modifyScaleOffset(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using a general transform. + // + template + pod::rectangle GXX_HIDDEN modifyGeneralRect( + const transform & T, + const pod::rectangle & r ) + { + // + // We have to transform all four corner points when using a + // general transform in order to figure out what the new corner + // points will be. + // + pod::point p0 = modifyGeneral(T,r.getLowerLeft()); + pod::point p1 = modifyGeneral(T,r.getLowerRight()); + pod::point p2 = modifyGeneral(T,r.getUpperRight()); + pod::point p3 = modifyGeneral(T,r.getUpperLeft()); + pod::rectangle rect; + rect.merge(p0); + rect.merge(p1); + rect.merge(p2); + rect.merge(p3); + return rect; + } + + template + pod::rectangle GXX_HIDDEN modifyStdRect ( + const transform & T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStd(T,r.getLowerLeft()), + modifyStd(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using standard transform with magnification. + // + template + pod::rectangle GXX_HIDDEN modifyStdMagRect( + const transform &T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStdMag(T,r.getLowerLeft()), + modifyStdMag(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using resolution transform. + // + template + pod::rectangle GXX_HIDDEN modifyResolutionRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyResolution(T,r.getLowerLeft()), + modifyResolution(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + + // + /// Type definition for determining inverse of various transform types. + // + typedef transform (*pGetInverseFun)(const transform &); + // + /// Table of inverse determining functions by transform type. + // + static pGetInverseFun getInverseFnTbl[transformTypeMAX]; + + typedef void (*pMultFun)( const transform & T1, + const transform & T2, + transform & outT ); + + static pMultFun multFnTbl[transformTypeMAX*transformTypeMAX]; + // + /// Initialize the function tables. + // + void transform::initFnTables() + { + // + // double to short + // + modifyDblToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToShortFunTbl[StdTransformType] = &modifyStd; + modifyDblToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to short + // + modifyLongToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToShortFunTbl[StdTransformType] = &modifyStd; + modifyLongToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to short + // + modifyIntToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToShortFunTbl[StdTransformType] = &modifyStd; + modifyIntToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to int + // + modifyDblToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToIntFunTbl[StdTransformType] = &modifyStd; + modifyDblToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to double + // + modifyDblToDblFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToDblFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToDblFunTbl[StdTransformType] = &modifyStd; + modifyDblToDblFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToDblFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToDblFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to int + // + modifyLongToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToIntFunTbl[StdTransformType] = &modifyStd; + modifyLongToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to int + // + modifyIntToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToIntFunTbl[StdTransformType] = &modifyStd; + modifyIntToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to long + // + modifyLongToLongFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToLongFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToLongFunTbl[StdTransformType] = &modifyStd; + modifyLongToLongFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToLongFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToLongFunTbl[ResolutionTransformType] = &modifyResolution; + // + /// Init get inverse func table. + // + getInverseFnTbl[ScaleOffsetTransformType] = &getInverseScaleOffset; + getInverseFnTbl[GeneralTransformType] = &getInverseGeneral; + getInverseFnTbl[StdTransformType] = &getInverseStd; + getInverseFnTbl[StdTransformWithMagType] = &getInverseStdWithMag; + getInverseFnTbl[ScaleTransformType] = &getInverseScale; + getInverseFnTbl[ResolutionTransformType] = &getInverseResolution; + // + /// Init the multiply func table. + // + multFnTbl[0] = &multScaleOffsetXScaleOffset; + multFnTbl[1] = &multScaleOffsetXGeneral; + multFnTbl[2] = &multScaleOffsetXStd; + multFnTbl[3] = &multScaleOffsetXStdWithMag; + multFnTbl[4] = &multScaleOffsetXScaleOffset; + multFnTbl[5] = &multScaleOffsetXResolution; + multFnTbl[6] = &multGeneralXScaleOffset; + multFnTbl[7] = &multGeneralXGeneral; + multFnTbl[8] = &multGeneralXStd; + multFnTbl[9] = &multGeneralXStdWithMag; + multFnTbl[10] = &multGeneralXScaleOffset; + multFnTbl[11] = &multGeneralXResolution; + multFnTbl[12] = &multStdXScaleOffset; + multFnTbl[13] = &multStdXGeneral; + multFnTbl[14] = &multStdXStd; + multFnTbl[15] = &multStdXStdWithMag; + multFnTbl[16] = &multStdXScaleOffset; + multFnTbl[17] = &multStdXResolution; + multFnTbl[18] = &multStdWithMagXScaleOffset; + multFnTbl[19] = &multStdWithMagXGeneral; + multFnTbl[20] = &multStdWithMagXStd; + multFnTbl[21] = &multStdWithMagXStdWithMag; + multFnTbl[22] = &multStdWithMagXScaleOffset; + multFnTbl[23] = &multStdWithMagXResolution; + multFnTbl[24] = &multScaleOffsetXScaleOffset; + multFnTbl[25] = &multScaleOffsetXGeneral; + multFnTbl[26] = &multScaleOffsetXStd; + multFnTbl[27] = &multScaleOffsetXStdWithMag; + multFnTbl[28] = &multScaleXScale; + multFnTbl[29] = &multScaleXResolution; + multFnTbl[30] = &multResolutionXAny; + multFnTbl[31] = &multResolutionXAny; + multFnTbl[32] = &multResolutionXAny; + multFnTbl[33] = &multResolutionXAny; + multFnTbl[34] = &multResolutionXAny; + multFnTbl[35] = &multResolutionXAny; + // + // Initialize the rectangle modification function tables. + // + modifyRectLongToLongFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectLongToLongFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectLongToLongFunTbl[StdTransformType] = modifyStdRect; + modifyRectLongToLongFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectLongToLongFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectLongToLongFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectDblToDblFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectDblToDblFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectDblToDblFunTbl[StdTransformType] = modifyStdRect; + modifyRectDblToDblFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectDblToDblFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectDblToDblFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectIntToIntFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectIntToIntFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectIntToIntFunTbl[StdTransformType] = modifyStdRect; + modifyRectIntToIntFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectIntToIntFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectIntToIntFunTbl[ResolutionTransformType] = modifyResolutionRect; + } + + transform transform::getInverse() const + { + return (*(getInverseFnTbl[type]))(*this); + } + + void transform::mult(const transform &T2, transform & outT) const + { + (*(multFnTbl[(type*transformTypeMAX)+T2.type]))(*this,T2,outT); + } + + pod::point transform::modifyDblToShort(pod::point p) const + { + return (*(modifyDblToShortFunTbl[type]))(*this, p); + } + + pod::point transform::modifyDblToInt(pod::point p) const + { + return (*(modifyDblToIntFunTbl[type]))(*this, p); + } + + pod::point transform::modifyDblToDbl(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + pod::point transform::modify(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + + pod::point transform::modifyIntToInt(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + pod::point transform::modify(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + + pod::point transform::modifyIntToShort(pod::point p) const + { + return (*(modifyIntToShortFunTbl[type]))(*this, p); + } + + pod::point transform::modifyLongToShort(pod::point p) const + { + return (*(modifyLongToShortFunTbl[type]))(*this, p); + } + + pod::point transform::modifyLongToInt(pod::point p) const + { + return (*(modifyLongToIntFunTbl[type]))(*this, p); + } + + pod::point transform::modifyLongToLong(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::point transform::modify(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::rectangle transform::operator()(const pod::rectangle & r) const + { + return (*(modifyRectDblToDblFunTbl[type]))(*this, r); + } + + pod::rectangle transform::operator()(const pod::rectangle & r) const + { + return (*(modifyRectLongToLongFunTbl[type]))(*this, r); + } + + pod::rectangle transform::operator()(const pod::rectangle & r) const + { + return (*(modifyRectIntToIntFunTbl[type]))(*this, r); + } + + pod::point transform::operator()(const pod::point & p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + + pod::point transform::operator()(const pod::point & p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::point transform::operator()(const pod::point & p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + + + // Value of standard orientation + const struct { bool xflip; double angle;} stdOrientXFlipAngValues[stdOrientMAX]= + { + {false, 0. }, // RO + {false, 90. }, // R90 + {false, 180. }, // R180 + {false, 270. }, // R270 + {true, 0. }, // XFlipR0 + {true, 90. }, //XFlipR90 + {true, 180. }, //XFlipR180 + {true, 270. } //XFlipR270 + }; + + const void transform::getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const + { + + if( type!=GeneralTransformType) + { + // + // standard orientation. Use table + // + int idx= (int) getOrient().getOri(); + isXFlip= stdOrientXFlipAngValues[idx].xflip; + angle = stdOrientXFlipAngValues[idx].angle; + mag = a11; + } + else + { + // From constructor + // double multiplier = 1.0; + // if (inXFlip == true) + // multiplier = -1.0; + // register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + // register double cosine = cos(newAngle); + // register double sine = sin(newAngle); + // a11 = inMag * cosine; + // a12 = inMag * sine; + // a21 = -inMag * multiplier * sine; + // a22 = inMag * multiplier * cosine; + // + // How to get angle, inMage and inXFlip from a11, a12, a21, and a22 + // Let sumProd = a11* a22 - a12*a21 + // = (inMag*consine)(inMag * multiplier * cosine) - (inMag * sine)(-inMag * multiplier * sine) + // = inMag*inMag*multiplier*consine*consine + inMag*inMag*multiplier*sine*sine + // = inMag*inMag*multiplier(consine* consine + sine*sine) + // = inMag*inMag*multiplier + // + // if( sumProd) < 0 ==> inXFlip=true + // inMag= SquareRoot( Abs(sumPro)); + // Angle= ArcCosine(a11/inMag) + + double sumProd= a11*a22 - a12*a21; + + //get inXFlip. + // sumProd= imMag*imMag*multiplier + isXFlip= sumProd < 0; + + // get abs(imMag*imMag) + if(sumProd<0) + sumProd= -sumProd; + + // get mag + mag= sqrt(sumProd); + + // get angle + if(mag> 0) + { + + double angleR= acos(a11/mag); + angle=radiansToDegrees(angleR); + + // aCos funciton range is 0 to 180. + // We need to decide if angle is between 180 to 360 + // + // How to solve it + // Let (Xt, Yt) is the point by applying (1,0) with transformation without xFlip, + // if Yt > 0, then angle is located between 180 and 360 + // + // i.e. + // | a11 a12 | x | 1 | = [a11 a21p ] = (Xt, Yt) + // | a21p a22 | | 0 | + // a21= multiplier * a21p = xFlip + angle + // if a21p > 0 angle is located between 180 and 360 + // + double a21p= isXFlip? -a21: a21; + if( a21p> 0 ) + angle= 360. - angle; + + } + else + angle=0; + }// end else + } + + transform transform::getInverseScaleOffset(const transform & T) + { + return transform( -T.offset.X()/T.a11, + -T.offset.Y()/T.a22, + 1.0/T.a11, + 1.0/T.a22); + } + // + /// Get the inverse of a general transform. + // + transform transform::getInverseGeneral(const transform & T ) + { + // + // compute the determinant + // + double det = T.a11*T.a22 - T.a12*T.a21; + + return transform( (T.offset.Y()*T.a21 - T.offset.X()*T.a22)/det, + (T.offset.X()*T.a12 - T.offset.Y()*T.a11)/det, + T.a22/det, + -T.a12/det, + -T.a21/det, + T.a11/det); + } + // + /// Get the inverse of a standard transform. + // + transform transform::getInverseStd(const transform & T) + { + // + // Transform the offset. + // + pod::point off = - T.offset * stdOrient(inverseStdOrient[T.orient.getOri()]); + // + // Return the inverted standard transform. + // + return transform (off.X(), off.Y(), + inverseStdOrient[T.orient.getOri()]); + } + // + /// Get the inverse of a standard transform with mag. + // + transform transform::getInverseStdWithMag(const transform & T) + { + register double oneOverMag = 1.0/T.a11; + register stdOrientEnum e = inverseStdOrient[T.orient.getOri()]; + // + // Transform the offset. + // + pod::point off = - (T.offset * stdOrient(e)) * oneOverMag; + + return transform( off.X(), + off.Y(), + e, + oneOverMag ); + } + // + /// Get the inverse of a scale transform. + // + transform transform::getInverseScale(const transform & T) + { + return transform( 0.0, + 0.0, + 1.0/T.a11, + 1.0/T.a22); + } + // + // Get the inverse of a resolution transform. + // + transform transform::getInverseResolution(const transform & T) + { + if (T.next) { + transform T1(T.a11, T.a22, false); + transform T2; + T1.mult(*(T.next), T2); + return T2.getInverse(); + } else { + return transform(1.0/T.a11, 1.0/T.a22, false); + } + } + // + /// Multiply two scale transforms. + // + void transform::multScaleXScale(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point(0.0, 0.0); + } + // + /// Multiply a scale transform with a resolution transform. + // + void transform::multScaleXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp(T1.a11, T1.a22, false); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(0.0); + outT.next->offset.setY(0.0); + } else { + outT.next = new transform(T1.a11, T1.a22, false); + } + } + } + // + // + /// Multiply two scale offset transforms. + // + void transform::multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleOffsetTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( + T2.a11*T1.offset.X() + T2.offset.X(), + T2.a22*T1.offset.Y() + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a general transform. + // + void transform::multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a11*T2.a12; + outT.a21 = T1.a22*T2.a21; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21 + T2.offset.X(), + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22 + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a standard transform. + // + void transform::multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0], + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]) + + T2.offset; + } + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + void transform::multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]), + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1])) + + T2.offset; + } + // + /// Multiply a scale offset transform with a resolution transform. + // + void transform::multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleOffsetTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = 0.0; + outT.next->a21 = 0.0; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + } + } + } + // + /// Multiply a general transform with a scale offset transform. + // + void transform::multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two general transforms. + // + void transform::multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11 + T1.a12*T2.a21; + outT.a12 = T1.a11*T2.a12 + T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11 + T1.a22*T2.a21; + outT.a22 = T1.a21*T2.a12 + T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a general transform with a standard transform. + // + void transform::multGeneralXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + outT.a21 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + void transform::multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a12 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + outT.a21 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a22 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + // + // Transform the offset. + // + outT.offset = (T1.offset * T2.orient) * T2.a11 + T2.offset; + } + // + /// Multiply a general transform with a resolution transform. + // + void transform::multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = GeneralTransformType; + outT.next->a11 = T1.a11; + outT.next->a22 = T1.a22; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + } + } + } + // + /// Multiply a standard transform with a scale and offset transform. + // + void transform::multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with a general transform. + // + void transform::multStdXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two standard transforms. + // + void transform::multStdXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformType; + outT.orient = multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + void transform::multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with a resolution transform. + // + void transform::multStdXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = StdTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + } + } + } + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + void transform::multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + void transform::multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21); + outT.a12 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22); + outT.a21 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21); + outT.a22 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22); + // + // Transfomr the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + void transform::multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply two standard transforms with magnification. + // + void transform::multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11*T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + void transform::multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = StdTransformWithMagType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + } + } + } + // + /// Multiply a resolution transform with any transform. + // + void transform::multResolutionXAny(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T1.a11; + outT.a12 = T1.a12; + outT.a21 = T1.a21; + outT.a22 = T1.a22; + + if(T1.next) { + if (!(outT.next)) + outT.next = new transform; + T1.next->mult(T2, *(outT.next)); + } else { + outT.next = new transform(T2); + } + } + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void transform::modify( const pod::point& rSrc, pod::point& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffset( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneral( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStd( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMag( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScale( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolution( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// This is pod::rectangle version of above function. + // + template + void transform::modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffsetRect( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneralRect( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStdRect( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMagRect( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScaleRect( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolutionRect( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void transform::modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + // + // If we have orthogonal transform? + // First check get12 since most of transform will + // have no rotation factor. + // + if ( get12() == 0 || get11() == 0 ) + modify( rSrc, rDest ); + // + // General case. + // + else + { + rDest.makeInvalid(); + pod::point tmp; + + modify( rSrc.getLowerLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getLowerRight(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperRight(), tmp ); + rDest.merge( tmp ); + } + } + + +/***************************************************************************** +* Instantiate template with some arguments. +*/ +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +namespace transformTest +{ + + + /// called by testGetAngleFlipMag() + bool testTran_(int idx, const transform& tr, bool xFlip0, double angle0, double mag0) + { + // Get angle/xflip/mag from tr + bool xFlip; + double angle, mag; + tr.getAngleFlipMag( angle,xFlip, mag); + + // Compare + bool bFlp= xFlip == xFlip0; + bool bAng=(angle - angle0) < absTolerance && + (angle0 -angle) < absTolerance ; + bool bMag= (mag - mag0) < absTolerance && + (mag0 -mag) < absTolerance ; + + // Print error message if there is different + if(!bFlp || !bAng || !bMag) + { + printf(" %-2d tr(xFlop=%s)",idx, (xFlip0?"T":"F")); + if(!bFlp) + printf("!= %s", (xFlip?"T":"F")); + + printf(" (angle=%10.5f)", angle0) ; + if(!bAng) + printf("!= %10.5f", angle); + + printf(" (mag=%5.3f)",mag0); + + if(!bMag) + printf("!= %5.3f", mag); + printf("\n"); + return false; + } + return true; + } + + // + /// Function test getAngelFlipMag() + // + bool testGetAngleFlipMag() + { + struct { bool xFlip; double angle; double mag; } testData[]= + { // xFlip Angle Max index + {false, 0, 1}, //0 standard Orientation + {false, 90, 1.1}, //1 + {false, 180, 1.2}, //2 + {false, 270, 1.3}, //3 + {true, 0, 1.4}, //4 + {true, 90, 1.5}, //5 + {true, 180, 1.6}, //6 + {true, 270, 1.7}, //7 + {false, 23, 1.8}, //8 non-standard Orientation + {true, 23, 1.9}, //9 + {false, 92, 2.1}, //10 + {true, 92, 2.2}, //11 + {false, 192, 2.3}, //12 + {true, 192, 2.4}, //13 + {false, 272, 2.5}, //14 + {true, 272, 2.6} //15 + }; + const int dataCount=16; + int failCtr=0; + int i=0; + for( ;i < dataCount; i++) + { + // Construct transform + transform tr(0,0, + testData[i].xFlip, + testData[i].angle, + testData[i].mag); + if(! testTran_(i, tr, testData[i].xFlip, testData[i].angle, testData[i].mag)) + failCtr++; + } + + /// set a11, a12, a21, a22 directly + transform trR0(101,101, 1, 0, 0, 1); + transform trR90(101,101, 0, 1, -1, 0); + transform trR180(101,101, -1,0, 0, -1); + transform trR270(101,101, 0, -1, 1, 0); + + transform XtrR0(101,101, 1, 0,0, -1); + transform XtrR90(101,101, 0, 1, 1, 0); + transform XtrR180(101,101, -1,0, 0, 1); + transform XtrR270(101,101, 0, -1, -1, 0); + + if(!testTran_(i++, trR0, false, 0, 1)) failCtr++; + if(!testTran_(i++, trR90, false, 90, 1)) failCtr++; + if(!testTran_(i++, trR180, false, 180, 1)) failCtr++; + if(!testTran_(i++, trR270, false, 270, 1)) failCtr++; + if(!testTran_(i++, XtrR0, true, 0, 1)) failCtr++; + if(!testTran_(i++, XtrR90, true, 90, 1)) failCtr++; + if(!testTran_(i++, XtrR180,true, 180, 1)) failCtr++; + if(!testTran_(i++, XtrR270,true, 270, 1)) failCtr++; + + + // Print summary + printf("transformation::testGetAngleFlipMag() test:%s\n", + (failCtr >0 ? " failed":" passed")); + + return failCtr==0; + } + + +}; + +}; // namespace base diff --git a/SSE2_transform.h b/SSE2_transform.h new file mode 100644 index 0000000..83e5eee --- /dev/null +++ b/SSE2_transform.h @@ -0,0 +1,1119 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#ifndef TRANSFORM_H_ +#define TRANSFORM_H_ + +// _MSC_VER >= 1400 means we deal with VC8 or higher. +#if defined( _MSC_VER ) +/*warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)*/ +#pragma warning( disable: 4290 ) +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace base; +// +/// The transform.h file contains the different transform types. +// +/*! + * Usage of transforms: + * Transforms are applied to row vectors from the right as shown below: + * OV = IV * T + * Here, OV and IV are the output and input row vectors and T is the transform. + * + * Multiplying transforms: + * Suppose we have a chain of transforms. + * OV = IV * T1 * T2 + * OV = IV * T + * Thus, T can be computed as follows: + * Transform T; + * T1.mult(T2, T); + * + * A general 2-D transform can be viewed in matrix form as follows: + * |a11 a12 0| + * |a21 a22 0| + * | tx ty 1| + * A general transform can be viewed as a sequence of 3 steps: + * 1- Scaling with value (Sx, Sy) (i.e. x' = Sx*x, y' = Sy*y). + * 2- rotating with angle A. + * 3- translating with value (tx, ty). + * In other words, the 2-D transform is the multiplication of the 3 transforms + * as follows: + * |Sx 0 0| | cos(A) sin(A) 0| | 1 0 0| + * |0 Sy 0|*|-sin(A) cos(A) 0|*| 0 1 0| + * |0 0 1| | 0 0 1| |tx ty 1| + * + * Using resolution transforms: + * In order to mimic applying resolution transforms to each cell individually, + * a resolution change operation is applied before anything. Suppose we call + * the resolution change transform RES. Also suppose the transform from the + * cell to the screen is TS. Thus: + * OV = IV * RES * TS. + * In order to change the resolution of a layout, we need to insert the + * resolution transform RES in the chain. Hence: + * 1- Create a resolution transform RES(xScale, yScale, true). + * 2- Assuming T is the total transform, T can be computed as follows: + * RES.mult(TS, T). + */ +namespace test +{ + // + /// Enum for types of transforms. + // + enum transformType + { + // + /// ScaleOffsetTransform type. + // + ScaleOffsetTransformType = 0, + // + /// GeneralTransform type. + // + GeneralTransformType, + // + /// StdTransform type. + // + StdTransformType, + // + /// StdTransformWithMag type. + // + StdTransformWithMagType, + // + /// StdTransformWithMag type. + // + ScaleTransformType, + // + /// Resolution type. + // + ResolutionTransformType, + // + /// Always keep this entry as the last enum value. + // + transformTypeMAX + }; // enum transformType + // + /// Inverses of the standard orientations. + // + extern const stdOrientEnum inverseStdOrient[stdOrientMAX]; + // + /// Coefficient matrices for the standard orientations. + // + extern const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2]; + // + /// Matrix holding standard orientations resulting from multiplying + /// different standard orientations. + // + extern const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX]; + + // + /// The main transformation class. + // + class GXX_VISIBLE transform + { + protected: + // + /// Type of transform. + // + unsigned int type : 4; + // + /// Orientation field. + // + base::stdOrient orient; + // + /// 2X2 coefficient submatrix. + /// a11 would be used for Sx for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + /// Also, a11 would be used for magnification in the case of + /// standard transforms with magnification. + /// a22 would be used for Sy for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + // + double a11, a12, a21, a22; + // + // Offset for the transform. + // + pod::point offset; + // + /// Pointer to next transform in chain. This is used by + /// resolution transforms. + // + transform *next; + + typedef pod::point (*pModifyFunDblToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToDbl)( + const transform &T, + pod::point xy ); + + private: + + // + /// Get the inverse of a scale offset transform. + // + static transform getInverseScaleOffset(const transform & T); + // + /// Get the inverse of a general transform. + // + static transform getInverseGeneral(const transform & T ); + // + /// Get the inverse of a standard transform. + // + static transform getInverseStd(const transform & T); + // + /// Get the inverse of a standard transform with mag. + // + static transform getInverseStdWithMag(const transform & T); + // + /// Get the inverse of a scale transform. + // + static transform getInverseScale(const transform & T); + // + // Get the inverse of a resolution transform. + // + static transform getInverseResolution(const transform & T); + // + /// Multiply two scale transforms. + // + static void multScaleXScale(const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale transform with a resolution transform. + // + static void multScaleXResolution( const transform &T1, + const transform &T2, + transform &outT); + // + // + /// Multiply two scale offset transforms. + // + static void multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a general transform. + // + static void multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a standard transform. + // + static void multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + static void multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a resolution transform. + // + static void multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a scale offset transform. + // + static void multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two general transforms. + // + static void multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform. + // + static void multGeneralXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + static void multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a resolution transform. + // + static void multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a scale and offset transform. + // + static void multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a general transform. + // + static void multStdXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms. + // + static void multStdXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + static void multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a resolution transform. + // + static void multStdXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + static void multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + static void multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + static void multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms with magnification. + // + static void multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + static void multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a resolution transform with any transform. + // + static void multResolutionXAny(const transform &T1, + const transform &T2, transform &outT); + + public: + + // + /// Default constuctor. + // + transform() + : + type(StdTransformType), + orient(R0), + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(0.0,0.0), + next(NULL) + {} + // + /// Constructor for a scale offset transform. + // + transform( + double offsetX, + double offsetY, + double scaleX, + double scaleY + ) + : + type(ScaleOffsetTransformType), + a11(scaleX), + a12(0.0), + a21(0.0), + a22(scaleY), + offset(offsetX,offsetY), + next(NULL) + { + double xAbs(offsetX > 0.0 ? offsetX : -offsetX); + double yAbs(offsetY > 0.0 ? offsetY : -offsetY); + if (xAbs < absTolerance && yAbs < absTolerance) + type = ScaleTransformType; + } + // + /// Constructor for a general transform. + // + transform( + double offsetX, + double offsetY, + double coeff11, + double coeff12, + double coeff21, + double coeff22 + ) + : + type(GeneralTransformType), + a11(coeff11), + a12(coeff12), + a21(coeff21), + a22(coeff22), + offset(offsetX,offsetY), + next(NULL) + {}; + // + /// Constructor for a rotate transform. + /// @param inCx X coordinate of the center of rotation. + /// @param inCy Y coordinate of the center of rotation. + /// @param angle rotation angle in degrees. + // + transform( + double inCx, + double inCy, + double angle + ) + : + type(GeneralTransformType), + a11(cos(degreesToRadians(angle))), + a12(sin(degreesToRadians(angle))), + a21(-a12), + a22(a11), + offset(inCy * a12 - inCx * a11 + inCx, + - inCy * a11 - inCx * a12 + inCy), + next(NULL) + {} + // + /// Constructor for a standard transform. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient = R0 + ) + : + type(StdTransformType), + orient(inOrient), + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(offsetX,offsetY), + next(NULL) + {} + // + /// Constructor for a standard transform with magnification. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient, + double inMag) + : + type(StdTransformWithMagType), + orient(inOrient), + a11(inMag), + a12(0.0), + a21(0.0), + a22(inMag), + offset(offsetX,offsetY), + next(NULL) + {} + // + /// Advanced constructor for typical references. + /// @param offsetX X value of translation offset. + /// @param offsetY Y value of translation offset. + /// @param inXFlip boolean reflecting the presence of an X flip. + /// @param inAngle rotation angle in degrees. + /// @param inMag magnification. + // + transform( + double offsetX, + double offsetY, + bool inXFlip, + double inAngle, + double inMag) + : + offset(offsetX,offsetY), + next(NULL) + { + stdOrient newOrient(inXFlip, inAngle); + if (newOrient.getOri() != UnknownStdOrient) + { + orient = newOrient; + if (inMag > 1.0 + relTolerance || + inMag < 1.0 - relTolerance) + { + a11 = inMag; + a12 = 0.0; + a21 = 0.0; + a22 = inMag; + type = StdTransformWithMagType; + } + else + { + a11 = 1.0; + a12 = 0.0; + a21 = 0.0; + a22 = 1.0; + type = StdTransformType; + } + } + else + { + type = GeneralTransformType; + register double multiplier = 1.0; + if (inXFlip == true) + multiplier = -1.0; + register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + register double cosine = cos(newAngle); + register double sine = sin(newAngle); + a11 = inMag * cosine; + a12 = inMag * sine; + a21 = -inMag * multiplier * sine; + a22 = inMag * multiplier * cosine; + } + } + // + /// Scale or resolution transform. + /// @param xScale X value of the scale factor. + /// @param yScale Y value of the scale factor. + /// @param rouding A true value means it is a resolution transform. + /// A false value will result in a standard scale transform. + // + transform( + double xScale, + double yScale, + bool rounding) + : + type(ScaleTransformType), + orient(R0), + a11(xScale), + a12(0.0), + a21(0.0), + a22(yScale), + offset(0.0, 0.0), + next(NULL) + { + if (rounding) { + double rVal(base::round(xScale)); + double diff(xScale - rVal); + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + else { + rVal = base::round(yScale); + diff = yScale - rVal; + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + } + } + } + // + /// Copy constructor + // + transform(const transform & inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + if (inT.next) { + next = new transform(*inT.next); + } else + next = NULL; + } + + // + /// Equal operator + // + bool operator == (const transform &inT) + { + if ((inT.type == type) && + (inT.orient.getOri() == orient.getOri()) && + (inT.a11 == a11) && + (inT.a12 == a12) && + (inT.a21 == a21) && + (inT.a22 == a22) && + (inT.offset == offset)) + { + if (next) + if (inT.next) + return (*next == *(inT.next)); + else + return false; + else + return true; + } + + return false; + } + + // + /// Non equal operator + // + bool operator != (const transform &inT) + { + return !(*this == inT); + } + + // + /// Assignment operator + // + transform & operator = (const transform &inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + if (inT.next) { + if (next) + *next = *(inT.next); + else + next = new transform(*(inT.next)); + } + return *this; + } + + // + /// Destructor + // + ~transform() + { + if (next) + delete next; + } + + // + /// Scale the transform by the given scalar. + // + transform & operator *= (const double d) + { + if (type != ResolutionTransformType) { + transform tmp(d, d, false); + transform out; + mult(tmp, out); + *this = out; + } else { + if (next) + *next *= d; + else + next = new transform(d, d, false); + } + return *this; + } + // + /// Initialize the function tables. + // + static void initFnTables(); + // + /// Test whether this is an identity transform. + // + bool isIdentityTransform() + throw (except::outOfRange) + { + const double onePlusTolerance = 1.0 + relTolerance; + const double oneMinusTolerance = 1.0 - relTolerance; + // + // See if the offsets are beyond the origin. + // + if (offset.X() > absTolerance || offset.X() < -absTolerance || + offset.Y() > absTolerance || offset.Y() < -absTolerance) + return false; + // + // Check by transform type. + // + switch((transformType) type) + { + case StdTransformWithMagType: + if (a11 > onePlusTolerance || a11 < oneMinusTolerance) + return false; + + case StdTransformType: + if (orient.getOri() != R0) + return false; + break; + + case GeneralTransformType: + if ( a12 > absTolerance || + a12 < -absTolerance || + a21 > absTolerance || + a21 < -absTolerance) + return false; + + case ScaleOffsetTransformType: + case ScaleTransformType: + if ( a11 > onePlusTolerance || + a11 < oneMinusTolerance || + a22 > onePlusTolerance || + a22 < oneMinusTolerance) + return false; + break; + + case ResolutionTransformType: + return false; + break; + + default: + throw except::outOfRange("base::transform:isIdentityTransform: Unknown type."); + } + return true; + } + // + /// Multiply with another transform. + // + void mult(const transform &T2, transform &outT) const; + transform operator *(const transform & T) const + { + transform out; + mult(T,out); + return out; + } + // + /// Print a transform, mainly for debug purpose. + // + void print(FILE *outStream, const char *linePrefix) const + { + std::string str = (std::string)(*this); + fprintf(outStream, "%stype = %s.\n", linePrefix, + str.c_str()); + if (getType() != ResolutionTransformType && + getType() != ScaleTransformType) { + fprintf(outStream, "%stx = %f.\n", linePrefix, offset.X()); + fprintf(outStream, "%sty = %f.\n", linePrefix, offset.Y()); + } + switch(type) { + case ScaleOffsetTransformType: + case ScaleTransformType: + fprintf(outStream, "%sscaleX = %f.\n", linePrefix, a11); + fprintf(outStream, "%sscaleY = %f.\n", linePrefix, a22); + break; + + case GeneralTransformType: + fprintf(outStream, "%sa11 = %f.\n", linePrefix, a11); + fprintf(outStream, "%sa12 = %f.\n", linePrefix, a12); + fprintf(outStream, "%sa21 = %f.\n", linePrefix, a21); + fprintf(outStream, "%sa22 = %f.\n", linePrefix, a22); + break; + + case StdTransformType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + break; + + case StdTransformWithMagType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + fprintf(outStream, "%smag = %f.\n", linePrefix, a11); + break; + + case ResolutionTransformType: + fprintf(outStream, "%sscale = %f.\n", linePrefix, a11); + if (next) { + std::string bfr(linePrefix); + bfr += " "; + next->print(outStream, bfr.c_str()); + } + break; + + default: + throw except::outOfRange("base::transform:print: Unknown type."); + } // switch + } + // + /// Return the inverse transform of the transform. + // + transform getInverse() const; + // + /// Returns the type of the transform. + // + transformType getType() const + { + return (transformType) type; + } + // + /// Returns the offset point of the transform. + // + pod::point getOffset() const + { + return offset; + } + // + /// Returns the offset point of the transform taking into account also resolution. + // + pod::point getOffsetRes() const + { + if ( getType() != ResolutionTransformType ) + return offset; + else + { + pod::point zero( 0., 0.); + pod::point off; + modify( zero, off ); + return off; + } + } + // + /// Set the offset of the transform. + // + void setOffset( pod::point off ) + { + offset = off; + } + stdOrient getOrient() const + { + return orient; + } + pod::point getDiagonal() const + { + return pod::point(a11,a22); + } + pod::point getRow1() const + { + return pod::point(a11,a12); + } + pod::point getRow2() const + { + return pod::point(a21,a22); + } + pod::point getCol1() const + { + return pod::point(a11,a21); + } + pod::point getCol2() const + { + return pod::point(a12,a22); + } + // + /// Return the magnitude of the vector (1,0). + // + double getXVectorMag() const + { + if ( a21 == 0.0 ) + return ::fabs(a11); + else if ( a11 == 0.0 ) + return ::fabs(a21); + else + return ::sqrt(a11*a11 + a21*a21); + } + // + /// A special function to return the X scale factor. This + /// is a nonnegative value that reflects the scaling effect + /// in the X direction. + // + double getXScale() const + { + if (type != ResolutionTransformType) + return getXVectorMag(); + else + return getXVectorMag() * (next ? next->getXScale() : 1.0); + } + // + /// Returns the a11 entry of the matrix. If the matrix is a scaling + /// one, then this returns the X-scale factor. + /// The result is not correct for all types of transforms. + // + double get11() const + { + return a11; + } + // + /// Return the a12 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get12() const + { + return a12; + } + // + /// Return the a21 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get21() const + { + return a21; + } + // + /// Returns the a22 entry of the matrix. If the matrix is a scaling + /// one, then this returns the Y-scale factor. + /// The result is not correct for all types of transforms. + // + double get22() const + { + return a22; + } + // + /// Return the next field. + // + const transform *getNext() const + { + return next; + } + + // + /// get angle, isXFlip and mag from transformation + // + const void getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const; + + + // + /// Modify a single point. + // + pod::point modifyDblToShort(pod::point) const; + pod::point modifyDblToInt(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + // + /// Transform doubles to doubles. + // + pod::point modifyDblToDbl(pod::point) const; + pod::point modify(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToDbl(pod::point) const + { return pod::point(); } + // + /// Transform ints to ints. + // + pod::point modifyIntToInt(pod::point) const; + pod::point modify(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + + pod::point modifyIntToShort(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + + pod::point modifyLongToShort(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + // + /// Transform longs to ints. + // + pod::point modifyLongToInt(pod::point) const; + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + // + /// Transform longs to longs. + // + pod::point modifyLongToLong(pod::point) const; + pod::point modify(pod::point) const; + // + // + // + pod::rectangle operator()(const pod::rectangle &) const; + pod::rectangle operator()(const pod::rectangle &) const; + pod::rectangle operator()(const pod::rectangle &) const; + pod::point operator()(const pod::point &) const; + pod::point operator()(const pod::point &) const; + pod::point operator()(const pod::point &) const; + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void modify( const pod::point& rSrc, pod::point& rDest ) const; + + // + /// This is pod::rectangle version of above function. + // + template + void modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Convert a transform type to a string. + // + operator std::string() const + { + switch(type) { + case ScaleOffsetTransformType: + return std::string("ScaleOffsetTransform"); + break; + case GeneralTransformType: + return std::string("GeneralTransform"); + break; + case StdTransformType: + return std::string("StdTransform"); + break; + case StdTransformWithMagType: + return std::string("StdTransformWithMag"); + break; + case ScaleTransformType: + return std::string("ScaleTransform"); + break; + case ResolutionTransformType: + return std::string("ResolutionTransform"); + break; + default: + throw except::outOfRange("base::transformTypeToString: Unknown type."); + } // switch + } + + friend std::ostream & operator << (std::ostream & os, const transform & t) + { + os << "" << std::endl; + os << "" << std::endl; + os << t.getRow1(); + os << t.getRow2(); + os << "" << std::endl; + os << "" << std::endl; + os << t.getOffset(); + os << "" << std::endl; + os << "" << std::endl; + return os; + } + + }; // class transform + +namespace transformTest +{ + + /// API test getAngelFlipmag + bool testGetAngleFlipMag(); +}; + +} // namespace base + +#endif // TRANSFORM_H_ diff --git a/SSE_cmplr_abstraction.h b/SSE_cmplr_abstraction.h new file mode 100644 index 0000000..b366a07 --- /dev/null +++ b/SSE_cmplr_abstraction.h @@ -0,0 +1,280 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_H_ +#define _SSE2_CMPL_ABSTRACTION_H_ + +#include +#include + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +// Ms Visual Studio +// +#if defined( _MSC_VER ) && _MSC_VER + +#include "SSE_cmplr_abstraction_MSC.h" + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +// the GCC +// +#elif defined( _gcc ) + +#include "SSE_cmplr_abstraction_GCC.h" + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +// Other +// +#else + +#include "SSE_cmplr_abstraction_other.h" + + +#endif + +// +// Namespace sse2 +// +namespace sse2 +{ + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// the wrapper for 128 bit xmm registers. +// +template +class xmm128 +{ +// Type +protected: + + // + /// The XMM register type. + // + typedef X MY_XMM; + + // + /// The XMM register type. + // + typedef T MY_TYPE; + +// Data +protected: + + // + /// The union of + // + union + { + MY_XMM x; + MY_TYPE n[N]; + }; + +// Construction +public: + + // + /// The default constructor. + // + xmm128() + { + // + // We must be 128 bits only. + // + BOOST_STATIC_ASSERT( 16/sizeof( MY_TYPE ) == N ); + } + + // + /// The copy constructor. + // + xmm128( const xmm128& op ) + { + // + // We must be 128 bits only. + // + BOOST_STATIC_ASSERT( 16/sizeof( MY_TYPE ) == N ); + + // + // Just assign. + // + x = op.x; + } + + // + /// The copy constructor. + // + xmm128( const MY_XMM& op ) + { + // + // We must be 128 bits only. + // + BOOST_STATIC_ASSERT( 16/sizeof( MY_TYPE ) == N ); + + // + // Just assign. + // + x = op.x; + x = op; + } + + // + /// The destructor. + // + ~xmm128() + {} + +// Interface +public: + + // + /// Assign our kind. + // + xmm128& operator= ( const xmm128& op ) + { + x = op.x; + return *this; + } + + // + /// Assign the xmm type. + // + xmm128& operator= ( const MY_XMM& op ) + { + x = op; + return *this; + } + + // + /// Operator to get packed type. The const version. + // + operator MY_XMM () const + { + return x; + } + + // + /// Operator to get packed type reference. Can be used as a lvalue. + // + MY_TYPE& operator[] ( int idx ) + { + assert( 0<= idx && idx < N ); + return n[idx]; + } + + // + /// Operator to get packed type. The const version. + // + MY_TYPE operator[] ( int idx ) const + { + assert( 0<= idx && idx < N ); + return n[idx]; + } + + // + /// Set from two values. + // + void set( MY_TYPE v1, MY_TYPE v2 ) + { + BOOST_STATIC_ASSERT( 16 / sizeof( MY_TYPE ) == 2 ); + operator[0] = v1; + operator[1] = v2; + } + + // + /// Set from two values. + // + void set( MY_TYPE v1, MY_TYPE v2, MY_TYPE v2, MY_TYPE v4 ) + { + BOOST_STATIC_ASSERT( 16 / sizeof( MY_TYPE ) == 4 ); + operator[0] = v1; + operator[1] = v2; + operator[2] = v3; + operator[3] = v4; + } + + add + sub + andnot + and + or + xor + + sqrt + mul + div + min + max + + shift + + comp +}; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + +/* +class xmm128d : public xmm128 < rxmm128d, double, 2 > +{ +// Construction +public: + + // + /// The default constructor. + // + xmm128d() + {} + + // + /// The copy constructor. + // + xmm128d( const xmm128d& op ) + : xmm128( op ) + {} + + // + /// The copy constructor. + // + xmm128d( const MY_XMM& op ) + : xmm128( op ) + {} + + // + /// The copy constructor. + // + xmm128d( double d1, double d2 ) + { + set( d1, d2 ); + } + + +// Interface +public: + + // + /// Set from two doubles. + // + void set( double d1, double d2 ) + { + operator[0] = d1; + operator[1] = d2; + } +}; +*/ + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_H_*/ diff --git a/SSE_cmplr_abstraction_GCC.h b/SSE_cmplr_abstraction_GCC.h new file mode 100644 index 0000000..7fdab22 --- /dev/null +++ b/SSE_cmplr_abstraction_GCC.h @@ -0,0 +1,60 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_GCC_H_ +#define _SSE2_CMPL_ABSTRACTION_GCC_H_ + +#include + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +// Primitive types +// + +/// 2xdouble +// +typedef int xmm128d __attribute__ ((mode(V2DF))); + +/// 4xfloat +// +typedef int xmm128s __attribute__ ((mode(V4SF))); + +/// 2xint64 +// +typedef int xmm128l __attribute__ ((mode(V4SF))); + +/// 4xint32 +// +typedef int xmm128i __attribute__ ((mode(V4SF))); + +/// int64 +// +typedef long int; + +// +// Namespace sse2 +// +} + +#include "SSE_cmplr_abstraction_GCC_pckdbl.h" +#include "SSE_cmplr_abstraction_GCC_pckfloat.h" +#include "SSE_cmplr_abstraction_GCC_pckint8.h" +#include "SSE_cmplr_abstraction_GCC_pckint16.h" +#include "SSE_cmplr_abstraction_GCC_pckint32.h" +#include "SSE_cmplr_abstraction_GCC_pckint64.h" + +#endif/*_SSE2_CMPL_ABSTRACTION_GCC_H_*/ diff --git a/SSE_cmplr_abstraction_MSC.h b/SSE_cmplr_abstraction_MSC.h new file mode 100644 index 0000000..40389ae --- /dev/null +++ b/SSE_cmplr_abstraction_MSC.h @@ -0,0 +1,61 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_H_ + +#include +#include + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +// Primitive types +// + +/// 2xdouble +// +typedef __m128d rxmm128d; + +/// 4xfloat +// +typedef __m128 rxmm128s; + +/// 2xint64 +// +typedef __m128i rxmm128l; + +/// 4xint32 +// +typedef __m128 rxmm128i; + +/// int64 +// +typedef __int64 int64; + +// +// Namespace sse2 +// +} + +#include "SSE_cmplr_abstraction_MSC_pckdbl.h" +#include "SSE_cmplr_abstraction_MSC_pckfloat.h" +#include "SSE_cmplr_abstraction_MSC_pckint8.h" +#include "SSE_cmplr_abstraction_MSC_pckint16.h" +#include "SSE_cmplr_abstraction_MSC_pckint32.h" +#include "SSE_cmplr_abstraction_MSC_pckint64.h" + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_backup.h b/SSE_cmplr_abstraction_MSC_backup.h new file mode 100644 index 0000000..f33b492 --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_backup.h @@ -0,0 +1,895 @@ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_H_ + +#include +#include + +// +// Namespace sse2 +// +namespace sse2 +{ + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +// Primitive types +// + +/// 2xdouble +// +typedef __m128d rxmm128d; + +/// 4xfloat +// +typedef __m128 rxmm128s; + +/// 2xint64 +// +typedef __m128i rxmm128l; + +/// 4xint32 +// +typedef __m128 rxmm128i; + +/// int64 +// +typedef __int64 int64; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double arithmetic +// +class arithmetic_pd +{ +public: + /*! + r0 := a0 + b0 + r1 := a1 + b1 + */ + static inline rxmm128d add( rxmm128d a, rxmm128d b ) + { + return _mm_add_pd( a, b ); + } + + /*! + r0 := a0 - b0 + r1 := a1 - b1 + */ + static inline rxmm128d sub( rxmm128d a, rxmm128d b ) + { + return _mm_sub_pd( a, b ); + } + + /*! + r0 := a0 * b0 + r1 := a1 * b1 + */ + static inline rxmm128d mul( rxmm128d a, rxmm128d b ) + { + return _mm_mul_pd( a, b ); + } + + /*! + r0 := a0 / b0 + r1 := a1 / b1 + */ + static inline rxmm128d div( rxmm128d a, rxmm128d b ) + { + return _mm_div_pd( a, b ); + } + + /*! + r0 := max( a0, b0 ) + r1 := max( a1, b1 ) + */ + static inline rxmm128d max( rxmm128d a, rxmm128d b ) + { + return _mm_max_pd( a, b ); + } + + /*! + r0 := min( a0, b0 ) + r1 := min( a1, b1 ) + */ + static inline rxmm128d min( rxmm128d a, rxmm128d b ) + { + return _mm_min_pd( a, b ); + } + + /*! + r0 := sqrt( a0 ) + r1 := sqrt( a1 ) + */ + static inline rxmm128d sqrt( rxmm128d a ) + { + return _mm_sqrt_pd( a, b ); + } +}; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// +class logic_pd +{ +public: + /*! + r0 := (~a0) & b0 + r1 := (~a1) & b1 + */ + static inline rxmm128d andnot( rxmm128d a, rxmm128d b ) + { + return _mm_andnot_pd( a, b ); + } + + /*! + r0 := a0 & b0 + r1 := a1 & b1 + */ + static inline XMM_TYPE and( rxmm128d a, rxmm128d b ) + { + return _mm_and_pd( a, b ); + } + + /*! + r0 := a0 | b0 + r1 := a1 | b1 + */ + static inline XMM_TYPE or( rxmm128d a, rxmm128d b ) + { + return _mm_or_pd( a, b ); + } + + /*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 + */ + static inline XMM_TYPE xor( rxmm128d a, rxmm128d b ) + { + return _mm_xor_pd( a, b ); + } +}; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double comparision +// +class comparision_pd +{ +public: + /*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_eq( rxmm128d a, rxmm128d b ) + { + return _mm_cmpeq_pd( a, b ); + } + + /*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_neq( rxmm128d a, rxmm128d b ) + { + return _mm_cmpneq_pd( a, b ); + } + + /*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_lt( rxmm128d a, rxmm128d b ) + { + return _mm_cmplt_pd( a, b ); + } + + /*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_le( rxmm128d a, rxmm128d b ) + { + return _mm_cmple_pd( a, b ); + } + + /*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_gt( rxmm128d a, rxmm128d b ) + { + return _mm_cmpgt_pd( a, b ); + } + + /*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_ge( rxmm128d a, rxmm128d b ) + { + return _mm_cmpge_pd( a, b ); + } + + /*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_ord( rxmm128d a, rxmm128d b ) + { + return _mm_cmpord_pd( a, b ); + } + + /*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffffffffffff : 0x0 + */ + static inline rxmm128d cmp_unord( rxmm128d a, rxmm128d b ) + { + return _mm_cmpunord_pd( a, b ); + } + +}; + + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// +class logic_pd +{ +public: +}; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// +class logic_pd +{ +public: +}; + + + + + +/// Abstract +// +class func_d64x2 +{ +public: + typedef XMM_TYPE rxmm128d; + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Arithmetic PD + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Arithmetic SD + + /*! + r0 := a0 + b0 + r1 := a1 + */ + static inline XMM_TYPE addsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_add_sd( a, b ); + } + + /*! + r0 := a0 - b0 + r1 := a1 + */ + static inline XMM_TYPE subsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_sub_sd( a, b ); + } + + /*! + r0 := a0 * b0 + r1 := a1 + */ + static inline XMM_TYPE mulsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_mul_sd( a, b ); + } + + /*! + r0 := a0 / b0 + r1 := a1 + */ + static inline XMM_TYPE divsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_div_sd( a, b ); + } + + /*! + r0 := max( a0, b0 ) + r1 := a1 + */ + static inline XMM_TYPE maxsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_max_sd( a, b ); + } + + /*! + r0 := min( a0, b0 ) + r1 := a1 + */ + static inline XMM_TYPE minsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_min_sd( a, b ); + } + + /*! + r0 := sqrt( b0 ) + r1 := a1 + */ + static inline XMM_TYPE sqrtsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_sqrt_sd( a, b ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Logic PD + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Comparision PD + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Comparision SD + + /*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpeqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpeq_sd( a, b ); + } + + /*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpneqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpneq_sd( a, b ); + } + + /*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpltsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmplt_sd( a, b ); + } + + /*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmplesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmple_sd( a, b ); + } + + /*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpgtsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpgt_sd( a, b ); + } + + /*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpgesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpge_sd( a, b ); + } + + /*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpordsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpord_sd( a, b ); + } + + /*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := a1 + */ + static inline XMM_TYPE cmpunordsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_cmpunord_sd( a, b ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Comparision SD + + /*! + r := (a0 == b0) ? 0x1 : 0x0 + */ + static inline int comieqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comieq_sd( a, b ); + } + + /*! + r := (a0 != b0) ? 0x1 : 0x0 + */ + static inline int comineqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comineq_sd( a, b ); + } + + /*! + r := (a0 < b0) ? 0x1 : 0x0 + */ + static inline int comiltsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comilt_sd( a, b ); + } + + /*! + r := (a0 <= b0) ? 0x1 : 0x0 + */ + static inline int comilesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comile_sd( a, b ); + } + + /*! + r := (a0 > b0) ? 0x1 : 0x0 + */ + static inline int comigtsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comigt_sd( a, b ); + } + + /*! + r := (a0 >= b0) ? 0x1 : 0x0 + */ + static inline int comigesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_comige_sd( a, b ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Comparision SD + + /*! + r := (a0 == b0) ? 0x1 : 0x0 + */ + static inline int ucomieqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomieq_sd( a, b ); + } + + /*! + r := (a0 != b0) ? 0x1 : 0x0 + */ + static inline int ucomineqsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomineq_sd( a, b ); + } + + /*! + r := (a0 < b0) ? 0x1 : 0x0 + */ + static inline int ucomiltsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomilt_sd( a, b ); + } + + /*! + r := (a0 <= b0) ? 0x1 : 0x0 + */ + static inline int ucomilesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomile_sd( a, b ); + } + + /*! + r := (a0 > b0) ? 0x1 : 0x0 + */ + static inline int ucomigtsd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomigt_sd( a, b ); + } + + /*! + r := (a0 >= b0) ? 0x1 : 0x0 + */ + static inline int ucomigesd( XMM_TYPE a, XMM_TYPE b ) + { + return _mm_ucomige_sd( a, b ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Conversion + + /*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 + */ + static inline rxmm128s cvtpd2ps( rxmm128d a ) + { + return _mm_cvtpd_ps( a ); + } + + /*! + r0 := (double) a0 + r1 := (double) a1 + */ + static inline rxmm128d cvtps2pd( rxmm128s a ) + { + return _mm_cvtps_pd( a ); + } + + /*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 + */ + static inline rxmm128l cvtpd2dq( rxmm128d a ) + { + return _mm_cvtpd_epi32( a ); + } + + /*! + r0 := (double) a0 + r1 := (double) a1 + */ + static inline rxmm128d cvtdq2pd( rxmm128l a ) + { + return _mm_cvtepi32_pd( a ); + } + + /*! + r := (int) a0 + */ + static inline int cvtsd2si( rxmm128d a ) + { + return _mm_cvtsd_si32( a ); + } + + /*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 + */ + static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128d b ) + { + return _mm_cvtsd_ss( a, b ); + } + + /*! + r0 := (double) b + r1 := a1 + */ + static inline rxmm128d cvtsi2sd( rxmm128d a, int b ) + { + return _mm_cvtsi32_sd( a, b ); + } + + /*! + r0 := (double) b0 + r1 := a1 + */ + static inline rxmm128d cvtss2sd( rxmm128d a, rxmm128s b ) + { + return _mm_cvtss_sd( a, b ); + } + + /*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 + */ + static inline rxmm128l cvttpd2dq( rxmm128d a ) + { + return _mm_cvttpd_epi32( a ); + } + + /*! + using truncate + r := (int) a0 + */ + static inline int cvttsd2si( rxmm128d a ) + { + return _mm_cvttsd_si32( a ); + } + + /*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 + */ + static inline rxmm128s cvtdq2ps( rxmm128l a ) + { + return _mm_cvtepi32_ps( a ); + } + + /*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 + */ + static inline rxmm128l cvtps2dq( rxmm128s a ) + { + return _mm_cvtps_epi32( a ); + } + + /*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 + */ + static inline rxmm128l cvttps2dq( rxmm128s a ) + { + return _mm_cvttps_epi32( a ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Misc + + /*! + r0 := a1 + r1 := b1 + */ + static inline rxmm128d unpckhpd( rxmm128d a, rxmm128d b ) + { + return _mm_unpackhi_pd( a, b ); + } + + /*! + r0 := a0 + r1 := b0 + */ + static inline rxmm128d unpcklpd( rxmm128d a, rxmm128d b ) + { + return _mm_unpacklo_pd( a, b ); + } + + /*! + r := sign(a1) << 1 | sign(a0) + */ + static inline int movmskpd( rxmm128d a, rxmm128d b ) + { + return _mm_movemask_pd( a, b ); + } + + /*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + */ + static inline int shuffle_pd( rxmm128d a, rxmm128d b, int i ) + { + return _mm_shuffle_pd( a, b, i ); + } + + /*! + == shuffle_pd( a, b, 1 ) + r0 := b0 + r1 := a1 + */ + static inline rxmm128d move_sd( rxmm128d a, rxmm128d b ) + { + return _mm_move_sd( a0 ); + } + + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Memory load + + /*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] + */ + static inline rxmm128d load_pd( double * p ) + { + return _mm_load_pd( p ); + } + + /*! + The address \arg p must be 16-byte aligned. + r0 := p[1] + r1 := p[0] + */ + static inline rxmm128d load_pd_reverse( double * p ) + { + return _mm_loadr_pd( p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] + */ + static inline rxmm128d load_pd_unaligned( double * p ) + { + return _mm_loadu_pd( p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := *p + */ + static inline rxmm128d load_pd_hi( rxmm128d a, double * p ) + { + return _mm_loadh_pd( a, p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := a1 + */ + static inline rxmm128d load_pd_lo( rxmm128d a, double * p ) + { + return _mm_loadl_pd( a, p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p + */ + static inline rxmm128d load_pd_both( double * p ) + { + return _mm_load1_pd( p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 + */ + static inline rxmm128d load_sd( double * p ) + { + return _mm_load_sd( p ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Memory store + + /*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 + */ + static inline void store_pd( double * p, rxmm128d a ) + { + _mm_load_pd( p, a ); + } + + /*! + The address \arg p must be 16-byte aligned. + p[0] := a1 + p[1] := a0 + */ + static inline void store_pd_reverse( double * p, rxmm128d a ) + { + _mm_storer_pd( p, a ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 + */ + static inline void store_pd_unaligned(double * p, rxmm128d a ) + { + _mm_storeu_pd( p, a ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + *p := a1 + */ + static inline void store_pd_hi( double * p, rxmm128d a ) + { + _mm_storeh_pd( p, a ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 + */ + static inline void store_pd_lo( double * p, rxmm128d a ) + { + _mm_storel_pd( p, a ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 + */ + static inline void store_pd_both( double * p, rxmm128d a ) + { + return _mm_store1_pd( p ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 + */ + static inline void store_sd( double * p, rxmm128d a ) + { + return _mm_store_sd( p ); + } + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ + // Memory set + + /*! + r0 := a0 + r1 := a1 + */ + static inline rxmm128d set_pd( double a1, double a0 ) + { + return _mm_set_pd( a1, a0 ); + } + + /*! + r0 := 0.0 + r1 := 0.0 + */ + static inline rxmm128d set_pd_zero() + { + return _mm_setzero_pd( a0 ); + } + + /*! + r0 := a0 + r1 := a0 + */ + static inline rxmm128d set_pd_both( double a0) + { + return _mm_set1_pd( a0 ); + } + + /*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 + */ + static inline rxmm128d set_sd( double a0 ) + { + return _mm_set_sd( a0 ); + } +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckdbl.h b/SSE_cmplr_abstraction_MSC_pckdbl.h new file mode 100644 index 0000000..a48e3ba --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckdbl.h @@ -0,0 +1,624 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKDBL_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKDBL_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class pd (packed double) +// +class pd +{ +public: + +// +/// The type. +// +typedef rxmm128d my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 +*/ +static inline rxmm128d add( rxmm128d a, rxmm128d b ) +{ + return _mm_add_pd( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 +*/ +static inline rxmm128d sub( rxmm128d a, rxmm128d b ) +{ + return _mm_sub_pd( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 +*/ +static inline rxmm128d mul( rxmm128d a, rxmm128d b ) +{ + return _mm_mul_pd( a, b ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 +*/ +static inline rxmm128d div( rxmm128d a, rxmm128d b ) +{ + return _mm_div_pd( a, b ); +} + +/*! + r0 := max( a0, b0 ) + r1 := max( a1, b1 ) +*/ +static inline rxmm128d max( rxmm128d a, rxmm128d b ) +{ + return _mm_max_pd( a, b ); +} + +/*! + r0 := min( a0, b0 ) + r1 := min( a1, b1 ) +*/ +static inline rxmm128d min( rxmm128d a, rxmm128d b ) +{ + return _mm_min_pd( a, b ); +} + +/*! + r0 := sqrt( a0 ) + r1 := sqrt( a1 ) +*/ +static inline rxmm128d sqrt( rxmm128d a ) +{ + return _mm_sqrt_pd( a ); +} + +/*! + r0 := recip(a0) + r1 := recip(a1) +*/ +static inline rxmm128d rcp( rxmm128d a ) +{ + rxmm128d t = _mm_set1_pd( 1.0 ); + return _mm_div_pd( t, a ); +} + +/*! + r0 := recip(sqrt(a0)) + r1 := recip(sqrt(a1)) +*/ +static inline rxmm128d rsqrt( rxmm128d a ) +{ + rxmm128d t = _mm_set1_pd( 1.0 ); + rxmm128d u = _mm_sqrt_pd( a ); + return _mm_div_pd( t, u ); +} +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// + +/*! + r0 := (~a0) & b0 + r1 := (~a1) & b1 +*/ +static inline rxmm128d andnot( rxmm128d a, rxmm128d b ) +{ + return _mm_andnot_pd( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128d a, rxmm128d b ) +{ + return _mm_and_pd( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128d a, rxmm128d b ) +{ + return _mm_or_pd( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 +*/ +static inline XMM_TYPE xor( rxmm128d a, rxmm128d b ) +{ + return _mm_xor_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_eq( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpeq_pd( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_neq( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpneq_pd( a, b ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_lt( rxmm128d a, rxmm128d b ) +{ + return _mm_cmplt_pd( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_le( rxmm128d a, rxmm128d b ) +{ + return _mm_cmple_pd( a, b ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_gt( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpgt_pd( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ge( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpge_pd( a, b ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpord_pd( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_unord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpunord_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a1 + r1 := b1 +*/ +static inline rxmm128d unpckh( rxmm128d a, rxmm128d b ) +{ + return _mm_unpackhi_pd( a, b ); +} + +/*! + r0 := a0 + r1 := b0 +*/ +static inline rxmm128d unpckl( rxmm128d a, rxmm128d b ) +{ + return _mm_unpacklo_pd( a, b ); +} + +/*! + r := sign(a1) << 1 | sign(a0) +*/ +static inline int movmsk( rxmm128d a, rxmm128d b ) +{ + return _mm_movemask_pd( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + \sa movmsk +*/ +static inline int shuffle( rxmm128d a, rxmm128d b, int i ) +{ + return _mm_shuffle_pd( a, b, i ); +} + +/*! + == shuffle( a, b, 1 ) + r0 := b0 + r1 := a1 +*/ +static inline rxmm128d move_sd( rxmm128d a, rxmm128d b ) +{ + return _mm_move_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load( double * p ) +{ + return _mm_load_pd( p ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[1] + r1 := p[0] +*/ +static inline rxmm128d load_reverse( double * p ) +{ + return _mm_loadr_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load_unaligned( double * p ) +{ + return _mm_loadu_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := *p +*/ +static inline rxmm128d load_hi( rxmm128d a, double * p ) +{ + return _mm_loadh_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := a1 +*/ +static inline rxmm128d load_lo( rxmm128d a, double * p ) +{ + return _mm_loadl_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p +*/ +static inline rxmm128d load_both( double * p ) +{ + return _mm_load1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 +*/ +static inline rxmm128d load_s( double * p ) +{ + return _mm_load_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store( double * p, rxmm128d a ) +{ + _mm_store_pd( p, a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a1 + p[1] := a0 +*/ +static inline void store_reverse( double * p, rxmm128d a ) +{ + _mm_storer_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store_unaligned(double * p, rxmm128d a ) +{ + _mm_storeu_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a1 +*/ +static inline void store_hi( double * p, rxmm128d a ) +{ + _mm_storeh_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_lo( double * p, rxmm128d a ) +{ + _mm_storel_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( double * p, rxmm128d a ) +{ + return _mm_store1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_s( double * p, rxmm128d a ) +{ + return _mm_store_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 +*/ +static inline rxmm128d set( double a1, double a0 ) +{ + return _mm_set_pd( a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 +*/ +static inline rxmm128d set_zero() +{ + return _mm_setzero_pd( a0 ); +} + +/*! + r0 := a0 + r1 := a0 +*/ +static inline rxmm128d set_both( double a0 ) +{ + return _mm_set1_pd( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 +*/ +static inline rxmm128d set_s( double a0 ) +{ + return _mm_set_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s cvtpd2ps( rxmm128d a ) +{ + return _mm_cvtpd_ps( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtps2pd( rxmm128s a ) +{ + return _mm_cvtps_pd( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128d a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_pd( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128d a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128d b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128d cvtsi2sd( rxmm128d a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128d cvtss2sd( rxmm128d a, rxmm128s b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128d a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128d a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128s cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128s a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128s a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class pd +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKDBL_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckfloat.h b/SSE_cmplr_abstraction_MSC_pckfloat.h new file mode 100644 index 0000000..9750f50 --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckfloat.h @@ -0,0 +1,667 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKFLOAT_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKFLOAT_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class ps (packed single precision) +// +class ps +{ +public: + +// +/// The type. +// +typedef rxmm128s my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 + r2 := a2 + b2 + r3 := a3 + b3 +*/ +static inline rxmm128s add( rxmm128s a, rxmm128s b ) +{ + return _mm_add_ps( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 + r2 := a2 - b2 + r3 := a3 - b3 +*/ +static inline rxmm128s sub( rxmm128s a, rxmm128s b ) +{ + return _mm_sub_ps( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 + r2 := a2 * b2 + r3 := a3 * b3 +*/ +static inline rxmm128s mul( rxmm128s a, rxmm128s b ) +{ + return _mm_mul_ps( a, b ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 + r2 := a2 / b2 + r3 := a3 / b3 +*/ +static inline rxmm128s div( rxmm128s a, rxmm128s b ) +{ + return _mm_div_ps( a, b ); +} + +/*! + r0 := max(a0, b0) + r1 := max(a1, b1) + r2 := max(a2, b2) + r3 := max(a3, b3) +*/ +static inline rxmm128s max( rxmm128s a, rxmm128s b ) +{ + return _mm_max_ps( a, b ); +} + +/*! + r0 := min(a0, b0) + r1 := min(a1, b1) + r2 := min(a2, b2) + r3 := min(a3, b3) +*/ +static inline rxmm128s min( rxmm128s a, rxmm128s b ) +{ + return _mm_min_ps( a, b ); +} + +/*! + r0 := sqrt(a0) + r1 := sqrt(a1) + r2 := sqrt(a2) + r3 := sqrt(a3) +*/ +static inline rxmm128s sqrt( rxmm128s a ) +{ + return _mm_sqrt_ps( a ); +} + +/*! + r0 := recip(a0) + r1 := recip(a1) + r2 := recip(a2) + r3 := recip(a3) +*/ +static inline rxmm128s rcp( rxmm128s a ) +{ + return _mm_rcp_ps( a ); +} + +/*! + r0 := recip(sqrt(a0)) + r1 := recip(sqrt(a1)) + r2 := recip(sqrt(a2)) + r3 := recip(sqrt(a3)) +*/ +static inline rxmm128s rsqrt( rxmm128s a ) +{ + return _mm_rsqrt_ps( a ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// + +/*! + r0 := ~a0 & b0 + r1 := ~a1 & b1 + r2 := ~a2 & b2 + r3 := ~a3 & b3 +*/ +static inline rxmm128s andnot( rxmm128s a, rxmm128s b ) +{ + return _mm_andnot_ps( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128s a, rxmm128s b ) +{ + return _mm_and_ps( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128s a, rxmm128s b ) +{ + return _mm_or_ps( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 + r2 := a2 ^ b2 + r3 := a3 ^ b3 +*/ +static inline XMM_TYPE xor( rxmm128s a, rxmm128s b ) +{ + return _mm_xor_ps( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffff : 0x0 + r2 := (a2 == b2) ? 0xffffffff : 0x0 + r3 := (a3 == b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_eq( rxmm128s a, rxmm128s b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpeq_ps( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffff : 0x0 + r2 := (a2 != b2) ? 0xffffffff : 0x0 + r3 := (a3 != b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_neq( rxmm128s a, rxmm128s b ) +{ + return _mm_cmpneq_ps( a, b ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffff : 0x0 + r2 := (a2 < b2) ? 0xffffffff : 0x0 + r3 := (a3 < b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_lt( rxmm128s a, rxmm128s b ) +{ + return _mm_cmplt_ps( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffff : 0x0 + r2 := (a2 <= b2) ? 0xffffffff : 0x0 + r3 := (a3 <= b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_le( rxmm128s a, rxmm128s b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmple_ps( a, b ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffff : 0x0 + r2 := (a2 > b2) ? 0xffffffff : 0x0 + r3 := (a3 > b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_gt( rxmm128s a, rxmm128s b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpgt_ps( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffff : 0x0 + r2 := (a2 >= b2) ? 0xffffffff : 0x0 + r3 := (a3 >= b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_ge( rxmm128s a, rxmm128s b ) +{ + return _mm_cmpge_ps( a, b ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffff : 0x0 + r2 := (a2 ord b2) ? 0xffffffff : 0x0 + r3 := (a3 ord b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_ord( rxmm128s a, rxmm128s b ) +{ + return _mm_cmpord_ps( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffff : 0x0 + r2 := (a2 unord b2) ? 0xffffffff : 0x0 + r3 := (a3 unord b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128s cmp_unord( rxmm128s a, rxmm128s b ) +{ + return _mm_cmpunord_ps( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a2 + r1 := b2 + r2 := a3 + r3 := b3 +*/ +static inline rxmm128s unpckh( rxmm128s a, rxmm128s b ) +{ + return _mm_unpackhi_ps( a, b ); +} + +/*! + r0 := a0 + r1 := b0 + r2 := a1 + r3 := b1 +*/ +static inline rxmm128s unpckl( rxmm128s a, rxmm128s b ) +{ + return _mm_unpacklo_ps( a, b ); +} + +/*! + r := sign(a3)<<3 | sign(a2)<<2 | sign(a1)<<1 | sign(a0) +*/ +static inline int movmsk( rxmm128s a, rxmm128s b ) +{ + return _mm_movemask_ps( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + r2 := (i2 == 1) ? b2 : a2 + r3 := (i3 == 1) ? b3 : a3 + \sa movmsk +*/ +static inline int shuffle( rxmm128s a, rxmm128s b, int i ) +{ + return _mm_shuffle_ps( a, b, i ); +} + +/*! + r3 := a3 + r2 := a2 + r1 := b3 + r0 := b2 +*/ +static inline rxmm128s move_hl( rxmm128s a, rxmm128s b ) +{ + return mm_movehl_ps( a0 ); +} + +/*! + r3 := b1 + r2 := b0 + r1 := a1 + r0 := a0 +*/ +static inline rxmm128s move_lh( rxmm128s a, rxmm128s b ) +{ + return _mm_movelh_ps( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] + r2 := p[2] + r3 := p[3] +*/ +static inline rxmm128s load( float * p ) +{ + return _mm_load_ps( p ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[3] + r1 := p[2] + r2 := p[1] + r3 := p[0] +*/ +static inline rxmm128s load_reverse( float * p ) +{ + return _mm_loadr_ps( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] + r2 := p[2] + r3 := p[3] +*/ +static inline rxmm128s load_unaligned( float * p ) +{ + return _mm_loadu_ps( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p + r2 := *p + r3 := *p +*/ +static inline rxmm128s load_both( float * p ) +{ + return _mm_load1_ps( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s load_s( float * p ) +{ + return _mm_load_ss( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 + p[2] := a2 + p[3] := a3 +*/ +static inline void store( float * p, rxmm128s a ) +{ + _mm_store_ps( p, a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a3 + p[1] := a2 + p[2] := a1 + p[3] := a0 +*/ +static inline void store_reverse( float * p, rxmm128s a ) +{ + _mm_storer_ps( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 + p[2] := a2 + p[3] := a3 +*/ +static inline void store_unaligned(float * p, rxmm128s a ) +{ + _mm_storeu_ps( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( float * p, rxmm128s a ) +{ + return _mm_store1_ps( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_s( float * p, rxmm128s a ) +{ + return _mm_store_ss( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s set( float a3, float a2, float a1, float a0 ) +{ + return _mm_set_ps( a3, a2, a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s set_zero() +{ + return _mm_setzero_ps( a0 ); +} + +/*! + r0 := a0 + r1 := a0 + r2 := a0 + r3 := a0 +*/ +static inline rxmm128s set_both( float a0 ) +{ + return _mm_set1_ps( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s set_s( float a0 ) +{ + return _mm_set_ss( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s cvtpd2ps( rxmm128s a ) +{ + return _mm_cvtpd_ps( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128s cvtps2pd( rxmm128s a ) +{ + return _mm_cvtps_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128s a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128s cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128s a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128s b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128s cvtsi2sd( rxmm128s a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128s cvtss2sd( rxmm128s a, rxmm128s b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128s a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128s a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128s cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128s a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128s a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class ps +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKFLOAT_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckint16.h b/SSE_cmplr_abstraction_MSC_pckint16.h new file mode 100644 index 0000000..438ba1a --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckint16.h @@ -0,0 +1,618 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKINT16_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKINT16_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class epi64 (packed single precision) +// +class epi64 +{ +public: + +// +/// The type. +// +typedef rxmm128l my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 +*/ +static inline rxmm128d add( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_add_pd( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 +*/ +static inline rxmm128d sub( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sub_pd( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 +*/ +static inline rxmm128d mul( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_mul_pd( a, b ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 +*/ +static inline rxmm128d div( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_div_pd( a, b ); +} + +/*! + r0 := max( a0, b0 ) + r1 := max( a1, b1 ) +*/ +static inline rxmm128d max( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_max_pd( a, b ); +} + +/*! + r0 := min( a0, b0 ) + r1 := min( a1, b1 ) +*/ +static inline rxmm128d min( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_min_pd( a, b ); +} + +/*! + r0 := sqrt( a0 ) + r1 := sqrt( a1 ) +*/ +static inline rxmm128d sqrt( rxmm128d a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sqrt_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer logic +// + +/*! + r0 := (~a0) & b0 + r1 := (~a1) & b1 +*/ +static inline rxmm128d andnot( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_andnot_pd( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_and_pd( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_or_pd( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 +*/ +static inline XMM_TYPE xor( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_xor_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_eq( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpeq_pd( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_neq( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpneq_pd( a, b ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_lt( rxmm128d a, rxmm128d b ) +{ + return _mm_cmplt_pd( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_le( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmple_pd( a, b ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_gt( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpgt_pd( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ge( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpge_pd( a, b ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpord_pd( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_unord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpunord_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a1 + r1 := b1 +*/ +static inline rxmm128d unpckh( rxmm128d a, rxmm128d b ) +{ + return _mm_unpackhi_pd( a, b ); +} + +/*! + r0 := a0 + r1 := b0 +*/ +static inline rxmm128d unpckl( rxmm128d a, rxmm128d b ) +{ + return _mm_unpacklo_pd( a, b ); +} + +/*! + r := sign(a1) << 1 | sign(a0) +*/ +static inline int movmsk( rxmm128d a, rxmm128d b ) +{ + return _mm_movemask_pd( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + \sa movmsk +*/ +static inline int shuffle( rxmm128d a, rxmm128d b, int i ) +{ + return _mm_shuffle_pd( a, b, i ); +} + +/*! + == shuffle( a, b, 1 ) + r0 := b0 + r1 := a1 +*/ +static inline rxmm128d move_sd( rxmm128d a, rxmm128d b ) +{ + return _mm_move_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load( double * p ) +{ + return _mm_load_pd( p ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[1] + r1 := p[0] +*/ +static inline rxmm128d load_reverse( double * p ) +{ + return _mm_loadr_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load_unaligned( double * p ) +{ + return _mm_loadu_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := *p +*/ +static inline rxmm128d load_hi( rxmm128d a, double * p ) +{ + return _mm_loadh_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := a1 +*/ +static inline rxmm128d load_lo( rxmm128d a, double * p ) +{ + return _mm_loadl_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p +*/ +static inline rxmm128d load_both( double * p ) +{ + return _mm_load1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 +*/ +static inline rxmm128d load_sd( double * p ) +{ + return _mm_load_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store( double * p, rxmm128d a ) +{ + _mm_load_pd( p, a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a1 + p[1] := a0 +*/ +static inline void store_reverse( double * p, rxmm128d a ) +{ + _mm_storer_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store_unaligned(double * p, rxmm128d a ) +{ + _mm_storeu_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a1 +*/ +static inline void store_hi( double * p, rxmm128d a ) +{ + _mm_storeh_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_lo( double * p, rxmm128d a ) +{ + _mm_storel_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( double * p, rxmm128d a ) +{ + return _mm_store1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_sd( double * p, rxmm128d a ) +{ + return _mm_store_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 +*/ +static inline rxmm128d set( double a1, double a0 ) +{ + return _mm_set_pd( a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 +*/ +static inline rxmm128d set_zero() +{ + return _mm_setzero_pd( a0 ); +} + +/*! + r0 := a0 + r1 := a0 +*/ +static inline rxmm128d set_both( double a0 ) +{ + return _mm_set1_pd( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 +*/ +static inline rxmm128d set_sd( double a0 ) +{ + return _mm_set_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s cvtpd2ps( rxmm128d a ) +{ + return _mm_cvtpd_ps( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtps2pd( rxmm128s a ) +{ + return _mm_cvtps_pd( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128d a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_pd( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128d a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128d b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128d cvtsi2sd( rxmm128d a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128d cvtss2sd( rxmm128d a, rxmm128s b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128d a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128d a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128s cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128s a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128s a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class epi64 +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKINT16_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckint32.h b/SSE_cmplr_abstraction_MSC_pckint32.h new file mode 100644 index 0000000..dceace4 --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckint32.h @@ -0,0 +1,676 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKINT32_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKINT32_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class epi64 (packed single precision) +// +class epi64 +{ +public: + +// +/// The type. +// +typedef rxmm128l my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 + r2 := a2 + b2 + r3 := a3 + b3 +*/ +static inline rxmm128l add( rxmm128l a, rxmm128l b ) +{ + return _mm_add_epi32( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 + r2 := a2 - b2 + r3 := a3 - b3 +*/ +static inline rxmm128l sub( rxmm128l a, rxmm128l b ) +{ + return _mm_sub_epi32( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 + r2 := a2 * b2 + r3 := a3 * b3 + \note Emulating through float. May be precision loss. +*/ +static inline rxmm128l mul( rxmm128l a, rxmm128l b ) +{ + register rxmm128s t = _mm_cvtepi32_ps( a ); + register rxmm128s u = _mm_cvtepi32_ps( b ); + register rxmm128s v = _mm_mul_ps( t, u ); + return _mm_cvtps_epi32( v ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 + r2 := a2 / b2 + r3 := a3 / b3 + \note Emulating through float. May be precision loss. +*/ +static inline rxmm128l div( rxmm128l a, rxmm128l b ) +{ + register rxmm128s t = _mm_cvtepi32_ps( a ); + register rxmm128s u = _mm_cvtepi32_ps( b ); + register rxmm128s v = _mm_div_ps( t, u ); + return _mm_cvtps_epi32( v ); +} + +/*! + r0 := max(a0, b0) + r1 := max(a1, b1) + r2 := max(a2, b2) + r3 := max(a3, b3) +*/ +static inline rxmm128l max( rxmm128l a, rxmm128l b ) +{ + register rxmm128l t = _mm_cmplt_epi32( a, b ); + int mask = _mm_movemask_epi8( t ); + _mm_shuffle_epi32 + BOOST_STATIC_ASSERT( false ); + return 0; +} + +/*! + r0 := min(a0, b0) + r1 := min(a1, b1) + r2 := min(a2, b2) + r3 := min(a3, b3) +*/ +static inline rxmm128l min( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return 0; +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double logic +// + +/*! + r0 := ~a0 + r1 := ~a1 + r2 := ~a2 + r3 := ~a3 +*/ +static inline rxmm128l not( rxmm128l a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_andnot_si128( a, b ); +} + +/*! + r0 := ~a0 & b0 + r1 := ~a1 & b1 + r2 := ~a2 & b2 + r3 := ~a3 & b3 +*/ +static inline rxmm128l andnot( rxmm128l a, rxmm128l b ) +{ + return _mm_andnot_si128( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128l a, rxmm128l b ) +{ + return _mm_and_si128( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128l a, rxmm128l b ) +{ + return _mm_or_si128( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 + r2 := a2 ^ b2 + r3 := a3 ^ b3 +*/ +static inline XMM_TYPE xor( rxmm128l a, rxmm128l b ) +{ + return _mm_xor_si128( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffff : 0x0 + r2 := (a2 == b2) ? 0xffffffff : 0x0 + r3 := (a3 == b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_eq( rxmm128l a, rxmm128l b ) +{ + return _mm_cmpeq_epi32( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffff : 0x0 + r2 := (a2 != b2) ? 0xffffffff : 0x0 + r3 := (a3 != b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_neq( rxmm128l a, rxmm128l b ) +{ + rxmm128l t = _mm_cmplt_epi32( a, b ); + rxmm128l u = _mm_cmpgt_epi32( a, b ); + return _mm_cmpor_si128( t, u ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffff : 0x0 + r2 := (a2 < b2) ? 0xffffffff : 0x0 + r3 := (a3 < b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_lt( rxmm128l a, rxmm128l b ) +{ + return _mm_cmplt_epi32( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffff : 0x0 + r2 := (a2 <= b2) ? 0xffffffff : 0x0 + r3 := (a3 <= b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_le( rxmm128l a, rxmm128l b ) +{ + rxmm128l t = _mm_cmplt_epi32( a, b ); + rxmm128l u = _mm_cmpeq_epi32( a, b ); + return _mm_cmpor_si128( t, u ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffff : 0x0 + r2 := (a2 > b2) ? 0xffffffff : 0x0 + r3 := (a3 > b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_gt( rxmm128l a, rxmm128l b ) +{ + return _mm_cmpgt_epi32( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffff : 0x0 + r2 := (a2 >= b2) ? 0xffffffff : 0x0 + r3 := (a3 >= b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_ge( rxmm128l a, rxmm128l b ) +{ + rxmm128l t = _mm_cmpgt_epi32( a, b ); + rxmm128l u = _mm_cmpeq_epi32( a, b ); + return _mm_cmpor_si128( t, u ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffff : 0x0 + r2 := (a2 ord b2) ? 0xffffffff : 0x0 + r3 := (a3 ord b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_ord( rxmm128l a, rxmm128l b ) +{ + return _mm_cmpord_epi32( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffff : 0x0 + r2 := (a2 unord b2) ? 0xffffffff : 0x0 + r3 := (a3 unord b3) ? 0xffffffff : 0x0 +*/ +static inline rxmm128l cmp_unord( rxmm128l a, rxmm128l b ) +{ + return _mm_cmpunord_epi32( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a1 + r1 := b2 + r2 := a3 + r3 := b3 +*/ +static inline rxmm128l unpckh( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_unpackhi_epi32( a, b ); +} + +/*! + r0 := a0 + r1 := b0 + r2 := a1 + r3 := b1 +*/ +static inline rxmm128l unpckl( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_unpacklo_epi32( a, b ); +} + +/*! + r := sign(a3)<<3 | sign(a2)<<2 | sign(a1)<<1 | sign(a0) +*/ +static inline int movmsk( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_movemask_epi32( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + r2 := (i2 == 1) ? b2 : a2 + r3 := (i3 == 1) ? b3 : a3 + \sa movmsk +*/ +static inline int shuffle( rxmm128l a, rxmm128l b, int i ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_shuffle_epi32( a, b, i ); +} + +/*! + r3 := a3 + r2 := a2 + r1 := b3 + r0 := b2 +*/ +static inline rxmm128l move_hl( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return mm_movehl_epi32( a0 ); +} + +/*! + r3 := b1 + r2 := b0 + r1 := a1 + r0 := a0 +*/ +static inline rxmm128l move_lh( rxmm128l a, rxmm128l b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_movelh_epi32( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] + r2 := p[2] + r3 := p[3] +*/ +static inline rxmm128l load( int * p ) +{ + return _mm_load_epi32( reinterpret_cast<__m128i*>(p) ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[3] + r1 := p[2] + r2 := p[1] + r3 := p[0] +*/ +static inline rxmm128l load_reverse( int * p ) +{ + BOOST_STATIC_ASSERT( false ); + rxmm128l t = _mm_loadr_epi32( reinterpret_cast<__m128i*>(p) ) + return _mm_loadr_epi32( reinterpret_cast<__m128i*>(p) ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] + r2 := p[2] + r3 := p[3] +*/ +static inline rxmm128l load_unaligned( int * p ) +{ + return _mm_loadu_epi32( reinterpret_cast<__m128i*>(p) ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p + r2 := *p + r3 := *p +*/ +static inline rxmm128l load_both( int * p ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_load1_epi32( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l load_s( int * p ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_load_ss( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 + p[2] := a2 + p[3] := a3 +*/ +static inline void store( int * p, rxmm128l a ) +{ + _mm_store_si128( reinterpret_cast<__m128i*>(p), a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a3 + p[1] := a2 + p[2] := a1 + p[3] := a0 +*/ +static inline void store_reverse( int * p, rxmm128l a ) +{ + BOOST_STATIC_ASSERT( false ); + _mm_storer_epi32( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 + p[2] := a2 + p[3] := a3 +*/ +static inline void store_unaligned(int * p, rxmm128l a ) +{ + _mm_storeu_si128( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( int * p, rxmm128l a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_store1_epi32( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_s( int * p, rxmm128l a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_store_ss( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128l set( int a3, int a2, int a1, int a0 ) +{ + return _mm_set_epi32( a3, a2, a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l set_zero() +{ + return _mm_setzero_si32( a0 ); +} + +/*! + r0 := a0 + r1 := a0 + r2 := a0 + r3 := a0 +*/ +static inline rxmm128l set_both( int a0 ) +{ + return _mm_set1_epi32( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l set_s( int a0 ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_set_ss( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed double convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2ps( rxmm128l a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128l cvtps2pd( rxmm128l a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128l a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128l cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_epi32( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128l a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128l cvtsd2ss( rxmm128l a, rxmm128l b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128l cvtsi2sd( rxmm128l a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128l cvtss2sd( rxmm128l a, rxmm128l b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128l a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128l a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128l cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_epi32( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128l a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128l a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class epi64 +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKINT32_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckint64.h b/SSE_cmplr_abstraction_MSC_pckint64.h new file mode 100644 index 0000000..d9f6210 --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckint64.h @@ -0,0 +1,618 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKINT64_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKINT64_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class epi64 (packed single precision) +// +class epi64 +{ +public: + +// +/// The type. +// +typedef rxmm128l my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 +*/ +static inline rxmm128d add( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_add_pd( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 +*/ +static inline rxmm128d sub( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sub_pd( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 +*/ +static inline rxmm128d mul( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_mul_pd( a, b ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 +*/ +static inline rxmm128d div( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_div_pd( a, b ); +} + +/*! + r0 := max( a0, b0 ) + r1 := max( a1, b1 ) +*/ +static inline rxmm128d max( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_max_pd( a, b ); +} + +/*! + r0 := min( a0, b0 ) + r1 := min( a1, b1 ) +*/ +static inline rxmm128d min( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_min_pd( a, b ); +} + +/*! + r0 := sqrt( a0 ) + r1 := sqrt( a1 ) +*/ +static inline rxmm128d sqrt( rxmm128d a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sqrt_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer logic +// + +/*! + r0 := (~a0) & b0 + r1 := (~a1) & b1 +*/ +static inline rxmm128d andnot( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_andnot_pd( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_and_pd( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_or_pd( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 +*/ +static inline XMM_TYPE xor( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_xor_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_eq( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpeq_pd( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_neq( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpneq_pd( a, b ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_lt( rxmm128d a, rxmm128d b ) +{ + return _mm_cmplt_pd( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_le( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmple_pd( a, b ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_gt( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpgt_pd( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ge( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpge_pd( a, b ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpord_pd( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_unord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpunord_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a1 + r1 := b1 +*/ +static inline rxmm128d unpckh( rxmm128d a, rxmm128d b ) +{ + return _mm_unpackhi_pd( a, b ); +} + +/*! + r0 := a0 + r1 := b0 +*/ +static inline rxmm128d unpckl( rxmm128d a, rxmm128d b ) +{ + return _mm_unpacklo_pd( a, b ); +} + +/*! + r := sign(a1) << 1 | sign(a0) +*/ +static inline int movmsk( rxmm128d a, rxmm128d b ) +{ + return _mm_movemask_pd( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + \sa movmsk +*/ +static inline int shuffle( rxmm128d a, rxmm128d b, int i ) +{ + return _mm_shuffle_pd( a, b, i ); +} + +/*! + == shuffle( a, b, 1 ) + r0 := b0 + r1 := a1 +*/ +static inline rxmm128d move_sd( rxmm128d a, rxmm128d b ) +{ + return _mm_move_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load( double * p ) +{ + return _mm_load_pd( p ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[1] + r1 := p[0] +*/ +static inline rxmm128d load_reverse( double * p ) +{ + return _mm_loadr_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load_unaligned( double * p ) +{ + return _mm_loadu_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := *p +*/ +static inline rxmm128d load_hi( rxmm128d a, double * p ) +{ + return _mm_loadh_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := a1 +*/ +static inline rxmm128d load_lo( rxmm128d a, double * p ) +{ + return _mm_loadl_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p +*/ +static inline rxmm128d load_both( double * p ) +{ + return _mm_load1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 +*/ +static inline rxmm128d load_sd( double * p ) +{ + return _mm_load_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store( double * p, rxmm128d a ) +{ + _mm_load_pd( p, a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a1 + p[1] := a0 +*/ +static inline void store_reverse( double * p, rxmm128d a ) +{ + _mm_storer_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store_unaligned(double * p, rxmm128d a ) +{ + _mm_storeu_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a1 +*/ +static inline void store_hi( double * p, rxmm128d a ) +{ + _mm_storeh_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_lo( double * p, rxmm128d a ) +{ + _mm_storel_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( double * p, rxmm128d a ) +{ + return _mm_store1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_sd( double * p, rxmm128d a ) +{ + return _mm_store_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 +*/ +static inline rxmm128d set( double a1, double a0 ) +{ + return _mm_set_pd( a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 +*/ +static inline rxmm128d set_zero() +{ + return _mm_setzero_pd( a0 ); +} + +/*! + r0 := a0 + r1 := a0 +*/ +static inline rxmm128d set_both( double a0 ) +{ + return _mm_set1_pd( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 +*/ +static inline rxmm128d set_sd( double a0 ) +{ + return _mm_set_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s cvtpd2ps( rxmm128d a ) +{ + return _mm_cvtpd_ps( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtps2pd( rxmm128s a ) +{ + return _mm_cvtps_pd( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128d a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_pd( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128d a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128d b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128d cvtsi2sd( rxmm128d a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128d cvtss2sd( rxmm128d a, rxmm128s b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128d a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128d a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128s cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128s a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128s a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class epi64 +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKINT64_H_*/ diff --git a/SSE_cmplr_abstraction_MSC_pckint8.h b/SSE_cmplr_abstraction_MSC_pckint8.h new file mode 100644 index 0000000..0b129df --- /dev/null +++ b/SSE_cmplr_abstraction_MSC_pckint8.h @@ -0,0 +1,618 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_MSC_PCKINT8_H_ +#define _SSE2_CMPL_ABSTRACTION_MSC_PCKINT8_H_ + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +/// class epi64 (packed single precision) +// +class epi64 +{ +public: + +// +/// The type. +// +typedef rxmm128l my_rxmm; + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer arithmetic +// + +/*! + r0 := a0 + b0 + r1 := a1 + b1 +*/ +static inline rxmm128d add( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_add_pd( a, b ); +} + +/*! + r0 := a0 - b0 + r1 := a1 - b1 +*/ +static inline rxmm128d sub( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sub_pd( a, b ); +} + +/*! + r0 := a0 * b0 + r1 := a1 * b1 +*/ +static inline rxmm128d mul( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_mul_pd( a, b ); +} + +/*! + r0 := a0 / b0 + r1 := a1 / b1 +*/ +static inline rxmm128d div( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_div_pd( a, b ); +} + +/*! + r0 := max( a0, b0 ) + r1 := max( a1, b1 ) +*/ +static inline rxmm128d max( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_max_pd( a, b ); +} + +/*! + r0 := min( a0, b0 ) + r1 := min( a1, b1 ) +*/ +static inline rxmm128d min( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_min_pd( a, b ); +} + +/*! + r0 := sqrt( a0 ) + r1 := sqrt( a1 ) +*/ +static inline rxmm128d sqrt( rxmm128d a ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_sqrt_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer logic +// + +/*! + r0 := (~a0) & b0 + r1 := (~a1) & b1 +*/ +static inline rxmm128d andnot( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_andnot_pd( a, b ); +} + +/*! + r0 := a0 & b0 + r1 := a1 & b1 +*/ +static inline XMM_TYPE and( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_and_pd( a, b ); +} + +/*! + r0 := a0 | b0 + r1 := a1 | b1 +*/ +static inline XMM_TYPE or( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_or_pd( a, b ); +} + +/*! + r0 := a0 ^ b0 + r1 := a1 ^ b1 +*/ +static inline XMM_TYPE xor( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_xor_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer comparision +// + +/*! + r0 := (a0 == b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 == b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_eq( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpeq_pd( a, b ); +} + +/*! + r0 := (a0 != b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 != b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_neq( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpneq_pd( a, b ); +} + +/*! + r0 := (a0 < b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 < b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_lt( rxmm128d a, rxmm128d b ) +{ + return _mm_cmplt_pd( a, b ); +} + +/*! + r0 := (a0 <= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 <= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_le( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmple_pd( a, b ); +} + +/*! + r0 := (a0 > b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 > b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_gt( rxmm128d a, rxmm128d b ) +{ + BOOST_STATIC_ASSERT( false ); + return _mm_cmpgt_pd( a, b ); +} + +/*! + r0 := (a0 >= b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 >= b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ge( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpge_pd( a, b ); +} + +/*! + r0 := (a0 ord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 ord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_ord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpord_pd( a, b ); +} + +/*! + r0 := (a0 unord b0) ? 0xffffffffffffffff : 0x0 + r1 := (a1 unord b1) ? 0xffffffffffffffff : 0x0 +*/ +static inline rxmm128d cmp_unord( rxmm128d a, rxmm128d b ) +{ + return _mm_cmpunord_pd( a, b ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer load +// + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Misc + +/*! + r0 := a1 + r1 := b1 +*/ +static inline rxmm128d unpckh( rxmm128d a, rxmm128d b ) +{ + return _mm_unpackhi_pd( a, b ); +} + +/*! + r0 := a0 + r1 := b0 +*/ +static inline rxmm128d unpckl( rxmm128d a, rxmm128d b ) +{ + return _mm_unpacklo_pd( a, b ); +} + +/*! + r := sign(a1) << 1 | sign(a0) +*/ +static inline int movmsk( rxmm128d a, rxmm128d b ) +{ + return _mm_movemask_pd( a, b ); +} + +/*! + r0 := (i0 == 1) ? b0 : a0 + r1 := (i1 == 1) ? b1 : a1 + \sa movmsk +*/ +static inline int shuffle( rxmm128d a, rxmm128d b, int i ) +{ + return _mm_shuffle_pd( a, b, i ); +} + +/*! + == shuffle( a, b, 1 ) + r0 := b0 + r1 := a1 +*/ +static inline rxmm128d move_sd( rxmm128d a, rxmm128d b ) +{ + return _mm_move_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory load + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load( double * p ) +{ + return _mm_load_pd( p ); +} + +/*! + The address \arg p must be 16-byte aligned. + r0 := p[1] + r1 := p[0] +*/ +static inline rxmm128d load_reverse( double * p ) +{ + return _mm_loadr_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := p[0] + r1 := p[1] +*/ +static inline rxmm128d load_unaligned( double * p ) +{ + return _mm_loadu_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := *p +*/ +static inline rxmm128d load_hi( rxmm128d a, double * p ) +{ + return _mm_loadh_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := a1 +*/ +static inline rxmm128d load_lo( rxmm128d a, double * p ) +{ + return _mm_loadl_pd( a, p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := *p +*/ +static inline rxmm128d load_both( double * p ) +{ + return _mm_load1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := *p + r1 := 0.0 +*/ +static inline rxmm128d load_sd( double * p ) +{ + return _mm_load_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory store + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store( double * p, rxmm128d a ) +{ + _mm_load_pd( p, a ); +} + +/*! + The address \arg p must be 16-byte aligned. + p[0] := a1 + p[1] := a0 +*/ +static inline void store_reverse( double * p, rxmm128d a ) +{ + _mm_storer_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a1 +*/ +static inline void store_unaligned(double * p, rxmm128d a ) +{ + _mm_storeu_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a1 +*/ +static inline void store_hi( double * p, rxmm128d a ) +{ + _mm_storeh_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_lo( double * p, rxmm128d a ) +{ + _mm_storel_pd( p, a ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + p[0] := a0 + p[1] := a0 +*/ +static inline void store_both( double * p, rxmm128d a ) +{ + return _mm_store1_pd( p ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + *p := a0 +*/ +static inline void store_sd( double * p, rxmm128d a ) +{ + return _mm_store_sd( p ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// Memory set + +/*! + r0 := a0 + r1 := a1 +*/ +static inline rxmm128d set( double a1, double a0 ) +{ + return _mm_set_pd( a1, a0 ); +} + +/*! + r0 := 0.0 + r1 := 0.0 +*/ +static inline rxmm128d set_zero() +{ + return _mm_setzero_pd( a0 ); +} + +/*! + r0 := a0 + r1 := a0 +*/ +static inline rxmm128d set_both( double a0 ) +{ + return _mm_set1_pd( a0 ); +} + +/*! + The address \arg p does not need to be 16-byte aligned. + r0 := a0 + r1 := 0.0 +*/ +static inline rxmm128d set_sd( double a0 ) +{ + return _mm_set_sd( a0 ); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +// +/// Packed integer convertion +// + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128s cvtpd2ps( rxmm128d a ) +{ + return _mm_cvtpd_ps( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtps2pd( rxmm128s a ) +{ + return _mm_cvtps_pd( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := 0.0 + r3 := 0.0 +*/ +static inline rxmm128l cvtpd2dq( rxmm128d a ) +{ + return _mm_cvtpd_epi32( a ); +} + +/*! + r0 := (double) a0 + r1 := (double) a1 +*/ +static inline rxmm128d cvtdq2pd( rxmm128l a ) +{ + return _mm_cvtepi32_pd( a ); +} + +/*! + r := (int) a0 +*/ +static inline int cvtsd2si( rxmm128d a ) +{ + return _mm_cvtsd_si32( a ); +} + +/*! + r0 := (float) b0 + r1 := a1 + r2 := a2 + r3 := a3 +*/ +static inline rxmm128s cvtsd2ss( rxmm128l a, rxmm128d b ) +{ + return _mm_cvtsd_ss( a, b ); +} + +/*! + r0 := (double) b + r1 := a1 +*/ +static inline rxmm128d cvtsi2sd( rxmm128d a, int b ) +{ + return _mm_cvtsi32_sd( a, b ); +} + +/*! + r0 := (double) b0 + r1 := a1 +*/ +static inline rxmm128d cvtss2sd( rxmm128d a, rxmm128s b ) +{ + return _mm_cvtss_sd( a, b ); +} + +/*! + using truncate + r0 := (int) a0 + r1 := (int) a1 + r2 := 0x0 + r3 := 0x0 +*/ +static inline rxmm128l cvttpd2dq( rxmm128d a ) +{ + return _mm_cvttpd_epi32( a ); +} + +/*! + using truncate + r := (int) a0 +*/ +static inline int cvttsd2si( rxmm128d a ) +{ + return _mm_cvttsd_si32( a ); +} + +/*! + r0 := (float) a0 + r1 := (float) a1 + r2 := (float) a2 + r3 := (float) a3 +*/ +static inline rxmm128s cvtdq2ps( rxmm128l a ) +{ + return _mm_cvtepi32_ps( a ); +} + +/*! + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvtps2dq( rxmm128s a ) +{ + return _mm_cvtps_epi32( a ); +} + +/*! + uses trancate + r0 := (int) a0 + r1 := (int) a1 + r2 := (int) a2 + r3 := (int) a3 +*/ +static inline rxmm128l cvttps2dq( rxmm128s a ) +{ + return _mm_cvttps_epi32( a ); +} + +// +// class epi64 +// +}; + +// +// Namespace sse2 +// +} + +#endif/*_SSE2_CMPL_ABSTRACTION_MSC_PCKINT8_H_*/ diff --git a/SSE_cmplr_abstraction_other.h b/SSE_cmplr_abstraction_other.h new file mode 100644 index 0000000..5fd9159 --- /dev/null +++ b/SSE_cmplr_abstraction_other.h @@ -0,0 +1,60 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +// +// The purpose of this file is to define SSE2 data types to abstacr from the compiler +// specific constructs. Currently the target compilers are GCC and the MS VC 2005. +// + +#ifndef _SSE2_CMPL_ABSTRACTION_OTHER_H_ +#define _SSE2_CMPL_ABSTRACTION_OTHER_H_ + +#include + +// +// Namespace sse2 +// +namespace sse2 +{ + +// +// Primitive types +// + +/// 2xdouble +// +typedef char xmm128d[16]; + +/// 4xfloat +// +typedef char xmm128s[16]; + +/// 2xint64 +// +typedef char xmm128l[16]; + +/// 4xint32 +// +typedef char xmm128i[16]; + +/// int64 +// +typedef long int; + +// +// Namespace sse2 +// +} + +#include "SSE_cmplr_abstraction_other_pckdbl.h" +#include "SSE_cmplr_abstraction_other_pckfloat.h" +#include "SSE_cmplr_abstraction_other_pckint8.h" +#include "SSE_cmplr_abstraction_other_pckint16.h" +#include "SSE_cmplr_abstraction_other_pckint32.h" +#include "SSE_cmplr_abstraction_other_pckint64.h" + +#endif/*_SSE2_CMPL_ABSTRACTION_OTHER_H_*/ diff --git a/SSE_transform.cpp b/SSE_transform.cpp new file mode 100644 index 0000000..3019b2c --- /dev/null +++ b/SSE_transform.cpp @@ -0,0 +1,43 @@ +// toIntTest.cpp : Defines the entry point for the console application. +// + +#include +#include "getCurrentTime.h" + +#include "base/transform.h" +//#include "base/point.h" + +#if !defined(__AIX) && !defined(__sparc) +#define LOW_ENDIAN_ARCH +#endif + +#ifdef _MSC_VER +#define MY_INLINE __forceinline +#else +#define MY_INLINE inline +#endif + +#ifndef _MSC_VER +#define __int64 long +#endif + + +void test1() +{ +} + +void test2() +{ + +} + +int main(int argc, char* argv[]) +{ +// Init + initGetCurrentTimeLib(); + +// test1(); + test2(); + + return 0; +} diff --git a/any_const_hides_copy_const.cpp b/any_const_hides_copy_const.cpp new file mode 100644 index 0000000..a657763 --- /dev/null +++ b/any_const_hides_copy_const.cpp @@ -0,0 +1,35 @@ +#include + +struct a +{ + int m; + a() + : m(0) + {} + a( int e ) + : m(e) + {} + +//private: +// a( const a & _ ) +// : m( _.m+1) +// {} +}; + +struct b : public a +{ + int n; + b() + : n(0) + {} +}; + +int main() +{ + a o; + a o2 = o; + std::cout << o2.m << std::endl; +// std::cout << o2.m <<' '< +#include +#include +#include +#include + + +typedef boost::variant*> tVarinat; + +int main () +{ + tVarinat v; + std::list l; + + printf( "size %d\n", sizeof( tVarinat ) ); + printf( "size %d\n", sizeof( std::string ) ); + printf( "size %d\n", sizeof( l ) ); + printf( "size %d\n", sizeof( boost::array ) ); + + return 0; +} + diff --git a/call_constructor.cpp b/call_constructor.cpp new file mode 100644 index 0000000..89f98cf --- /dev/null +++ b/call_constructor.cpp @@ -0,0 +1,34 @@ +#include + +class a +{ +public: + a() + { + printf( "kuku\n" ); + } + + ~a() + { + printf( "~a\n" ); + } + + int f() + { + return 0; + } +}; + +int main() +{ + a o; + +// o.a( 0 ); + o.~a(); + + o.f(); + + reinterpret_cast(0)->a::a(); + + +} diff --git a/constStrType.cpp b/constStrType.cpp new file mode 100644 index 0000000..7791857 --- /dev/null +++ b/constStrType.cpp @@ -0,0 +1,20 @@ +#include + +template +struct A +{ + int f ( T t ) + { + //T b = "valod"; + printf( "%s %d\n", t, sizeof( t ) ); + return sizeof( t ); + } +}; + +int main ( void ) +{ + A o; + o.f( "abc" ); + return 0; +} + diff --git a/dlload.cpp b/dlload.cpp new file mode 100644 index 0000000..7703561 --- /dev/null +++ b/dlload.cpp @@ -0,0 +1,19 @@ +#include +#include + +int main () +{ +// void* h1 = dlopen( "/home/vishap/p4/wb/main/stage-g/lib/amd64/libProteus.so", RTLD_LAZY|RTLD_GLOBAL); + void* h1 = dlopen( "/home/vishap/p4/wb/main/stage-g/lib/amd64/libProteus.so", RTLD_NOW|RTLD_GLOBAL); + if ( !h1 ) puts( dlerror() ); + printf( "handle1 = 0x%x\n", h1 ); + void* h2 = dlopen( "/home/vishap/p4/wb/main/src/icwb/test/libProteus.so", RTLD_LAZY|RTLD_GLOBAL); + if ( !h2 ) puts( dlerror() ); + printf( "handle2 = 0x%x\n", h2 ); + + dlclose(h1); + dlclose(h2); + + return 0; +} + diff --git a/dyn_cast.cpp b/dyn_cast.cpp new file mode 100644 index 0000000..1bb31b7 --- /dev/null +++ b/dyn_cast.cpp @@ -0,0 +1,46 @@ + +#include + +class A +{ +public: virtual void* getThis() +{ return this; } +}; + +class B : virtual public A +{ +public: virtual void* getThis() +{ return this; } + +public: virtual void printB() +{ puts("B"); } +}; + +class C : virtual public A +{ +public: virtual void* getThis() +{ return this; } + +public: virtual void printC() +{ puts("C"); } +}; + +class D : public B, + public C +{ +public: virtual void* getThis() +{ return this; } +}; + +int main () +{ + D o; + B* pB = reinterpret_cast( o.getThis() ); + C* pC = reinterpret_cast( o.getThis() ); + + pB->printB(); + pC->printC(); + + return 0; +} + diff --git a/external_guard/external_guard.cpp b/external_guard/external_guard.cpp new file mode 100644 index 0000000..fb3d877 --- /dev/null +++ b/external_guard/external_guard.cpp @@ -0,0 +1,18 @@ + +#include + +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" +#include "external_guard_time100000.h" + +int main () +{ + return 0; +} diff --git a/external_guard/external_guard_time10.h b/external_guard/external_guard_time10.h new file mode 100644 index 0000000..7e458a8 --- /dev/null +++ b/external_guard/external_guard_time10.h @@ -0,0 +1,42 @@ + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + +#ifndef _EXT__H_ +#include +#endif + + diff --git a/external_guard/external_guard_time100.h b/external_guard/external_guard_time100.h new file mode 100644 index 0000000..7d14891 --- /dev/null +++ b/external_guard/external_guard_time100.h @@ -0,0 +1,13 @@ + +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" +#include "external_guard_time10.h" + + diff --git a/external_guard/external_guard_time1000.h b/external_guard/external_guard_time1000.h new file mode 100644 index 0000000..63d917e --- /dev/null +++ b/external_guard/external_guard_time1000.h @@ -0,0 +1,11 @@ +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" +#include "external_guard_time100.h" + diff --git a/external_guard/external_guard_time10000.h b/external_guard/external_guard_time10000.h new file mode 100644 index 0000000..a6457b4 --- /dev/null +++ b/external_guard/external_guard_time10000.h @@ -0,0 +1,11 @@ +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" +#include "external_guard_time1000.h" + diff --git a/external_guard/external_guard_time100000.h b/external_guard/external_guard_time100000.h new file mode 100644 index 0000000..3acbec0 --- /dev/null +++ b/external_guard/external_guard_time100000.h @@ -0,0 +1,11 @@ +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" +#include "external_guard_time10000.h" + diff --git a/getcurrenttime.h b/getcurrenttime.h new file mode 100644 index 0000000..63033b4 --- /dev/null +++ b/getcurrenttime.h @@ -0,0 +1,329 @@ +// toIntTest.cpp : Defines the entry point for the console application. +// + +#include +#include +#include +#include + +#undef min +#undef max + + +#if defined( WIN32 ) +//#define QUERY_PERFORMANCE_COUNTER +#define RDTSC +#else +#define GET_TIME_OF_DAY +#endif + +#ifdef RDTSC +#include + +class perf +{ + __int64 r64; + + __forceinline __int64 getCurrentTime() + { + __asm + { + // + // Serialized instruction ensure all previouse + // instructions a done befor reading the performance + // counter. + // +// cpuid + // + // Read the time stamp counter. + // + rdtsc + } + } + +public: + __forceinline perf() + { + ::Sleep( 0 ); + __asm cpuid + r64 = getCurrentTime(); + } + + __forceinline double elapsed() + { + __int64 now = getCurrentTime(); + return double(now - r64 ); + } + +}; + +__int64 nCPUFrequency; +double dblCPUFrequency; + +inline __int64 getCurrentTimeI() +{ + __asm + { + rdtsc + } +} + +inline double getCurrentTime() +{ +// return double(getCurrentTimeI()); + // + // The time stamp counter. + // + union { + __int64 r64; + __int32 r32[2]; + } tsc; + // + // Read the time stamp counter. + // + __asm + { + // + // Serialized instruction ensure all previouse + // instructions a done befor reading the performance + // counter. + // +// cpuid + // + // Read the counter. + // + rdtsc + // + // + // +// mov tsc.r32[0], eax +// mov tsc.r32[4], edx + movd xmm0,eax + movd xmm1,edx + pshufd xmm1, xmm0, 0xF7 + + } + + + + // + // Get time in seconds. + // + return double(tsc.r64);// / dblCPUFrequency; +} + +void initGetCurrentTimeLib_hlpr() +{ + // + // Use only one fixed CPU + // + BOOL b; + DWORD_PTR proc_affi; + DWORD_PTR sys_affi; + DWORD_PTR exclud_affi; + GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); + exclud_affi = proc_affi & ~sys_affi; + proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; + int i = 0; + while (( proc_affi >>= 1 )) ++i; + proc_affi = 1 << i; + b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); + // + // Set the priority of thread high. + // + b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); + b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + // + // Get the frequency. + // + nCPUFrequency = 2000000000; +// QueryPerformanceFrequency( +// reinterpret_cast( &nCPUFrequency ) ); + // + // Frequency counter supported in CPUs of family x86 + // starting from Pentium 4 or Pentium 3. So for old CPUs + // this will not work. + // + // If CPU doesn't support performance counter then just return. + // + if ( !nCPUFrequency ) + puts("WARNING: This CPU doesn't support QueryPerformanceFrequency."); + // + // Convert to double. + // + dblCPUFrequency = double(nCPUFrequency); +} +#endif + + +#ifdef QUERY_PERFORMANCE_COUNTER +#include + +double dblCPUFrequency; +inline double getCurrentTime() +{ + // + // This call must be quite fast. Since, in x86 architectur + // it is one instruction. Yet WIN32 API might added some + // additional processing. + // + // \todo Vahagn: add our assembly optimised function. + // + __int64 nCPUTickCount; + QueryPerformanceCounter( + reinterpret_cast( &nCPUTickCount ) + ); + // + // Get time in seconds. + // + return double(nCPUTickCount) / dblCPUFrequency; +} + +void initGetCurrentTimeLib_hlpr() +{ + // + // Use only one fixed CPU + // + BOOL b; + DWORD_PTR proc_affi; + DWORD_PTR sys_affi; + DWORD_PTR exclud_affi; + GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); + exclud_affi = proc_affi & ~sys_affi; + proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; + int i = 0; + while (( proc_affi >>= 1 )) ++i; + proc_affi = 1 << i; + b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); + // + // Set the priority of thread high. + // + b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); + b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + // + // Get the frequency. + // + __int64 nCPUFrequency; + QueryPerformanceFrequency( + reinterpret_cast( &nCPUFrequency ) + ); + // + // Frequency counter supported in CPUs of family x86 + // starting from Pentium 4 or Pentium 3. So for old CPUs + // this will not work. + // + // If CPU doesn't support performance counter then just return. + // + if ( !nCPUFrequency ) + puts("WARNING: This CPU doesn't support QueryPerformanceFrequency."); + // + // Convert to double. + // + dblCPUFrequency = double(nCPUFrequency); +} +#endif + +#ifdef GET_TIME_OF_DAY +#include + +inline double getCurrentTime() +{ + timeval t; + gettimeofday(&t,0); + return (double)t.tv_sec + ((double)t.tv_usec/1000000.0); +} + +void initGetCurrentTimeLib_hlpr() +{ +} + +#endif + +void initGetCurrentTimeLib() +{ + initGetCurrentTimeLib_hlpr(); + +#if 0 +for ( int j=0; j < 10000; ++j ) +{ + + // + // Calculate the time expectation and dispersion + // of getCurrentTime on this CPU. + // + const int nProbeCount = 100000; + double dblTimeExpect = 0.; + double dblTimeDispersia = 0.; + for ( int i = nProbeCount; i; --i ) + { + register double dblTimeBase = getCurrentTime(); + register double dblTimeCurrent = getCurrentTime(); + double dblTimeDelta = dblTimeCurrent - dblTimeBase; + dblTimeExpect += dblTimeDelta; + dblTimeDispersia += dblTimeDelta * dblTimeDelta; + } + // + // finalize. + // + dblTimeExpect /= double( nProbeCount ); + dblTimeDispersia = dblTimeDispersia / double( nProbeCount ) + - dblTimeExpect * dblTimeExpect; + printf( "Expectation: %f\n" + "Dispersion: %f\n", + dblTimeExpect, + sqrt(dblTimeDispersia) ); + puts( "----------------------------------------------------" ); + } +#endif + + +#if 0 + const int nProbeCount = 1000; + double* ddd = new double[ nProbeCount ]; + double* p = ddd; + double m = std::numeric_limits::max(); + for ( int i = nProbeCount; i; --i ) + { + register double dblTimeBase = getCurrentTime(); + register double dblTimeCurrent = getCurrentTime(); + *p++ = dblTimeCurrent - dblTimeBase; + m = std::min( m, dblTimeCurrent - dblTimeBase ); +// printf( "%10.1f\n", dblTimeCurrent - dblTimeBase ); + } + + printf( "%10.1f\n", m ); + + std::ofstream o; + o.open( "times.txt" ); + p = ddd; + for ( int i = nProbeCount; i; --i ) + { + o << *p++ << std::endl; + } + o << std::endl; + delete [] ddd; +#endif + +#if 1 + + for ( int j = 0; j < 1000; ++j ) + { + const int nProbeCount = 10000; + double m = 1e300; + for ( int i = nProbeCount; i; --i ) + { + perf pc; + __asm cpuid + __asm cpuid + __asm cpuid + __asm cpuid + double c = pc.elapsed(); + m = min( m, c ); + } + std::cout << m << std::endl; + } +#endif + +} + + diff --git a/getcurrenttime2.h b/getcurrenttime2.h new file mode 100644 index 0000000..04fdf03 --- /dev/null +++ b/getcurrenttime2.h @@ -0,0 +1,287 @@ +// +// Use "rdtsc" to mesure performance. +// +// +#ifndef __PERFORMANCE__H__ +#define __PERFORMANCE__H__ + +#include +#include +#include +#include +#include + +#if defined( WIN32 ) +#undef min +#undef max +#endif + +#if defined( WIN32 ) +#define QUERY_PERFORMANCE_COUNTER +#define RDTSC +#else +#define GET_TIME_OF_DAY +#endif + +#if defined( RDTSC ) +#include + +class perf +{ + __int64 beginning; + static double frequency; + + __forceinline __int64 getCurrentTime() + { + __asm + { + // + // Read the time stamp counter. + // + rdtsc + } + } + +public: + __forceinline perf() + { +// ::Sleep( 0 ); + // + // Serialized instruction ensure all previouse + // instructions a done befor reading the performance + // counter. + // + __asm xor eax,eax + __asm cpuid + beginning = getCurrentTime(); +// __asm xor eax,eax +// __asm cpuid + } + + __forceinline double elapsed() + { + __int64 now = getCurrentTime(); + return double(now - beginning - 60 ) / frequency; + } + + static void init() + { + // + // Use only one fixed CPU + // + BOOL b; + DWORD_PTR proc_affi; + DWORD_PTR sys_affi; + DWORD_PTR exclud_affi; + GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); + exclud_affi = proc_affi & ~sys_affi; + proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; + int i = 0; + while (( proc_affi >>= 1 )) ++i; + proc_affi = 1 << i; + b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); + // + // Set the priority of thread high. + // + b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); + b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + + // + // Get the frequency. + // Temporaily put 1. + // + frequency = 1.; + } +}; + +double perf::frequency; + +#elif defined( QUERY_PERFORMANCE_COUNTER ) +#include + +class perf +{ + __int64 beginning; + static double frequency; + + __forceinline __int64 getCurrentTime() + { + // + // This call must be quite fast. Since, in x86 architectur + // it is one instruction. Yet WIN32 API might added some + // additional processing. + // + // \todo Vahagn: add our assembly optimised function. + // + __int64 tc; + QueryPerformanceCounter( + reinterpret_cast( &tc ) + ); + return tc; + } + +public: + __forceinline perf() + { +// ::Sleep( 0 ); + beginning = getCurrentTime(); + } + + __forceinline double elapsed() + { + __int64 now = getCurrentTime(); + return double(now - beginning ); // frequency; + } + + static void init() + { + // + // Use only one fixed CPU + // + BOOL b; + DWORD_PTR proc_affi; + DWORD_PTR sys_affi; + DWORD_PTR exclud_affi; + GetProcessAffinityMask( GetCurrentProcess(), &proc_affi, &sys_affi ); + exclud_affi = proc_affi & ~sys_affi; + proc_affi = ( exclud_affi ) ? proc_affi : proc_affi; + int i = 0; + while (( proc_affi >>= 1 )) ++i; + proc_affi = 1 << i; + b = SetProcessAffinityMask( GetCurrentProcess(), proc_affi ); + // + // Set the priority of thread high. + // + b = SetPriorityClass( GetCurrentProcess(), REALTIME_PRIORITY_CLASS ); + b = SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL ); + + // + // Get the frequency. + // + __int64 pf; + QueryPerformanceFrequency( + reinterpret_cast( &pf ) + ); + // + // Get the frequency. + // + frequency = double(pf); + } +}; + +double perf::frequency; + +#elif defined ( GET_TIME_OF_DAY ) + +#include + +class perf +{ + timeval beginning; + +public: + __forceinline perf() + { + gettimeofday(&beginning,0); + } + + __forceinline double elapsed() + { + timeval now; + gettimeofday(&now,0); + return double(now.tv_sec) - double(beginning.tv_sec) + + (double(now.tv_usec)-double(beginning.tv_usec))/1000000.0; + } + + static void init() + { + } +}; + +#endif + +template +double mesure( F& fnctr, int nProbes = 100000, bool bPrint = false ) +{ + typedef std::map probs_type; + + probs_type probs; + int n = 0; + for ( int i = 0; i < nProbes; ++i ) + { + perf pc; + fnctr(); + double m = pc.elapsed(); + n = ++probs[ m ]; + } + + double m; + n = 0; + for ( probs_type::iterator it = probs.begin(); + it != probs.end(); + ++it ) + { + if ( it->second > n ) + { + n = it->second; + m = it->first; + } + } + + if ( bPrint ) + { + std::cout << "tsc=" << m << " probes=" << nProbes << std::endl; + std::cout << "===============================" << std::endl; + for ( probs_type::iterator it = probs.begin(); + it != probs.end(); + ++it ) + std::cout << "prob=" << it->first << "\t amount=" << it->second << std::endl; + } + + return m; +}; + +struct nop +{ + __forceinline void operator() () + { + } +}; + +void perf_init() +{ + perf::init(); + + mesure( nop(), 100000, true ); + +#if 0 + + + typedef std::map probs_type; + + probs_type probs; + double m = 1e300; + double s = 0; + int i_last = 0; + int i = 0; + int n = 0; + double c; + for ( ; n < 1000000; ++i ) + { + perf pc; + c = pc.elapsed(); + n = ++probs[ c ]; + } + std::cout << "tsc=" << c << " probes=" << i << std::endl; + std::cout << "=========================" << std::endl; + for ( probs_type::iterator it = probs.begin(); + it != probs.end(); + ++it ) + { + std::cout << "prob=" << it->first << "\t amount=" << it->second << std::endl; + } +#endif + +} + +#endif//__PERFORMANCE__H__ \ No newline at end of file diff --git a/libgd_test/libgd_test.sln b/libgd_test/libgd_test.sln new file mode 100644 index 0000000..fbaf95e --- /dev/null +++ b/libgd_test/libgd_test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgd_test", "libgd_test.vcproj", "{B0DC9AC9-CE8C-422D-B67B-57F4593B1BC8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B0DC9AC9-CE8C-422D-B67B-57F4593B1BC8}.Debug|Win32.ActiveCfg = Debug|Win32 + {B0DC9AC9-CE8C-422D-B67B-57F4593B1BC8}.Debug|Win32.Build.0 = Debug|Win32 + {B0DC9AC9-CE8C-422D-B67B-57F4593B1BC8}.Release|Win32.ActiveCfg = Release|Win32 + {B0DC9AC9-CE8C-422D-B67B-57F4593B1BC8}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/libgd_test/libgd_test.vcproj b/libgd_test/libgd_test.vcproj new file mode 100644 index 0000000..068203e --- /dev/null +++ b/libgd_test/libgd_test.vcproj @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/long_long_size.cpp b/long_long_size.cpp new file mode 100644 index 0000000..384fc92 --- /dev/null +++ b/long_long_size.cpp @@ -0,0 +1,10 @@ +#include + +int main ( void ) +{ + std::cout << "sizeof(long) = " << sizeof( long ) << std::endl; + std::cout << "sizeof(long long) = " << sizeof( long long ) << std::endl; + + return 0; +} + diff --git a/mergeTwoFiles/mergeTwoFiles.cpp b/mergeTwoFiles/mergeTwoFiles.cpp new file mode 100644 index 0000000..1671cf6 --- /dev/null +++ b/mergeTwoFiles/mergeTwoFiles.cpp @@ -0,0 +1,40 @@ +// mergeTwoFiles.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + FILE* f1 = fopen( "D:\\tmp\\pf.avi", "rb" ); + FILE* f2 = fopen( "D:\\tmp\\PulpFiction2.avi", "rb" ); + FILE* o = fopen( "D:\\tmp\\aaaa.avi", "wb" ); + + char buf[2048]; + for ( ; !feof( f1 ); ) + { + int n = fread( buf, 1, sizeof( buf ), f1 ); + if ( !n ) + break; + + bool b = false; + for ( int i = 0; !b && i < n; ++i ) + if ( buf[i] ) + b = true; + + if ( !b ) + { + int pos = ftell( f1 ); + fseek( f2, pos, SEEK_SET ); + n = fread( buf, 1, sizeof( buf ), f2 ); + } + + fwrite( buf, 1, n, o ); + } + + fclose( o ); + fclose( f1 ); + fclose( f2 ); + return 0; +} + diff --git a/mergeTwoFiles/mergeTwoFiles.sln b/mergeTwoFiles/mergeTwoFiles.sln new file mode 100644 index 0000000..976dd42 --- /dev/null +++ b/mergeTwoFiles/mergeTwoFiles.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mergeTwoFiles", "mergeTwoFiles.vcproj", "{F07269AD-FE36-43E5-A832-92D5FC475DE2}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F07269AD-FE36-43E5-A832-92D5FC475DE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {F07269AD-FE36-43E5-A832-92D5FC475DE2}.Debug|Win32.Build.0 = Debug|Win32 + {F07269AD-FE36-43E5-A832-92D5FC475DE2}.Release|Win32.ActiveCfg = Release|Win32 + {F07269AD-FE36-43E5-A832-92D5FC475DE2}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/mergeTwoFiles/mergeTwoFiles.vcproj b/mergeTwoFiles/mergeTwoFiles.vcproj new file mode 100644 index 0000000..102ebcd --- /dev/null +++ b/mergeTwoFiles/mergeTwoFiles.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mergeTwoFiles/stdafx.cpp b/mergeTwoFiles/stdafx.cpp new file mode 100644 index 0000000..96d643d --- /dev/null +++ b/mergeTwoFiles/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// mergeTwoFiles.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/mergeTwoFiles/stdafx.h b/mergeTwoFiles/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/mergeTwoFiles/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/openMP_simple_test.cpp b/openMP_simple_test.cpp new file mode 100644 index 0000000..ed906f0 --- /dev/null +++ b/openMP_simple_test.cpp @@ -0,0 +1,66 @@ +// toIntTest.cpp : Defines the entry point for the console application. +// + +#include +#include +#include "getCurrentTime.h" + +#include "../fw/2007.12/src/base/point.h" + +#if !defined(__AIX) && !defined(__sparc) +#define LOW_ENDIAN_ARCH +#endif + +#ifdef _MSC_VER +#define MY_INLINE __forceinline +#else +#define MY_INLINE inline +#endif + +#ifndef _MSC_VER +#define __int64 long +#endif + + +void test1() +{ + int th_id, nthreads; + #pragma omp parallel private(th_id) + { + th_id = omp_get_thread_num(); + printf("Hello World from thread %d\n", th_id); + #pragma omp barrier + if ( th_id == 0 ) + { + nthreads = omp_get_num_threads(); + printf("There are %d threads\n",nthreads); + } + } +} + +void test2() +{ + int th_id, nthreads; + #pragma omp parallel private(th_id) + { + th_id = omp_get_thread_num(); + printf("Hello World from thread %d\n", th_id); +// #pragma omp barrier + if ( th_id == 0 ) + { + nthreads = omp_get_num_threads(); + printf("There are %d threads\n",nthreads); + } + } +} + +int main(int argc, char* argv[]) +{ +// Init + initGetCurrentTimeLib(); + +// test1(); + test2(); + + return 0; +} diff --git a/pnginfo/pnginfo.cpp b/pnginfo/pnginfo.cpp new file mode 100644 index 0000000..459616e --- /dev/null +++ b/pnginfo/pnginfo.cpp @@ -0,0 +1,213 @@ +// pnginfo.cpp : Defines the entry point for the console application. +// +#include +#include +#include + +#include +#include + +static void error_handler(png_structp png_ptr, png_const_charp msg) +{ + // if (png_ptr) + // ; + throw std::logic_error( boost::str(boost::format("libpng: %1") % msg).c_str() ); +} + +static void warning_handler(png_structp png_ptr, png_const_charp msg) +{ + // if (png_ptr) + // ; + std::cerr << "Warning: libpng: " << msg << std::endl; +} + +void print_info( const std::string& name ) +{ + png_structp png_ptr = 0; + png_infop info_ptr = 0; +try +{ + // + // Open the file. + // + FILE * file = fopen( name.c_str(), "rb"); + if ( !file ) + throw std::logic_error( "fopen failed." ); + // + // First check the eight byte PNG signature. + // + png_byte signature[8]; + fread(signature, 1, 8, file); + if (png_sig_cmp(signature, 0, 8)) + throw std::logic_error( "Bad signature." ); + // + // Create the two png(-info) structures. + // + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + 0/*this*/, + (png_error_ptr)error_handler, + (png_error_ptr)warning_handler); + if (!png_ptr) + throw std::logic_error( "png_create_read_struct failed." ); + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + throw std::logic_error( "png_create_info_struct failed." ); + // + // Initialize the png structure. + // + png_init_io(png_ptr, file); + png_set_sig_bytes(png_ptr, 8); + // + // Read all PNG info up to image data. + // + png_read_info(png_ptr, info_ptr); + // + // Get width, height, bit-depth and color-type. + // + png_uint_32 width; + png_uint_32 height; + int bitDepth; + int colorType; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, + &colorType, NULL, NULL, NULL); + png_size_t rowBytes = png_get_rowbytes(png_ptr, info_ptr); + int channels = png_get_channels(png_ptr, info_ptr); + + std::string colorTypeStr; + switch ( colorType ) + { + case PNG_COLOR_TYPE_GRAY: + colorTypeStr = "PNG_COLOR_TYPE_GRAY"; + break; + case PNG_COLOR_TYPE_GRAY_ALPHA: + colorTypeStr = "PNG_COLOR_TYPE_GRAY_ALPHA"; + break; + case PNG_COLOR_TYPE_PALETTE: + colorTypeStr = "PNG_COLOR_TYPE_PALETTE"; + break; + case PNG_COLOR_TYPE_RGB: + colorTypeStr = "PNG_COLOR_TYPE_RGB"; + break; + case PNG_COLOR_TYPE_RGB_ALPHA: + colorTypeStr = "PNG_COLOR_TYPE_RGB_ALPHA"; + break; + default: + colorTypeStr = boost::str( boost::format( "%02x" ) % colorType ); + } + + std::cout << "Name: " << name << std::endl; + std::cout << "Width: " << width << std::endl; + std::cout << "Height: " << height << std::endl; + std::cout << "Bit Depth: " << bitDepth << std::endl; + std::cout << "Channels: " << channels << std::endl; + std::cout << "Color Type: " << colorTypeStr << std::endl; +#if 0 + // + // Expand images of all color-type and bit-depth to 3x8-bit RGB. + // let the library process alpha, transparency, background, etc. + // + if (colorType == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png_ptr); + if (bitDepth < 8) + png_set_expand(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) + png_set_expand(png_ptr); + if (colorType == PNG_COLOR_TYPE_GRAY || + colorType == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + if (colorType == PNG_COLOR_TYPE_RGB_ALPHA || + colorType == PNG_COLOR_TYPE_GRAY_ALPHA || + png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) + png_set_swap_alpha(png_ptr); + else + png_set_filler(png_ptr, ~0, PNG_FILLER_BEFORE); + if (bitDepth == 16) +# ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED + png_set_scale_16(png_ptr); +# else + png_set_strip_16(png_ptr); +# endif + // + // Set the background color to draw transparent and alpha images over. + // + png_color_16 * bg16; + if (png_get_bKGD(png_ptr, info_ptr, &bg16)) + png_set_background(png_ptr, bg16, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0); + // + // If required set gamma conversion. + // + double dGamma; + if (png_get_gAMA(png_ptr, info_ptr, &dGamma)) + png_set_gamma(png_ptr, (double) 2.2, dGamma); + // + // After the transformations are registered, update info_ptr data. + // + png_read_update_info(png_ptr, info_ptr); + // + // Get again width, height and the new bit-depth and color-type. + // + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colorType, 0, 0, 0); + // + // Row_bytes is the width x number of channels. + // + if ( rowBytes != channels * width * bitDepth / 8 ) + throw std::logic_error( "row bytes is not equal to channels*width*bitDepth/8" ); + // + // Check if the image can store data. + // + if ( I::bit_depth != bitDepth ) + throw std::logic_error( "bit depth don't match." ); + if ( I::channels != channels ) + throw std::logic_error( "channels don't match." ); + // + // Now we can allocate memory to store the image. + // + image.resize( width, height ); + // + // Read data raw by raw. + // + for (png_uint_32 i = 0; i < height; i++) + png_read_row( png_ptr, (png_bytep)image.getData( 0, i ), 0 ); + // + // Read the additional chunks in the PNG file (not really needed). + // + png_read_end(png_ptr, 0); +#endif + // + // Destroy reader and info. + // + png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); + png_ptr = 0; + info_ptr = 0; +} +catch ( ... ) +{ + if ( png_ptr ) + png_destroy_read_struct( &png_ptr, &info_ptr, 0 ); + throw; +}} + +int main(int argc, char * argv[]) +{try{ + + if ( argc != 2 ) + { + std::cerr << "Usage: " << argv[0] << " " << std::endl; + return 3; + } + + print_info(argv[1]); + + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << "Error: " << e.what() << std::endl; + return 2; +} +catch (...) +{ + std::cerr << "Error: unknown." << std::endl; + return 1; +}} + diff --git a/pnginfo/pnginfo.vcxproj b/pnginfo/pnginfo.vcxproj new file mode 100644 index 0000000..f1fbf9c --- /dev/null +++ b/pnginfo/pnginfo.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {248F64F5-D206-4134-A85A-7C919EE88B50} + Win32Proj + pnginfo + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;C:\Users\Vahagnk\src\boost_1_48_0;C:\Users\Vahagnk\src\gtest-1.6.0\include + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);libpngd.lib;zlibd.lib + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;%(AdditionalLibraryDirectories);C:\Users\Vahagnk\src\gtest-1.6.0 + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions); _CRT_SECURE_NO_WARNINGS + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;C:\Users\Vahagnk\src\boost_1_48_0;C:\Users\Vahagnk\src\gtest-1.6.0\include + + + Console + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);libpngd.lib;zlibd.lib + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;%(AdditionalLibraryDirectories);C:\Users\Vahagnk\src\gtest-1.6.0 + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;C:\Users\Vahagnk\src\boost_1_48_0;C:\Users\Vahagnk\src\gtest-1.6.0\include + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);libpng.lib;zlib.lib + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;%(AdditionalLibraryDirectories);C:\Users\Vahagnk\src\gtest-1.6.0 + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions); _CRT_SECURE_NO_WARNINGS + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;C:\Users\Vahagnk\src\boost_1_48_0;C:\Users\Vahagnk\src\gtest-1.6.0\include + + + Console + true + true + true + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies);libpng.lib;zlib.lib + C:\Users\Vahagnk\src\libpng-1.5.10;C:\Users\Vahagnk\src\zlib-1.2.6;%(AdditionalLibraryDirectories);C:\Users\Vahagnk\src\gtest-1.6.0 + + + + + + + + + \ No newline at end of file diff --git a/pnginfo/pnginfo.vcxproj.filters b/pnginfo/pnginfo.vcxproj.filters new file mode 100644 index 0000000..f65d5b4 --- /dev/null +++ b/pnginfo/pnginfo.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/shift_size.cpp b/shift_size.cpp new file mode 100644 index 0000000..fe9a02d --- /dev/null +++ b/shift_size.cpp @@ -0,0 +1,17 @@ +#include +#include + +int main ( ) +{ + std::cout << "shift amount: "; + int a; + + std::cin >> a; + + int b = 1; + + int c = b << a; + + std::cout << " 1 << " << a << " = " << std::hex << c << std::endl; + return 0; +} diff --git a/sln/SEE_test/SEE_test.sln b/sln/SEE_test/SEE_test.sln new file mode 100644 index 0000000..43e5969 --- /dev/null +++ b/sln/SEE_test/SEE_test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SEE_test", "SEE_test.vcproj", "{CD622CAF-1FB7-4E6B-8130-89A4B8A2AD8A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CD622CAF-1FB7-4E6B-8130-89A4B8A2AD8A}.Debug|Win32.ActiveCfg = Debug|Win32 + {CD622CAF-1FB7-4E6B-8130-89A4B8A2AD8A}.Debug|Win32.Build.0 = Debug|Win32 + {CD622CAF-1FB7-4E6B-8130-89A4B8A2AD8A}.Release|Win32.ActiveCfg = Release|Win32 + {CD622CAF-1FB7-4E6B-8130-89A4B8A2AD8A}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/SEE_test/SEE_test.vcproj b/sln/SEE_test/SEE_test.vcproj new file mode 100644 index 0000000..609cacc --- /dev/null +++ b/sln/SEE_test/SEE_test.vcproj @@ -0,0 +1,263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/WindowsApplication1/WindowsApplication1.sln b/sln/WindowsApplication1/WindowsApplication1.sln new file mode 100644 index 0000000..0f5a55e --- /dev/null +++ b/sln/WindowsApplication1/WindowsApplication1.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "WindowsApplication1", "WindowsApplication1.vbproj", "{E5DFDA7A-4D1A-446E-A316-2ABF82859657}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E5DFDA7A-4D1A-446E-A316-2ABF82859657}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E5DFDA7A-4D1A-446E-A316-2ABF82859657}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E5DFDA7A-4D1A-446E-A316-2ABF82859657}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E5DFDA7A-4D1A-446E-A316-2ABF82859657}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/any_const_hides_copy_const/any_const_hides_copy_const.sln b/sln/any_const_hides_copy_const/any_const_hides_copy_const.sln new file mode 100644 index 0000000..f9247a8 --- /dev/null +++ b/sln/any_const_hides_copy_const/any_const_hides_copy_const.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "any_const_hides_copy_const", "any_const_hides_copy_const\any_const_hides_copy_const.vcproj", "{C73246A3-C434-444A-9490-7C3AAD72C099}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C73246A3-C434-444A-9490-7C3AAD72C099}.Debug|Win32.ActiveCfg = Debug|Win32 + {C73246A3-C434-444A-9490-7C3AAD72C099}.Debug|Win32.Build.0 = Debug|Win32 + {C73246A3-C434-444A-9490-7C3AAD72C099}.Release|Win32.ActiveCfg = Release|Win32 + {C73246A3-C434-444A-9490-7C3AAD72C099}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/any_const_hides_copy_const/any_const_hides_copy_const/any_const_hides_copy_const.vcproj b/sln/any_const_hides_copy_const/any_const_hides_copy_const/any_const_hides_copy_const.vcproj new file mode 100644 index 0000000..49a0075 --- /dev/null +++ b/sln/any_const_hides_copy_const/any_const_hides_copy_const/any_const_hides_copy_const.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/boost_variant_test/boost_variant_test.sln b/sln/boost_variant_test/boost_variant_test.sln new file mode 100644 index 0000000..96cc0ea --- /dev/null +++ b/sln/boost_variant_test/boost_variant_test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boost_variant_test", "boost_variant_test.vcproj", "{6A52DAA3-54D4-4929-867F-F268F087F518}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6A52DAA3-54D4-4929-867F-F268F087F518}.Debug|Win32.ActiveCfg = Debug|Win32 + {6A52DAA3-54D4-4929-867F-F268F087F518}.Debug|Win32.Build.0 = Debug|Win32 + {6A52DAA3-54D4-4929-867F-F268F087F518}.Release|Win32.ActiveCfg = Release|Win32 + {6A52DAA3-54D4-4929-867F-F268F087F518}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/boost_variant_test/boost_variant_test.vcproj b/sln/boost_variant_test/boost_variant_test.vcproj new file mode 100644 index 0000000..58f82ae --- /dev/null +++ b/sln/boost_variant_test/boost_variant_test.vcproj @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/openMpSimpleTest/openMpSimpleTest.sln b/sln/openMpSimpleTest/openMpSimpleTest.sln new file mode 100644 index 0000000..c67fe2b --- /dev/null +++ b/sln/openMpSimpleTest/openMpSimpleTest.sln @@ -0,0 +1,23 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openMpSimpleTest", "openMpSimpleTest.vcproj", "{5F1F3ED8-2682-4901-83CE-83D545D0D68B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + PseudoDebug|Win32 = PseudoDebug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.Debug|Win32.ActiveCfg = Debug|Win32 + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.Debug|Win32.Build.0 = Debug|Win32 + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.PseudoDebug|Win32.ActiveCfg = PseudoDebug|Win32 + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.PseudoDebug|Win32.Build.0 = PseudoDebug|Win32 + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.Release|Win32.ActiveCfg = Release|Win32 + {5F1F3ED8-2682-4901-83CE-83D545D0D68B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/openMpSimpleTest/openMpSimpleTest.vcproj b/sln/openMpSimpleTest/openMpSimpleTest.vcproj new file mode 100644 index 0000000..17cc90a --- /dev/null +++ b/sln/openMpSimpleTest/openMpSimpleTest.vcproj @@ -0,0 +1,290 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/qstringDebug/GeneratedFiles/Debug/moc_qstringdebug.cpp b/sln/qstringDebug/GeneratedFiles/Debug/moc_qstringdebug.cpp new file mode 100644 index 0000000..da029b3 --- /dev/null +++ b/sln/qstringDebug/GeneratedFiles/Debug/moc_qstringdebug.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'qstringdebug.h' +** +** Created: Fri May 30 00:05:16 2008 +** by: The Qt Meta Object Compiler version 59 (Qt 4.3.3) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "../../qstringdebug.h" +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'qstringdebug.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 59 +#error "This file was generated using the moc from 4.3.3. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +static const uint qt_meta_data_qstringDebug[] = { + + // content: + 1, // revision + 0, // classname + 0, 0, // classinfo + 0, 0, // methods + 0, 0, // properties + 0, 0, // enums/sets + + 0 // eod +}; + +static const char qt_meta_stringdata_qstringDebug[] = { + "qstringDebug\0" +}; + +const QMetaObject qstringDebug::staticMetaObject = { + { &QMainWindow::staticMetaObject, qt_meta_stringdata_qstringDebug, + qt_meta_data_qstringDebug, 0 } +}; + +const QMetaObject *qstringDebug::metaObject() const +{ + return &staticMetaObject; +} + +void *qstringDebug::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_qstringDebug)) + return static_cast(const_cast< qstringDebug*>(this)); + return QMainWindow::qt_metacast(_clname); +} + +int qstringDebug::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QMainWindow::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + return _id; +} diff --git a/sln/qstringDebug/GeneratedFiles/ui_qstringdebug.h b/sln/qstringDebug/GeneratedFiles/ui_qstringdebug.h new file mode 100644 index 0000000..cf13785 --- /dev/null +++ b/sln/qstringDebug/GeneratedFiles/ui_qstringdebug.h @@ -0,0 +1,66 @@ +/******************************************************************************** +** Form generated from reading ui file 'qstringdebug.ui' +** +** Created: Fri May 30 00:05:11 2008 +** by: Qt User Interface Compiler version 4.3.3 +** +** WARNING! All changes made in this file will be lost when recompiling ui file! +********************************************************************************/ + +#ifndef UI_QSTRINGDEBUG_H +#define UI_QSTRINGDEBUG_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Ui_qstringDebugClass +{ +public: + QMenuBar *menuBar; + QToolBar *mainToolBar; + QWidget *centralWidget; + QStatusBar *statusBar; + + void setupUi(QMainWindow *qstringDebugClass) + { + if (qstringDebugClass->objectName().isEmpty()) + qstringDebugClass->setObjectName(QString::fromUtf8("qstringDebugClass")); + qstringDebugClass->resize(600, 400); + menuBar = new QMenuBar(qstringDebugClass); + menuBar->setObjectName(QString::fromUtf8("menuBar")); + qstringDebugClass->setMenuBar(menuBar); + mainToolBar = new QToolBar(qstringDebugClass); + mainToolBar->setObjectName(QString::fromUtf8("mainToolBar")); + qstringDebugClass->addToolBar(mainToolBar); + centralWidget = new QWidget(qstringDebugClass); + centralWidget->setObjectName(QString::fromUtf8("centralWidget")); + qstringDebugClass->setCentralWidget(centralWidget); + statusBar = new QStatusBar(qstringDebugClass); + statusBar->setObjectName(QString::fromUtf8("statusBar")); + qstringDebugClass->setStatusBar(statusBar); + + retranslateUi(qstringDebugClass); + + QMetaObject::connectSlotsByName(qstringDebugClass); + } // setupUi + + void retranslateUi(QMainWindow *qstringDebugClass) + { + qstringDebugClass->setWindowTitle(QApplication::translate("qstringDebugClass", "qstringDebug", 0, QApplication::UnicodeUTF8)); + Q_UNUSED(qstringDebugClass); + } // retranslateUi + +}; + +namespace Ui { + class qstringDebugClass: public Ui_qstringDebugClass {}; +} // namespace Ui + +#endif // UI_QSTRINGDEBUG_H diff --git a/sln/qstringDebug/main.cpp b/sln/qstringDebug/main.cpp new file mode 100644 index 0000000..f0f5dfc --- /dev/null +++ b/sln/qstringDebug/main.cpp @@ -0,0 +1,11 @@ +#include +#include "qstringdebug.h" + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + qstringDebug w; + w.show(); + a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit())); + return a.exec(); +} diff --git a/sln/qstringDebug/qstringDebug.sln b/sln/qstringDebug/qstringDebug.sln new file mode 100644 index 0000000..23eb4d9 --- /dev/null +++ b/sln/qstringDebug/qstringDebug.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qstringDebug", "qstringDebug.vcproj", "{A1511B5B-670F-4CB4-83D4-F9E66868E48B}" + GlobalSection(Qt) = preSolution + Integration = True + EndGlobalSection +EndProject +Global + GlobalSection(Qt) = preSolution + Integration = True + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A1511B5B-670F-4CB4-83D4-F9E66868E48B}.Debug|Win32.ActiveCfg = Debug|Win32 + {A1511B5B-670F-4CB4-83D4-F9E66868E48B}.Debug|Win32.Build.0 = Debug|Win32 + {A1511B5B-670F-4CB4-83D4-F9E66868E48B}.Release|Win32.ActiveCfg = Release|Win32 + {A1511B5B-670F-4CB4-83D4-F9E66868E48B}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/qstringDebug/qstringDebug.vcproj b/sln/qstringDebug/qstringDebug.vcproj new file mode 100644 index 0000000..b77c236 --- /dev/null +++ b/sln/qstringDebug/qstringDebug.vcproj @@ -0,0 +1,343 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/qstringDebug/qstringdebug.cpp b/sln/qstringDebug/qstringdebug.cpp new file mode 100644 index 0000000..265b1cc --- /dev/null +++ b/sln/qstringDebug/qstringdebug.cpp @@ -0,0 +1,14 @@ +#include "qstringdebug.h" + +qstringDebug::qstringDebug(QWidget *parent, Qt::WFlags flags) + : QMainWindow(parent, flags) +{ + ui.setupUi(this); + + QString str = "kukukuku"; +} + +qstringDebug::~qstringDebug() +{ + +} diff --git a/sln/qstringDebug/qstringdebug.h b/sln/qstringDebug/qstringdebug.h new file mode 100644 index 0000000..f9708f8 --- /dev/null +++ b/sln/qstringDebug/qstringdebug.h @@ -0,0 +1,19 @@ +#ifndef QSTRINGDEBUG_H +#define QSTRINGDEBUG_H + +#include +#include "ui_qstringdebug.h" + +class qstringDebug : public QMainWindow +{ + Q_OBJECT + +public: + qstringDebug(QWidget *parent = 0, Qt::WFlags flags = 0); + ~qstringDebug(); + +private: + Ui::qstringDebugClass ui; +}; + +#endif // QSTRINGDEBUG_H diff --git a/sln/std_vs_qt/std_vs_qt.sln b/sln/std_vs_qt/std_vs_qt.sln new file mode 100644 index 0000000..fd3398c --- /dev/null +++ b/sln/std_vs_qt/std_vs_qt.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "std_vs_qt", "std_vs_qt.vcproj", "{41F5283C-3803-4436-8116-4133A5780B81}" + GlobalSection(Qt) = preSolution + Integration = True + EndGlobalSection +EndProject +Global + GlobalSection(Qt) = preSolution + Integration = True + EndGlobalSection + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {41F5283C-3803-4436-8116-4133A5780B81}.Debug|Win32.ActiveCfg = Debug|Win32 + {41F5283C-3803-4436-8116-4133A5780B81}.Debug|Win32.Build.0 = Debug|Win32 + {41F5283C-3803-4436-8116-4133A5780B81}.Release|Win32.ActiveCfg = Release|Win32 + {41F5283C-3803-4436-8116-4133A5780B81}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/std_vs_qt/std_vs_qt.vcproj b/sln/std_vs_qt/std_vs_qt.vcproj new file mode 100644 index 0000000..f700337 --- /dev/null +++ b/sln/std_vs_qt/std_vs_qt.vcproj @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/toIntTest.sln b/sln/toIntTest.sln new file mode 100644 index 0000000..353c1d3 --- /dev/null +++ b/sln/toIntTest.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toIntTest", "toIntTest.vcproj", "{4A53E026-6A19-4687-9583-1BA2F787E1D1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4A53E026-6A19-4687-9583-1BA2F787E1D1}.Debug|Win32.ActiveCfg = Debug|Win32 + {4A53E026-6A19-4687-9583-1BA2F787E1D1}.Debug|Win32.Build.0 = Debug|Win32 + {4A53E026-6A19-4687-9583-1BA2F787E1D1}.Release|Win32.ActiveCfg = Release|Win32 + {4A53E026-6A19-4687-9583-1BA2F787E1D1}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/toIntTest.vcproj b/sln/toIntTest.vcproj new file mode 100644 index 0000000..2d06167 --- /dev/null +++ b/sln/toIntTest.vcproj @@ -0,0 +1,205 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sln/virtual_method_ptr/virtual_method_ptr.sln b/sln/virtual_method_ptr/virtual_method_ptr.sln new file mode 100644 index 0000000..040fb9e --- /dev/null +++ b/sln/virtual_method_ptr/virtual_method_ptr.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "virtual_method_ptr", "virtual_method_ptr.vcproj", "{E1F1366C-5734-4F02-8A1C-15B8A65512E6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E1F1366C-5734-4F02-8A1C-15B8A65512E6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E1F1366C-5734-4F02-8A1C-15B8A65512E6}.Debug|Win32.Build.0 = Debug|Win32 + {E1F1366C-5734-4F02-8A1C-15B8A65512E6}.Release|Win32.ActiveCfg = Release|Win32 + {E1F1366C-5734-4F02-8A1C-15B8A65512E6}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/sln/virtual_method_ptr/virtual_method_ptr.vcproj b/sln/virtual_method_ptr/virtual_method_ptr.vcproj new file mode 100644 index 0000000..55bc5fd --- /dev/null +++ b/sln/virtual_method_ptr/virtual_method_ptr.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static_cast_vs_dynamik.cpp b/static_cast_vs_dynamik.cpp new file mode 100644 index 0000000..943cd7e --- /dev/null +++ b/static_cast_vs_dynamik.cpp @@ -0,0 +1,35 @@ + +class a +{ +public: +int i; + +public: +virtual void f() +{ + i = 0; +} + +}; + +class b : virtual public a +{ +public: +virtual void f() +{ + i = 1; +} + +}; + +int main() +{ + b o; + + a* pA = &o; + + b* pB = static_cast(pA); + + return 0; +} + diff --git a/std_vs_qt.cpp b/std_vs_qt.cpp new file mode 100644 index 0000000..c62fcfe --- /dev/null +++ b/std_vs_qt.cpp @@ -0,0 +1,725 @@ + +#include +#include "getCurrentTime.h" + +#include +#include +#include +#include +#include + +#if defined( _MSC_VER ) +#pragma intrinsic (memcpy,memcmp,memset,strcat,strcmp,strcpy,strlen) +#endif + +namespace constructor +{ + void * operator new( size_t count, + void * object ) + { + return object; + } +} + +//#define ALLOC_AT_ONCE +//#define USE_MALLOC +// TEMPLATE CLASS allocator +template +class fast_allocator +#ifndef USE_MALLOC + : public std::allocator +#endif +{ + char memory[N]; +#ifndef ALLOC_AT_ONCE + char* marker; +#endif + +public: + typedef std::allocator MyBase; + typedef T value_type; + typedef value_type *pointer; + typedef value_type & reference; + typedef const value_type *const_pointer; + typedef const value_type & const_reference; + + typedef size_t size_type; + typedef ptrdiff_t difference_type; + + template + struct rebind + { // convert an allocator<_Ty> to an allocator <_Other> + typedef fast_allocator<_Other,N> other; + }; + + // return address of mutable _Val + pointer address(reference _Val) const + { + return (&_Val); + } + + const_pointer address(const_reference _Val) const + { // return address of nonmutable _Val + return (&_Val); + } + + fast_allocator() throw() +#ifndef ALLOC_AT_ONCE + : marker( memory ) +#endif + {} + + // construct by copying (do nothing) + fast_allocator( const fast_allocator& ) throw() +#ifndef ALLOC_AT_ONCE + : marker( memory ) +#endif + {} + + // construct from a related allocator (do nothing) +// template +// allocatorN(const std::allocator<_Other>&) throw() +// : marker( memory ) +// {} + + // deallocate object at _Ptr, ignore size + void deallocate(pointer p, size_type n ) + { +#ifdef ALLOC_AT_ONCE + if ( p != static_cast(memory) ) +#ifdef USE_MALLOC + free( p ); +#else + return MyBase::deallocate( p, n ); +#endif +#else/*ALLOC_AT_ONCE*/ + if ( p+n == marker ) + marker = p; + else if ( p < static_cast(memory) + || static_cast(&memory[N]) <= p ) +#ifdef USE_MALLOC + free( p ); +#else + return MyBase::deallocate( p, n ); +#endif +#endif + } + + // allocate array of n elements + pointer allocate(size_type nCount) + { + register size_type s = sizeof(T)*nCount; +#ifdef ALLOC_AT_ONCE + if ( sizeof(T)*nCount < N ) + return static_cast(memory); +#else + if ( sizeof(T)*nCount < (&memory[N] - marker) ) + { + pointer p = static_cast(marker); + marker += s; + return p; + } +#endif + else +#ifdef USE_MALLOC + return static_cast(malloc( s )); +#else + return MyBase::allocate( nCount ); +#endif + } + + // allocate array of n elements, ignore hint + pointer allocate(size_type nCount, const void *) + { + return allocate(nCount); + } + + // construct object at _Ptr with value _Val + void construct(pointer _Ptr, const T& _Val) + { + ::new (_Ptr) T(_Val); + } + + // destroy object at _Ptr + void destroy( pointer p ) + { + p->~T(); + } + + // estimate maximum array size + size_type max_size() const throw() + { +#ifdef USE_MALLOC + return (size_type)(-1) / sizeof(T); +#else +// return MyBase::max_size(); + return (int)(-1) / sizeof(T); +#endif + } + +// bool operator( const fast_allocator& op ) +// { +// return &op == this; +// } +}; + +template +inline +bool operator== ( const fast_allocator& op1, + const fast_allocator& op2 ) +{ + return &op1 == &op2; +} + +// STRUCT char_traits (FROM ) +template +struct fast_char_traits +{ // properties of a string or stream char element + typedef C char_type; + typedef int int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; +// typedef _Mbstatet state_type; + + // assign an element + static void assign( char_type& l, const char_type& r) + { + l = r; + } + + // test for element equality + static bool eq( const char_type& l, const char_type& r) + { + return (l == r); + } + + // test if l precedes r + static bool lt( const char_type& l, const char_type& r) + { + return (l < r); + } + + // compare [_First1, _First1 + n) with [_First2, ...) + static int compare(const char_type *op1, const char_type *op2, size_t n) + { + return (::memcmp(op1, op2, n*sizeof(char_type))); + } + + // find length of null-terminated string + static size_t length(const char_type * op) + { + return (::strlen(op)); + } + + // assume there is enough space in the destination buffer + static char_type * copy(char_type *dest, const char_type *src, size_t n) + { + return reinterpret_cast(::memcpy( dest, src, n*sizeof(char_type) )); + } + + // look for _Ch in [_First, _First + n) + static const char_type * find(const char_type * src, size_t n, const char_type& ch) + { + return ((const char_type *)::memchr(src, ch, n)); + } + + // move [_First1, _First1 + n) to [_First2, ...) + // assume there is enough space in the destination buffer + static char_type * move(char_type *dest, const char_type *src, size_t n) + { + return reinterpret_cast(::memmove(dest, src, n*sizeof(char_type))); + } + + // assign n * _Ch to [_First, ...) + static char_type * assign(char_type *_First, size_t n, char_type _Ch) + { + return ((char_type *)::memset(_First, _Ch, n)); + } + + // convert metacharacter to character + static char_type to_char_type(const int_type& chMeta) + { + return ((char_type)chMeta); + } + + // convert character to metacharacter + static int_type to_int_type(const char_type& ch) + { + return ((unsigned char)ch); + } + + // test for metacharacter equality + static bool eq_int_type(const int_type& l, const int_type& r) + { + return (l == r); + } + + // return end-of-file metacharacter + static int_type eof() + { + return (EOF); + } + + // return anything but EOF + static int_type not_eof(const int_type& chMeta) + { + return (chMeta != eof() ? chMeta : !eof()); + } +}; + +template < + class CharType, + class Traits=fast_char_traits, + class Allocator=fast_allocator +> +class fast_basic_string : public std::basic_string< CharType, Traits, Allocator > +{ +public: + typedef fast_basic_string< CharType, Traits, Allocator > MySelf; + typedef std::basic_string< CharType, Traits, Allocator > MyBase; + + fast_basic_string( + const typename MyBase::value_type* _Ptr, + typename MyBase::size_type _Count, + const typename MyBase::allocator_type& _Al = Allocator ( ) + ) + : std::basic_string< CharType, Traits, Allocator >( _Ptr, _Count, _Al ) + {} + + fast_basic_string( + const typename MyBase::value_type* _Ptr, + const typename MyBase::allocator_type& _Al = Allocator ( ) + ) + : std::basic_string< CharType, Traits, Allocator >( _Ptr, _Al ) + {} + + fast_basic_string( + const MyBase& _Right, + typename MyBase::size_type _Roff = 0, + typename MyBase::size_type _Count = npos, + const typename MyBase::allocator_type& _Al = Allocator ( ) + ) + : std::basic_string< CharType, Traits, Allocator >( _Right, _Roff, _Count, _Al ) + {} + + fast_basic_string( + typename MyBase::size_type _Count, + typename MyBase::value_type _Ch, + const typename MyBase::allocator_type& _Al = Allocator ( ) + ) + : std::basic_string< CharType, Traits, Allocator >( _Count, _Ch, _Al ) + {} + + explicit fast_basic_string( + const typename MyBase::allocator_type& _Al = Allocator ( ) + ) + : std::basic_string< CharType, Traits, Allocator >( _Al ) + {} + +#if 0 //ndef _MSC_VER + bool operator == ( const MySelf& str ) + { + return ( str.size() != size() ) ? false : MyBase::operator == ( str ); + } +#endif +}; + +#if 1 //def _MSC_VER +template +inline +bool operator==( + const fast_basic_string& l, + const fast_basic_string& r ) +{ // test for string equality + return (l.size() != r.size()) ? + false : (l.compare(r) == 0); +} +#endif + +typedef fast_basic_string< char > fast_string; + + +const char* testStr[] = +{ + "1", //1 + "12", //2 + "123", //3 + "1234", //4 + "12345", //5 + "123456", //6 + "1234567", //7 + "12345678", //8 + "123456781", //9 + "1234567812", //10 + "12345678123", //11 + "123456781234", //12 + "1234567812345", //13 + "12345678123456", //14 + "123456781234567", //15 + "1234567812345678", //16 + "12345678123456781", //17 + "123456781234567812", //18 + "1234567812345678123", //19 + "12345678123456781234567812345678", //32 + "12345678123456781234567812345678123456781234567812345678123456", //62 + "123456781234567812345678123456781234567812345678123456781234567", //63 + "1234567812345678123456781234567812345678123456781234567812345678", //64 + + "12345678123456781234567812345678123456781234567812345678123456781", + "123456781234567812345678123456781234567812345678123456781234567812", + "1234567812345678123456781234567812345678123456781234567812345678123", + "12345678123456781234567812345678123456781234567812345678123456781234", + "123456781234567812345678123456781234567812345678123456781234567812345678", + "12345678123456781234567812345678123456781234567812345678123456781234567812345678", + "123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", + "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", + "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678" + "12345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678", + +}; + +template +inline +int initString( const S2& str ) +{ + S a( str ); + return 0; +} + +template +inline +int assignString( const S2& str ) +{ + S a; + a = str; + return 0; +} + +template +inline +int cmpEqString( const S& str1, const S& str2 ) +{ + return str1 == str2; +} + +template +inline +int cmpLessString( const S& str1, const S& str2 ) +{ + return str1 < str2; +} + +/* +std::list listQString; +int alocQString(char const * const pStr) +{ + QString* a = new QString(pStr); + listQString.push_back( a ); + return 0; +} + +int freeQString() +{ + std::list::iterator it = listQString.begin(); + std::list::iterator itEnd = listQString.end(); + for ( ; it!=itEnd; ++it ) + delete *it; + listQString.clear(); + return 0; +} + +std::list listStdString; +int alocStdString(char const * const pStr) +{ + std::string* a = new std::string(pStr); + listStdString.push_back( a ); + return 0; +} + +int freeStdString() +{ + std::list::iterator it = listStdString.begin(); + std::list::iterator itEnd = listStdString.end(); + for ( ; it!=itEnd; ++it ) + delete *it; + listStdString.clear(); + return 0; +} +*/ + +template< class S1, + class S2, + int (*func1)( const S1& ), + int (*func2)( const S2& ), + int nProbes > +void testStringsUnary( char const * const pStr ) +{ + double dwStart, dwEnd; + + S1 s1_op( pStr ); + S2 s2_op( pStr ); + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = func1(s1_op); + dwEnd = getCurrentTime(); + double dblDiff1 = dwEnd - dwStart; + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = func2(s2_op); + dwEnd = getCurrentTime(); + double dblDiff2 = dwEnd - dwStart; + + printf( "m1 %f m2 %f m1/m2 %f probs=%d\n", dblDiff1, dblDiff2, dblDiff1/dblDiff2, nProbes ); +} + +template< class S1, + class S2, + int (*func1)(const S1&, const S1& ), + int (*func2)(const S2&, const S2& ), + int nProbes > +void testStringsBinary( char const * const pStr1, char const * const pStr2 ) +{ + double dwStart, dwEnd; + + S1 s1_op1( pStr1 ); + S1 s1_op2( pStr2 ); + + S2 s2_op1( pStr1 ); + S2 s2_op2( pStr2 ); + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = func1(s1_op1,s1_op2); + dwEnd = getCurrentTime(); + double dblDiff1 = dwEnd - dwStart; + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = func2(s2_op1,s2_op2); + dwEnd = getCurrentTime(); + double dblDiff2 = dwEnd - dwStart; + + printf( "m1 %f m2 %f m1/m2 %f probs=%d\n", dblDiff1, dblDiff2, dblDiff1/dblDiff2, nProbes ); +} + +/* +void testStrings( char const * const pStr ) +{ + double dwStart, dwEnd; + + int nProbes = 5000000; + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = alocStdString(pStr); + dwEnd = getCurrentTime(); + printf( "alocStdString \t%f\t\t", dwEnd - dwStart ); + dwStart = getCurrentTime(); + { + volatile int a = freeStdString(); + } + dwEnd = getCurrentTime(); + printf( "freeStdString \t%f\n", dwEnd - dwStart ); + + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = alocQString(pStr); + dwEnd = getCurrentTime(); + printf( "alocQString \t%f\t\t", dwEnd - dwStart ); + dwStart = getCurrentTime(); + { + volatile int a = freeQString(); + } + dwEnd = getCurrentTime(); + printf( "freeQString \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = alocStdString(pStr); + dwEnd = getCurrentTime(); + printf( "alocStdString \t%f\t\t", dwEnd - dwStart ); + dwStart = getCurrentTime(); + { + volatile int a = freeStdString(); + } + dwEnd = getCurrentTime(); + printf( "freeStdString \t%f\n", dwEnd - dwStart ); + + + dwStart = getCurrentTime(); + for ( int i = nProbes; i; --i ) + volatile int a = alocQString(pStr); + dwEnd = getCurrentTime(); + printf( "alocQString \t%f\t\t", dwEnd - dwStart ); + dwStart = getCurrentTime(); + { + volatile int a = freeQString(); + } + dwEnd = getCurrentTime(); + printf( "freeQString \t%f\n", dwEnd - dwStart ); +} +*/ + +template +void test() +{ +#if 1 + /* + */ + puts( "constructor(char*) \n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsUnary, + initString, + 1000000>( testStr[i] ); + } +#endif + +#if 1 + /* + */ + puts( "constructor(native) \n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsUnary, + initString, + 1000000>( testStr[i] ); + } +#endif + +#if 1 + /* + */ + puts( "operator = (char*) \n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsUnary, + assignString, + 1000000>( testStr[i] ); + } +#endif + +#if 1 + /* + */ + puts( "operator = (native) \n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]); ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsUnary, + assignString, + 1000000>( testStr[i] ); + } +#endif + +#if 1 + /* + */ + puts( "operator == () (equal strings)\n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsBinary< S1, + S2, + cmpEqString, + cmpEqString, + 1000000>( testStr[i], testStr[i] ); + } +#endif + +#if 1 + /* + */ + puts( "operator == () (never equal strings)\n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsBinary< S1, + S2, + cmpEqString, + cmpEqString, + 1000000>( testStr[i], testStr[i+1] ); + } +#endif + +#if 1 + /* + */ + puts( "operator < (less strings)\n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsBinary< S1, + S2, + cmpLessString, + cmpLessString, + 1000000>( testStr[i], testStr[i+1] ); + } +#endif + +#if 1 + /* + */ + puts( "operator < () (great strings)\n" + "============================================================"); + for ( int i = 0; i < sizeof(testStr)/sizeof(testStr[0]) -1; ++i ) + { + printf("strlen: %3d ", strlen(testStr[i]), testStr[i] ); + testStringsBinary< S1, + S2, + cmpLessString, + cmpLessString, + 1000000>( testStr[i+1], testStr[i] ); + } +#endif +} + +int main(int argc, char *argv[]) +{ + // Init + initGetCurrentTimeLib(); + double dwStart, dwEnd; + int nProbes; + + QCoreApplication a(argc, argv); + +#if 1 + puts( "************************************************************\n" + "************************************************************\n" + "Testing m1=QString vs m2=std::string \n" + "************************************************************"); + test(); +#endif + +#if 0 + puts( "************************************************************\n" + "************************************************************\n" + "Testing m1=QString vs m2=fast_string \n" + "************************************************************"); + test(); +#endif + +// return a.exec(); + return 0; +} diff --git a/stdafx.cpp b/stdafx.cpp new file mode 100644 index 0000000..ab6cf71 --- /dev/null +++ b/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/stdafx.h b/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/stl_vector_resize.cpp b/stl_vector_resize.cpp new file mode 100644 index 0000000..bae2c6e --- /dev/null +++ b/stl_vector_resize.cpp @@ -0,0 +1,47 @@ +#include +#include + +int main( void ) +{ + std::vector v; + + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.push_back( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.resize( 1 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.resize( 0 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.resize( 33 ); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + v.clear(); + std::cout << "capacity " << v.capacity() << "\t\tsize " << v.size() << std::endl; + return 0; +} + diff --git a/tbb_test/main.cpp b/tbb_test/main.cpp new file mode 100644 index 0000000..6c52903 --- /dev/null +++ b/tbb_test/main.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#include + +#include +#include + +static const size_t N = 23; + +class SubStringFinder +{ + const std::string str; + size_t *max_array; + size_t *pos_array; + +public: + void operator() ( const tbb::blocked_range& r ) const + { + std::cout << "gs:" << r.grainsize() << " b:" << r.begin() << " e:" << r.end() << std::endl; + std::cout.flush(); + for ( size_t i = r.begin(); i != r.end(); ++i ) + { + size_t max_size = 0, max_pos = 0; + for (size_t j = 0; j < str.size(); ++j) + if (j != i) + { + size_t limit = str.size()-std::max(i,j); + for (size_t k = 0; k < limit; ++k) + { + if (str[i + k] != str[j + k]) + break; + if (k > max_size) + { + max_size = k; + max_pos = j; + } + } + } + max_array[i] = max_size; + pos_array[i] = max_pos; + } + } + + SubStringFinder(std::string &s, size_t *m, size_t *p) + : str(s), max_array(m), pos_array(p) + { } +}; + +int test() +{ + std::string str[N] = { std::string("a"), std::string("b") }; + + for (size_t i = 2; i < N; ++i) + str[i] = str[i-1]+str[i-2]; + std::string &to_scan = str[N-1]; + size_t num_elem = to_scan.size(); + + size_t *max = new size_t[num_elem]; + size_t *pos = new size_t[num_elem]; + + tbb::parallel_for( tbb::blocked_range(0, num_elem ), + SubStringFinder( to_scan, max, pos ) ); + + for (size_t i = 0; i < num_elem; ++i) + std::cout << " " << max[i] << "(" << pos[i] << ")" << std::endl; + delete[] pos; + delete[] max; + return 0; +} + +class copy_tracker +{ + int v; +public: + copy_tracker() + : v(0) + { + std::cout << "copy_tracker::copy_tracker()" << std::endl; + } + + copy_tracker( copy_tracker& c ) + : v( c.v ) + { + std::cout << "copy_tracker::copy_tracker( copy_tracker& c )" << std::endl; + } + + void echo() + { + std::cout << v << std::endl; + } +}; + +copy_tracker copy_tracker_by_value() +{ + return copy_tracker(); +} + +copy_tracker copy_tracker_by_value2() +{ + return copy_tracker_by_value(); +} + +void test_copy_tracker() +{ + volatile copy_tracker o = copy_tracker_by_value2(); + +} + +int test_flowgraph() +{ + return 0; +} + +int main ( void ) +{try{ + + //test(); + + test_copy_tracker(); + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; +}} \ No newline at end of file diff --git a/tbb_test/tbb_test.sln b/tbb_test/tbb_test.sln new file mode 100644 index 0000000..221a93b --- /dev/null +++ b/tbb_test/tbb_test.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tbb_test", "tbb_test.vcxproj", "{5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Debug|Win32.ActiveCfg = Debug|Win32 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Debug|Win32.Build.0 = Debug|Win32 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Debug|x64.ActiveCfg = Debug|x64 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Debug|x64.Build.0 = Debug|x64 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Release|Win32.ActiveCfg = Release|Win32 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Release|Win32.Build.0 = Release|Win32 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Release|x64.ActiveCfg = Release|x64 + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/tbb_test/tbb_test.vcxproj b/tbb_test/tbb_test.vcxproj new file mode 100644 index 0000000..88cd71a --- /dev/null +++ b/tbb_test/tbb_test.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {5771BE40-BCC1-4DBB-9E0B-9B0FEF85927E} + Win32Proj + tbb_test + + + + Application + true + Unicode + + + Application + true + Unicode + + + Application + false + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + + + + false + + + false + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(TBB_INCLUDE) + + + Console + true + $(TBB_LIB64) + tbb_debug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(TBB_INCLUDE) + + + Console + true + $(TBB_LIB64) + tbb_debug.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(TBB_INCLUDE) + + + Console + true + true + true + $(TBB_LIB64) + tbb.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(TBB_INCLUDE) + + + Console + true + true + true + $(TBB_LIB64) + tbb.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + \ No newline at end of file diff --git a/tbb_test/tbb_test.vcxproj.filters b/tbb_test/tbb_test.vcxproj.filters new file mode 100644 index 0000000..8755a3a --- /dev/null +++ b/tbb_test/tbb_test.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/temporary_objects.cpp b/temporary_objects.cpp new file mode 100644 index 0000000..8606607 --- /dev/null +++ b/temporary_objects.cpp @@ -0,0 +1,41 @@ +#include + +class a +{ +public: + a() + { + std::cout << "construction" << std::endl; + } + ~a() + { + std::cout << "destruction" << std::endl; + } +}; + +class guard +{ +public: + a _a; + a* operator & () + { + return &_a; + } +}; + +guard f() +{ + return guard(); +} + +void g ( a* p ) +{ + std::cout << "working with a" << std::endl; +} + +int main() +{ + g( &f() ); + + return 0; +} diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..14c1680 --- /dev/null +++ b/test.cpp @@ -0,0 +1,45 @@ +// test.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include + +#if 0 +template +class aaa +{ +public: virtual C getC() = 0; +}; + +template +class ccc : public aaa +{ +public: virtual C getC(){ return 0; } +}; + +template class ccc; +template class ccc; +template class ccc; + +class bbb : public ccc, + public ccc, + public ccc +{ +public: +// using ccc::getC; + virtual int ccc::getC() { return 1; } + virtual long long ccc::getC() { return 1; } + virtual double ccc::getC() { return 1; } +}; +#endif + +int _tmain(int argc, _TCHAR* argv[]) +{ +// bbb o; +// int i = static_cast*>(&o)->getC(); +// double d = static_cast*>(&o)->getC(); +// long long ll = static_cast*>(&o)->getC(); + std::cout << sizeof( long long ) << std::endl; + return 0; +} + diff --git a/test.sln b/test.sln new file mode 100644 index 0000000..1a9e1ea --- /dev/null +++ b/test.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcproj", "{8AFC11C5-424C-402B-B9B5-12ED039608A3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8AFC11C5-424C-402B-B9B5-12ED039608A3}.Debug|Win32.ActiveCfg = Debug|Win32 + {8AFC11C5-424C-402B-B9B5-12ED039608A3}.Debug|Win32.Build.0 = Debug|Win32 + {8AFC11C5-424C-402B-B9B5-12ED039608A3}.Release|Win32.ActiveCfg = Release|Win32 + {8AFC11C5-424C-402B-B9B5-12ED039608A3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test.vcproj b/test.vcproj new file mode 100644 index 0000000..0382fb5 --- /dev/null +++ b/test.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testConstructorCall/stdafx.cpp b/testConstructorCall/stdafx.cpp new file mode 100644 index 0000000..b2e2f51 --- /dev/null +++ b/testConstructorCall/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testConstructorCall.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testConstructorCall/stdafx.h b/testConstructorCall/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/testConstructorCall/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testConstructorCall/testConstructorCall.cpp b/testConstructorCall/testConstructorCall.cpp new file mode 100644 index 0000000..af9b696 --- /dev/null +++ b/testConstructorCall/testConstructorCall.cpp @@ -0,0 +1,52 @@ +// testConstructorCall.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +#include + +class a +{ +public: + a() + { + printf( "a\n" ); + } + + ~a() + { + printf( "~a\n" ); + } + + int f() + { + return 0; + } + + void operator delete ( void* p ) + { + printf( "operator delete()\n" ); + } +}; + +int _tmain(int argc, _TCHAR* argv[]) +{ +/* + a o; + +// o.a( 0 ); + o.~a(); + + o.f(); + + reinterpret_cast(0)->a::a(); +*/ + a* p1 = new a(); + delete p1; + + a* p2 = new a(); + a::operator delete( p2 ); + + return 0; +} + diff --git a/testConstructorCall/testConstructorCall.sln b/testConstructorCall/testConstructorCall.sln new file mode 100644 index 0000000..72a5bff --- /dev/null +++ b/testConstructorCall/testConstructorCall.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testConstructorCall", "testConstructorCall.vcproj", "{BB1AE9BF-69DD-4638-933A-2E513E939A2C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB1AE9BF-69DD-4638-933A-2E513E939A2C}.Debug|Win32.ActiveCfg = Debug|Win32 + {BB1AE9BF-69DD-4638-933A-2E513E939A2C}.Debug|Win32.Build.0 = Debug|Win32 + {BB1AE9BF-69DD-4638-933A-2E513E939A2C}.Release|Win32.ActiveCfg = Release|Win32 + {BB1AE9BF-69DD-4638-933A-2E513E939A2C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testConstructorCall/testConstructorCall.vcproj b/testConstructorCall/testConstructorCall.vcproj new file mode 100644 index 0000000..c1f2b61 --- /dev/null +++ b/testConstructorCall/testConstructorCall.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testDeviceIOWin32/stdafx.cpp b/testDeviceIOWin32/stdafx.cpp new file mode 100644 index 0000000..173c9c7 --- /dev/null +++ b/testDeviceIOWin32/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testDeviceIOWin32.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testDeviceIOWin32/stdafx.h b/testDeviceIOWin32/stdafx.h new file mode 100644 index 0000000..3444da8 --- /dev/null +++ b/testDeviceIOWin32/stdafx.h @@ -0,0 +1,23 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include +#include +#include + +#include +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testDeviceIOWin32/testDeviceIOWin32.cpp b/testDeviceIOWin32/testDeviceIOWin32.cpp new file mode 100644 index 0000000..abe5506 --- /dev/null +++ b/testDeviceIOWin32/testDeviceIOWin32.cpp @@ -0,0 +1,699 @@ +// testDeviceIOWin32.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +#include +#include +#include + +#include +#include +#include + +/* + CD + Every byte == 14bit (EFM) ?? + Small Frame == 588bit == 24 byte <== this is the unit of read. Can't read smaller portions. + +-----------+------------+--------------+-----------+--------------+-----------+ + | Sync code | Subchannel | Main Channel | CIRC code | Main Channel | CIRC code | + | | byte | data | | data | | +bit | 24+3 | 14+3 | 12x(14+3) | 4x(14+3) | 12x(14+3) | 4x(14+3) | + +-----------+------------+--------------+-----------+--------------+-----------+ + + Frame == 98 Small Frames == 2352 bytes <== this is reachable form soft. + +98 byte of subchannel ( 2 sync bytes + 96 bytes of data ) + The first 2 small frames containe sync bytes and then the rest of small frames + containe data bytes. + + + Session == Lead-in + Program Area + Lead-out + Lead-in == TOC in Q-Subchannel + Program Area == Logical Tracks (at least containes one logical track) + + + Address format is MSF (Minute/Second/Frame) M=60*S S=75*F + 1 Audio Sec = 4(Stereo 16bit)*44100(Hz)=176400 byte = 75 * 2352 byte = 75 Frame + 0<= F <= 74 + 0<= S <= 59 + 0<= M <= 99 + + +*/ + +enum { + ADDR_SEC2FRAME = 75, + ADDR_MIN2SEC = 60, + + CTRL_COPYPROT_MASK = 0x02, // 0010 + CTRL_TYPE_MASK = 0x0C, // 1100 + CTRL_AUDIO2CH_TRACK = 0x00, // + CTRL_DATA_TRACK = 0x04, // + CTRL_AUDIO4CH_TRACK = 0x06, // + CTRL_RESERVED_TRACK = 0x0C, // + CTRL_DATA_INCREMENTAL = 0x01, // + CTRL_AUDIO_50_15 = 0x01, // + + FRAME_DATA = 2352, + +}; + +#define MAXIMUM_NUMBER_TRACKS 100 +#define NSECTORS 13 +#define UNDERSAMPLING 1 +#define CB_CDDASECTOR 2368 +#define CB_QSUBCHANNEL 16 +#define CB_CDROMSECTOR 2048 +#define CB_AUDIO (CB_CDDASECTOR-CB_QSUBCHANNEL) + +/* The code of interest is in the subroutine GetDriveGeometry. The + code in main shows how to interpret the results of the call. */ + +class device +{ +protected: + + // Handle to the drive to be examined. + HANDLE hDevice; + + DISK_GEOMETRY dg; + CDROM_TOC toc; + + bool m_bLocked; + +public: + + device() + { + hDevice = INVALID_HANDLE_VALUE; + m_bLocked = false; + } + + ~device() + { + if ( hDevice != INVALID_HANDLE_VALUE ) + { + if ( m_bLocked ) + storageMediaUnlock(); + close(); + } + } + + bool create( const TCHAR* pszDevice ) + { + hDevice = ::CreateFile(pszDevice, // drive to open + GENERIC_READ | + GENERIC_WRITE , // no access to the drive + FILE_SHARE_READ | // share mode + FILE_SHARE_WRITE, + NULL, // default security attributes + OPEN_EXISTING, // disposition + 0, // file attributes + NULL); // do not copy file attributes + if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive + { + printErr("CreateFile"); + return false; + } + + return true; + } + + bool close() + { + if ( hDevice != INVALID_HANDLE_VALUE ) + { + ::CloseHandle(hDevice); + hDevice = INVALID_HANDLE_VALUE; + } + + return true; + } + + static void printErr( char* szMsg = "" ) + { + printf ("%s Error %ld. ", szMsg, GetLastError ()); + + char szMsgBfr[ 1024 ]; + ::FormatMessageA( + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + GetLastError (), + 0, // Default language + szMsgBfr, + sizeof( szMsgBfr ), + NULL ); + szMsgBfr[sizeof( szMsgBfr )-1] = 0; + + puts ( szMsgBfr ); + } + + bool diskGetDriveGeometry() + { + DWORD junk; // discard results + + printf("IOCTL_DISK_GET_DRIVE_GEOMETRY\n"); + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform + NULL, 0, // no input buffer + &dg, sizeof(dg), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + else + { + printf("MediaType = %d\n", dg.MediaType); + printf("Cylinders = %I64d\n", dg.Cylinders); + printf("Tracks/cylinder = %ld\n", (ULONG) dg.TracksPerCylinder); + printf("Sectors/track = %ld\n", (ULONG) dg.SectorsPerTrack); + printf("Bytes/sector = %ld\n", (ULONG) dg.BytesPerSector); + + ULONGLONG DiskSize = dg.Cylinders.QuadPart * (ULONG)dg.TracksPerCylinder * + (ULONG)dg.SectorsPerTrack * (ULONG)dg.BytesPerSector; + printf("Disk size = %I64d (Bytes) = %I64d (Gb)\n", DiskSize, + DiskSize / (1024 * 1024 * 1024)); + } + puts(""); + + return true; + } + + bool diskGetCacheInformation() + { + DWORD junk; // discard results + DISK_CACHE_INFORMATION dci; + + printf("IOCTL_DISK_GET_CACHE_INFORMATION\n"); + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_DISK_GET_CACHE_INFORMATION, // operation to perform + NULL, 0, // no input buffer + &dci, sizeof(dci), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + else + { + printf("ParametersSavable = %d\n", dci.ParametersSavable); + printf("ReadCacheEnabled = %d\n", dci.ReadCacheEnabled); + printf("WriteCacheEnabled = %d\n", dci.WriteCacheEnabled); + printf("ReadRetentionPriority = %d\n", dci.ReadRetentionPriority); + printf("WriteRetentionPriority = %d\n", dci.WriteRetentionPriority); + printf("DisablePrefetchTransferLength = %d\n", dci.DisablePrefetchTransferLength); + if ( dci.PrefetchScalar ) + { + printf("ScalarPrefetch.Minimum = %d\n", dci.ScalarPrefetch.Minimum); + printf("ScalarPrefetch.Maximum = %d\n", dci.ScalarPrefetch.Maximum); + printf("ScalarPrefetch.MaximumBlocks = %d\n", dci.ScalarPrefetch.MaximumBlocks); + } + else + { + printf("BlockPrefetch.Minimum = %d\n", dci.BlockPrefetch.Minimum); + printf("BlockPrefetch.Maximum = %d\n", dci.BlockPrefetch.Maximum); + } + } + puts(""); + + return true; + } + + bool diskPerformance() + { + DWORD junk; // discard results + DISK_PERFORMANCE dp; + + printf("IOCTL_DISK_PERFORMANCE\n"); + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_DISK_PERFORMANCE, // operation to perform + NULL, 0, // no input buffer + &dp, sizeof(dp), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + else + { + printf("BytesRead = %I64d\n", dp.BytesRead); + printf("BytesWritten = %I64d\n", dp.BytesWritten); + printf("ReadTime = %I64d\n", dp.ReadTime); + printf("WriteTime = %I64d\n", dp.WriteTime); + printf("IdleTime = %I64d\n", dp.IdleTime); + printf("ReadCount = %d\n", dp.ReadCount); + printf("WriteCount = %d\n", dp.WriteCount); + printf("QueueDepth = %d\n", dp.QueueDepth); + printf("SplitCount = %d\n", dp.SplitCount); + printf("QueryTime = %I64d\n", dp.QueryTime); + printf("StorageDeviceNumber = %d\n", dp.StorageDeviceNumber); + printf("StorageManagerName = %c%c%c%c%c%c%c%c\n", + dp.StorageManagerName[0], dp.StorageManagerName[1], + dp.StorageManagerName[2], dp.StorageManagerName[3], + dp.StorageManagerName[4], dp.StorageManagerName[5], + dp.StorageManagerName[6], dp.StorageManagerName[7]); + } + puts(""); + + ////////////////////////////////////////////////////////////////////////////// + printf("IOCTL_DISK_PERFORMANCE_OFF\n"); + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_DISK_PERFORMANCE_OFF, // operation to perform + NULL, 0, // no input buffer + 0, 0, // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + puts(""); + + return true; + } + + bool diskVerify() + { + DWORD junk; // discard results + VERIFY_INFORMATION vi; + + printf("IOCTL_DISK_VERIFY\n"); + vi.StartingOffset.QuadPart = 0; + vi.Length = 2048; + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_DISK_VERIFY, // operation to perform + &vi, sizeof(vi), // no input buffer + 0, 0, // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + puts(""); + + return true; + } + + bool storageMediaLock() + { + DWORD junk; // discard results + PREVENT_MEDIA_REMOVAL pmr; + pmr.PreventMediaRemoval = 1; + + printf("IOCTL_STORAGE_MEDIA_REMOVAL lock\n"); + if ( !::DeviceIoControl( hDevice, + IOCTL_STORAGE_MEDIA_REMOVAL, + &pmr, sizeof( pmr ), + 0, 0, + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + + m_bLocked = true; + return true; + } + + bool storageMediaUnlock() + { + DWORD junk; // discard results + PREVENT_MEDIA_REMOVAL pmr; + pmr.PreventMediaRemoval = 0; + + printf("IOCTL_STORAGE_MEDIA_REMOVAL unlock\n"); + if ( !::DeviceIoControl( hDevice, + IOCTL_STORAGE_MEDIA_REMOVAL, + &pmr, sizeof( pmr ), + 0, 0, + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + + m_bLocked = false; + return true; + } + + bool storageLoadMedia() + { + DWORD junk; // discard results + + printf("IOCTL_STORAGE_LOAD_MEDIA\n"); + if ( !::DeviceIoControl( hDevice, + IOCTL_STORAGE_LOAD_MEDIA, + 0, 0, + 0, 0, + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + else + { +// printf(""); + } + + return true; + } + + bool storageCheckVerify() + { + DWORD junk; // discard results + + printf("IOCTL_STORAGE_CHECK_VERIFY\n"); + if ( !::DeviceIoControl( hDevice, + IOCTL_STORAGE_CHECK_VERIFY, + 0, 0, + 0, 0, + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + else + { +// printf(""); + } + + return true; + } + + bool storageEjectMedia() + { + DWORD junk; // discard results + + printf("IOCTL_STORAGE_EJECT_MEDIA\n"); + if ( !::DeviceIoControl( hDevice, + IOCTL_STORAGE_EJECT_MEDIA, + 0, 0, + 0, 0, + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + else + { +// printf(""); + } + + return true; + } + + bool storageReadCapacity() + { +// 2003 +#if 0 + DWORD junk; // discard results + + STORAGE_READ_CAPACITY src; + printf("IOCTL_STORAGE_READ_CAPACITY\n"); + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_STORAGE_READ_CAPACITY, // operation to perform + NULL, 0, // no input buffer + &src, sizeof(src), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + return false; + } + else + { + printf("Version = %d\n", src.Version); + printf("Size = %d\n", src.Size); + printf("BlockLength = %d\n", src.BlockLength); + printf("NumberOfBlocks = %I64d\n", dg.NumberOfBlocks); + printf("DiskLength = %I64d\n", dg.DiskLength); + } + puts(""); +#endif + return true; + } + + bool cdromDiskInfo() + { +#if 0 + DWORD junk; // discard results + printf("IOCTL_CDROM_DISC_INFO\n"); + CDROM_DISCINFO cdi; + if ( !DeviceIoControl( hDevice, // device to be queried + IOCTL_CDROM_DISC_INFO, // operation to perform + 0, 0, // no input buffer + &cdi, sizeof( cdi ), // output buffer + &junk, // # bytes returned + (LPOVERLAPPED) NULL) ) // synchronous I/O + { + printErr(""); + } + else + { + printf("Reserved = %I64d\n", cdi.Reserved ); + printf("FirstTrack = %I64d\n", cdi.FirstTrack ); + printf("LastTrack = %I64d\n", cdi.LastTrack ); + printf("LastTrack = %I64d\n", cdi.LeadOutTrackAddr ); + printf("FirstSession = %I64d\n", cdi.FirstSession ); + printf("LastSession = %I64d\n", cdi.LastSession ); + printf("ReqSession = %I64d\n", cdi.ReqSession ); + printf("RetSession = %I64d\n", cdi.RetSession ); + printf("LogicStartAddr = %I64d\n", cdi.LogicStartAddr ); + } + puts(""); +#endif + } + + + bool cdromReadTOC() + { + DWORD junk; // discard results + printf("IOCTL_CDROM_READ_TOC\n"); + + if ( !::DeviceIoControl( hDevice, + IOCTL_CDROM_READ_TOC, + 0, 0, + &toc, sizeof(toc), + &junk, + (LPOVERLAPPED)0 ) ) + { + printErr(""); + return false; + } + else + { + std::cout << "Length = " << (USHORT&)toc.Length << std::endl; + std::cout << "FirstTrack = " << int(toc.FirstTrack) << std::endl; + std::cout << "LastTrack = " << int(toc.LastTrack) << std::endl; + for ( int i = 0; i < (toc.LastTrack - toc.FirstTrack +1); ++i ) + { + std::cout << "track " << i << " {" << std::endl; + + if ( toc.TrackData[i].Control & CTRL_COPYPROT_MASK ) + std::cout << " No copy protection" << std::endl; + else + std::cout << " Copy protected" << std::endl; + + int n = toc.TrackData[i].Control & CTRL_TYPE_MASK; + if ( n == CTRL_AUDIO2CH_TRACK ) + std::cout << " 2 channel audio track" << std::endl; + else if ( n == CTRL_AUDIO4CH_TRACK ) + std::cout << " 4 channel audio track" << std::endl; + else if ( n == CTRL_DATA_TRACK ) + std::cout << " Data track" << std::endl; + else + std::cout << " Unknown type of track" << std::endl; + + if ( n == CTRL_DATA_TRACK ) + { + if ( toc.TrackData[i].Control & CTRL_DATA_INCREMENTAL ) + std::cout << " Incremental record" << std::endl; + else + std::cout << " Continuous record" << std::endl; + } + else + { + if ( toc.TrackData[i].Control & CTRL_AUDIO_50_15 ) + std::cout << " Predistortion 50/15 mks" << std::endl; + else + std::cout << " No predistortion" << std::endl; + } + + std::cout << " Adr = " << int(toc.TrackData[i].Adr) << std::endl; + std::cout << " TrackNumber = " << int(toc.TrackData[i].TrackNumber) << std::endl; + std::cout << " Address[0] = " << int(toc.TrackData[i].Address[0]) << std::endl; + std::cout << " Minute = " << int(toc.TrackData[i].Address[1]) << std::endl; + std::cout << " Second = " << int(toc.TrackData[i].Address[2]) << std::endl; + std::cout << " Frame = " << int(toc.TrackData[i].Address[3]) << std::endl; + std::cout << " Start Sector = " << toc.TrackData[i].Address[1] * ADDR_MIN2SEC * ADDR_SEC2FRAME + + toc.TrackData[i].Address[2] * ADDR_SEC2FRAME + + toc.TrackData[i].Address[3] << std::endl; + std::cout << "}" << std::endl; + + } + } + + return true; + } + + virtual int cdromRawRead( int sector, int num, char* buf, int buf_size ); + +}; + +int device::cdromRawRead( int sector, int num, char* buf, int buf_size ) +{ + DWORD nBytsRead = 0; + + RAW_READ_INFO rri; +// rri.TrackMode = CDDA; + rri.TrackMode = YellowMode2; + rri.SectorCount = num; + rri.DiskOffset.QuadPart = sector*CB_CDROMSECTOR; + + memset ( buf, 0, buf_size ); + +#if 1 +// std::cout << "IOCTL_CDROM_RAW_READ" << std::endl; + if ( !::DeviceIoControl( hDevice, + IOCTL_CDROM_RAW_READ, + &rri, sizeof(rri), + buf, buf_size, + &nBytsRead, + (LPOVERLAPPED)0 ) ) + { + int i = 0; + char tmp[32]; + + for ( ; i < buf_size && !buf[i]; ++i ); + if ( i < buf_size ) + _snprintf( tmp, sizeof( tmp), "Sector %d buf!=0", sector ); + else + _snprintf( tmp, sizeof( tmp), "Sector %d", sector ); + + printErr( tmp ); + return false; + } + else +#endif + { +#if 0 + std::cout << " Read " << nBytsRead << " bytes" << std::endl; + const int cCol = 16; + for ( int i = 0; i < int(nBytsRead) ; ) + { + int k = i; + for ( int j = 0; j < cCol && k < int(nBytsRead); ++k, ++j ) + { + std::cout << std::hex << (((unsigned)( buf[k] ) >> 4) & 0xF ) << ((unsigned)( buf[k] ) & 0x0F ) << " "; + } + + for ( int j = 0; j < cCol && i < int(nBytsRead); ++i, ++j ) + { + if ( 32 < buf[i] && buf[i] < 255 ) + std::cout << buf[i]; + else + std::cout << ' '; + } + + std::cout << std::endl; + } +#endif + } + + // CB_CDROMSECTOR +#if 0 + if (m_bTocValid && ((sector + NumSectors) <= GetEndSector(m_TOC.LastTrack))) + { + RAW_READ_INFO rri; + rri.TrackMode = CDDA; + rri.SectorCount = (DWORD)NumSectors; + rri.DiskOffset.QuadPart = sector*CB_CDROMSECTOR; + + DWORD charsRead = 0; + if (::DeviceIoControl(m_hDrive, IOCTL_CDROM_RAW_READ, &rri, sizeof(rri), Buffer, (DWORD)NumSectors * CB_AUDIO, &charsRead, NULL) != 0) + return true; + else + return false; + } + else + return false; +#endif + return nBytsRead; +} + + +int _tmain(int argc, _TCHAR* argv[]) +{ +//TCHAR szDevice[] = L"\\\\.\\PhysicalDrive0"; +//TCHAR szDevice[] = L"\\\\.\\PhysicalDrive2"; +TCHAR szDevice[] = L"\\\\.\\E:"; + + FILE* f = fopen( "dump.txt", "wb" ); + + device d; + + if ( !d.create( szDevice ) ) + { + std::cerr << "Cannot open device." << std::endl; + return 1; + } + + if ( !d.storageCheckVerify() ) + { + std::cerr << "Media is not accessable." << std::endl; + return 2; + } + + if ( !d.storageMediaLock() ) + { + std::cerr << "Cannot lock the media." << std::endl; + return 3; + } + +// d.diskGetDriveGeometry(); +// d.storageReadCapacity(); +// d.diskGetCacheInformation(); +// d.diskPerformance(); + +// d.cdromDiskInfo(); + d.cdromReadTOC(); + + const int nStart = 000; + const int nAmount = nStart + 350000; + int i = nStart; + char buf[ 2*FRAME_DATA ]; + for ( ; i < nAmount; ++i ) + { + int n = d.cdromRawRead( i, 1, buf, sizeof( buf ) ); +// fwrite( buf, 1, n, f ); + } + + d.storageMediaUnlock(); + d.storageMediaUnlock(); + d.storageMediaUnlock(); + d.storageMediaUnlock(); + d.storageMediaUnlock(); + d.storageMediaUnlock(); + +// d.storageEjectMedia(); + + d.close(); + + fclose( f ); + + return 0; +} + + + diff --git a/testDeviceIOWin32/testDeviceIOWin32.sln b/testDeviceIOWin32/testDeviceIOWin32.sln new file mode 100644 index 0000000..ce77802 --- /dev/null +++ b/testDeviceIOWin32/testDeviceIOWin32.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testDeviceIOWin32", "testDeviceIOWin32.vcproj", "{E94938D0-9C6D-4792-824D-919AC911027C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E94938D0-9C6D-4792-824D-919AC911027C}.Debug|Win32.ActiveCfg = Debug|Win32 + {E94938D0-9C6D-4792-824D-919AC911027C}.Debug|Win32.Build.0 = Debug|Win32 + {E94938D0-9C6D-4792-824D-919AC911027C}.Release|Win32.ActiveCfg = Release|Win32 + {E94938D0-9C6D-4792-824D-919AC911027C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testDeviceIOWin32/testDeviceIOWin32.vcproj b/testDeviceIOWin32/testDeviceIOWin32.vcproj new file mode 100644 index 0000000..71244f8 --- /dev/null +++ b/testDeviceIOWin32/testDeviceIOWin32.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testLong64.cpp b/testLong64.cpp new file mode 100644 index 0000000..c7f1694 --- /dev/null +++ b/testLong64.cpp @@ -0,0 +1,19 @@ +// testLong64.cpp : Defines the entry point for the console application. +// + +//#include "stdafx.h" + +#include + +//#define long __int64 + +int main(int argc, char * argv[]) +{ + std::cout << "short " << sizeof( short ) << std::endl; + std::cout << "int " << sizeof( int ) << std::endl; + std::cout << "long " << sizeof( long ) << std::endl; + std::cout << "long long " << sizeof( long long ) << std::endl; + std::cout << "void* " << sizeof( void* ) << std::endl; + return 0; +} + diff --git a/testMultipleDerviation/stdafx.cpp b/testMultipleDerviation/stdafx.cpp new file mode 100644 index 0000000..3c9199e --- /dev/null +++ b/testMultipleDerviation/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testMultipleDerviation.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testMultipleDerviation/stdafx.h b/testMultipleDerviation/stdafx.h new file mode 100644 index 0000000..22809e8 --- /dev/null +++ b/testMultipleDerviation/stdafx.h @@ -0,0 +1,19 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testMultipleDerviation/testMultipleDerviation.cpp b/testMultipleDerviation/testMultipleDerviation.cpp new file mode 100644 index 0000000..80e0073 --- /dev/null +++ b/testMultipleDerviation/testMultipleDerviation.cpp @@ -0,0 +1,124 @@ +// testMultipleDerviation.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +class a +{ +public: + virtual void f() = 0; +}; + +class b : public virtual a +{ +public: + virtual void g() = 0; +}; + +class c : public virtual a +{ + int n; + +public: + c() + { n = 0; } + + virtual void f() + { ++n; } +}; + +class d : public b, public c +{ +public: +// virtual void f() +// { +// c::f(); +// } + + virtual void g() + { + puts( "d::g()" ); + } +}; + +class a2 +{ +public: + virtual void f() = 0; +}; + +class b2 : public virtual a +{ +public: + virtual void g() = 0; +}; + +class c2 : public a2 +{ + int n; + +public: + c2() + { n = 0; } + + virtual void f() + { ++n; } +}; + +class d2 : public b2, public c2 +{ +public: + virtual void f() + { + c2::f(); + } + + virtual void g() + { + puts( "d::g()" ); + } +}; + + +int main(int argc, _TCHAR* argv[]) +{ + const int nAmount = 1000000000; + + d o; + d2 o2; + + int nWins1 = 0; + int nWins2 = 0; + + for ( ; true ; ) + { + DWORD dwStart = GetTickCount(); + + for ( register int n = nAmount; n; --n ) + o.f(); + + DWORD dwDuration = GetTickCount() - dwStart; + printf( "Virtual inheritence takes %dms\n", dwDuration ); + + + + DWORD dwStart2 = GetTickCount(); + + for ( register int n = nAmount; n; --n ) + o2.f(); + + DWORD dwDuration2 = GetTickCount() - dwStart2; + printf( "Redirection of function %dms\n", dwDuration2 ); + + if ( dwDuration2 > dwDuration ) + ++nWins1; + else + ++nWins2; + + printf( "count %d : %d\n\n", nWins1, nWins2 ); + } + + + return 0; +} + diff --git a/testMultipleDerviation/testMultipleDerviation.sln b/testMultipleDerviation/testMultipleDerviation.sln new file mode 100644 index 0000000..3c90091 --- /dev/null +++ b/testMultipleDerviation/testMultipleDerviation.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testMultipleDerviation", "testMultipleDerviation.vcproj", "{79D765B8-B695-498E-B1E2-BDC2A6474311}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {79D765B8-B695-498E-B1E2-BDC2A6474311}.Debug|Win32.ActiveCfg = Debug|Win32 + {79D765B8-B695-498E-B1E2-BDC2A6474311}.Debug|Win32.Build.0 = Debug|Win32 + {79D765B8-B695-498E-B1E2-BDC2A6474311}.Release|Win32.ActiveCfg = Release|Win32 + {79D765B8-B695-498E-B1E2-BDC2A6474311}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testMultipleDerviation/testMultipleDerviation.vcproj b/testMultipleDerviation/testMultipleDerviation.vcproj new file mode 100644 index 0000000..cf51abb --- /dev/null +++ b/testMultipleDerviation/testMultipleDerviation.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testOutputIterator/stdafx.cpp b/testOutputIterator/stdafx.cpp new file mode 100644 index 0000000..b738d19 --- /dev/null +++ b/testOutputIterator/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testOutputIterator.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testOutputIterator/stdafx.h b/testOutputIterator/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/testOutputIterator/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testOutputIterator/testOutputIterator.cpp b/testOutputIterator/testOutputIterator.cpp new file mode 100644 index 0000000..6ca6ed0 --- /dev/null +++ b/testOutputIterator/testOutputIterator.cpp @@ -0,0 +1,37 @@ +// testOutputIterator.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include +#include +#include + + +int _tmain(int argc, _TCHAR* argv[]) +{ +#if 0 + std::vector v; + std::vector::iterator ot = v.begin(); + + *++ot = 1; + *++ot = 2; + *++ot = 3; + *++ot = 4; +#endif + + std::list l; + l.push_back( 1 ); + l.push_back( 2 ); +// l.splice( l.begin(), l, l.begin() ); + + std::cout << &(*l.begin()) << " " << &(*++l.begin()) << " " << *l.begin() << " " << *++l.begin() << std::endl; + + std::swap( l.begin(), ++l.begin() ); + + std::cout << &(*l.begin()) << " " << &(*++l.begin()) << " " << *l.begin() << " " << *++l.begin() << std::endl; + + + + return 0; +} + diff --git a/testOutputIterator/testOutputIterator.sln b/testOutputIterator/testOutputIterator.sln new file mode 100644 index 0000000..9c831ab --- /dev/null +++ b/testOutputIterator/testOutputIterator.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testOutputIterator", "testOutputIterator.vcproj", "{2F4EF401-584C-4DD9-B360-115A4620CF89}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2F4EF401-584C-4DD9-B360-115A4620CF89}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F4EF401-584C-4DD9-B360-115A4620CF89}.Debug|Win32.Build.0 = Debug|Win32 + {2F4EF401-584C-4DD9-B360-115A4620CF89}.Release|Win32.ActiveCfg = Release|Win32 + {2F4EF401-584C-4DD9-B360-115A4620CF89}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testOutputIterator/testOutputIterator.vcproj b/testOutputIterator/testOutputIterator.vcproj new file mode 100644 index 0000000..5d563ad --- /dev/null +++ b/testOutputIterator/testOutputIterator.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testProtectedVirtInheritence/stdafx.cpp b/testProtectedVirtInheritence/stdafx.cpp new file mode 100644 index 0000000..734d395 --- /dev/null +++ b/testProtectedVirtInheritence/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testProtectedVirtInheritence.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testProtectedVirtInheritence/stdafx.h b/testProtectedVirtInheritence/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/testProtectedVirtInheritence/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testProtectedVirtInheritence/testProtectedVirtInheritence.cpp b/testProtectedVirtInheritence/testProtectedVirtInheritence.cpp new file mode 100644 index 0000000..e8b6b2f --- /dev/null +++ b/testProtectedVirtInheritence/testProtectedVirtInheritence.cpp @@ -0,0 +1,59 @@ +// testProtectedVirtInheritence.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +class B; + +class A +{ + friend class B; +private: + A() + { + puts("A::A"); + } +}; + +class B : public virtual A +{ +public: + B() + { + puts("B::B"); + } +}; + +class C : public B +{ +public: + C() + { + puts("C::C"); + } +}; + +class D : public B +{ +public: + D() + { + puts("D::D"); + } +}; + +class E : public C, public D +{ +public: + E() + { + puts("E::E"); + } +}; + +int _tmain(int argc, _TCHAR* argv[]) +{ + E o; + return 0; +} + diff --git a/testProtectedVirtInheritence/testProtectedVirtInheritence.sln b/testProtectedVirtInheritence/testProtectedVirtInheritence.sln new file mode 100644 index 0000000..c42b1af --- /dev/null +++ b/testProtectedVirtInheritence/testProtectedVirtInheritence.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testProtectedVirtInheritence", "testProtectedVirtInheritence.vcproj", "{DB37A195-3F0B-4EEE-9A17-E08DF81C7AAB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DB37A195-3F0B-4EEE-9A17-E08DF81C7AAB}.Debug|Win32.ActiveCfg = Debug|Win32 + {DB37A195-3F0B-4EEE-9A17-E08DF81C7AAB}.Debug|Win32.Build.0 = Debug|Win32 + {DB37A195-3F0B-4EEE-9A17-E08DF81C7AAB}.Release|Win32.ActiveCfg = Release|Win32 + {DB37A195-3F0B-4EEE-9A17-E08DF81C7AAB}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testProtectedVirtInheritence/testProtectedVirtInheritence.vcproj b/testProtectedVirtInheritence/testProtectedVirtInheritence.vcproj new file mode 100644 index 0000000..b43c204 --- /dev/null +++ b/testProtectedVirtInheritence/testProtectedVirtInheritence.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testStaticCast.cpp b/testStaticCast.cpp new file mode 100644 index 0000000..3e36481 --- /dev/null +++ b/testStaticCast.cpp @@ -0,0 +1,132 @@ +#include + +template const char* tn( C ) { return "unknown"; } +template <> const char* tn( int ) { return "int"; } +template <> const char* tn( long ) { return "long"; } + +template +class a +{ +public: + virtual void f( C n ) + { + std::cout << "a<" << tn( n ) << ">::f(" << tn( n ) << ")" << std::endl; + } + + a* getA( C ) + { + return this; + } +}; + +template +class b : virtual public a +{ +public: + virtual void f( C n ) + { + a::f( n ); + std::cout << "b<" << tn( n ) << ">::(" << tn( n )<< ")" << std::endl; + } +}; + +class c : public b, public b +{ +public: + virtual void f( int n ) + { return f_impl( n ); } + virtual void f( long n ) + { return f_impl( n ); } + + template + void f_impl( D n ) + { + b::f( n ); + std::cout << "c::f(" << tn( n ) << ")" << std::endl; + } + + using a::getA; + using a::getA; +/* + virtual a* getA( int n ) + { + return b::getA( n ); + } + virtual a* getA( long n ) + { + return b::getA( n ); + } +*/ +}; + +class d : public c +{ +public: + virtual void f( int n ) + { return f_impl( n ); } + virtual void f( long n ) + { return f_impl( n ); } + + template + void f_impl( D n ) + { + c::f( n ); + std::cout << "d::f(" << tn( n )<< ")" << std::endl; + } +}; + +void test_cast( c* p ) +{ + b* bi = p; + b* bl = p; + + a* ai = p; + a* al = p; + + a* bai = bi; + a* bal = bl; + + a* gai = p->getA( int(0) ); + a* gal = p->getA( long(0) ); + + a* dai = dynamic_cast*>(p); + a* dal = dynamic_cast*>(p); + b* dbi = dynamic_cast*>(p); + b* dbl = dynamic_cast*>(p); + + a* sai = static_cast*>(p); + a* sal = static_cast*>(p); + b* sbi = static_cast*>(p); + b* sbl = static_cast*>(p); + + p->f( long(0) ); + std::cout << "=================>calling p->f( long )" << std::endl; + al->f( long(0) ); + std::cout << "=================>calling al->f( long )" << std::endl; + + std::cout << "dai=" << dai << " dal=" << dal << std::endl; + std::cout << "sai=" << sai << " sal=" << sal << std::endl; + std::cout << "bai=" << bai << " bal=" << bal << std::endl; + std::cout << "gai=" << gai << " gal=" << gal << std::endl; + std::cout << " ai=" << ai << " al=" << al << std::endl; + std::cout << "dbi=" << dbi << " dbl=" << dbl << std::endl; + std::cout << "sbi=" << sbi << " sbl=" << sbl << std::endl; + std::cout << " bi=" << bi << " bl=" << bl << std::endl; + std::cout << " p=" << p << std::endl; +} + +int main ( void ) +{ + d d_o; + c c_o; + + test_cast( &c_o ); + std::cout << "&c_o=" << &c_o << std::endl; + std::cout << std::endl + << "------------------------------------------" << std::endl; + test_cast( &d_o ); + std::cout << "&d_o=" << &d_o << std::endl; + + return 0; +} + diff --git a/testTemplate/testTemplate.sln b/testTemplate/testTemplate.sln new file mode 100644 index 0000000..55fc2c3 --- /dev/null +++ b/testTemplate/testTemplate.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testTemplate", "testTemplate\testTemplate.vcproj", "{3BE8B06E-AB57-42B1-AF54-D91EB3C0D1E3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3BE8B06E-AB57-42B1-AF54-D91EB3C0D1E3}.Debug|Win32.ActiveCfg = Debug|Win32 + {3BE8B06E-AB57-42B1-AF54-D91EB3C0D1E3}.Debug|Win32.Build.0 = Debug|Win32 + {3BE8B06E-AB57-42B1-AF54-D91EB3C0D1E3}.Release|Win32.ActiveCfg = Release|Win32 + {3BE8B06E-AB57-42B1-AF54-D91EB3C0D1E3}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testTemplate/testTemplate/stdafx.cpp b/testTemplate/testTemplate/stdafx.cpp new file mode 100644 index 0000000..de2683f --- /dev/null +++ b/testTemplate/testTemplate/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testTemplate.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testTemplate/testTemplate/stdafx.h b/testTemplate/testTemplate/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/testTemplate/testTemplate/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testTemplate/testTemplate/testTemplate.cpp b/testTemplate/testTemplate/testTemplate.cpp new file mode 100644 index 0000000..7b327c4 --- /dev/null +++ b/testTemplate/testTemplate/testTemplate.cpp @@ -0,0 +1,46 @@ +// testTemplate.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + +class a +{ +public: + + template < void (a::*f)( void ) > + void g() + { + (this->*f)(); + } + + void f1() + { + puts( "a::f1()" ); + } + + void f2() + { + puts( "a::f2()" ); + } + + void g1() + { + g<&a::f1>(); + } + + void g2() + { + g<&a::f2>(); + } +}; + +int _tmain(int argc, _TCHAR* argv[]) +{ + a o; + + o.g1(); + o.g2(); + + return 0; +} + diff --git a/testTemplate/testTemplate/testTemplate.vcproj b/testTemplate/testTemplate/testTemplate.vcproj new file mode 100644 index 0000000..9f26d1e --- /dev/null +++ b/testTemplate/testTemplate/testTemplate.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testTransform/_transform.cpp b/testTransform/_transform.cpp new file mode 100644 index 0000000..559e2c8 --- /dev/null +++ b/testTransform/_transform.cpp @@ -0,0 +1,1582 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#include "base/type-traits2.h" +#include "ssetypes.h" + +#include "transform.h" +#include "base/constants.h" + +namespace base +{ + + const stdOrientEnum inverseStdOrient[stdOrientMAX] = + { + R0, + R270, + R180, + R90, + XFlipR0, + XFlipR90, + XFlipR180, + XFlipR270 + }; + /* In Aix64 platform char is by default unsigned this causes difference in values, ensuring signed char array */ + const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2] = + { + // + /// R0: 0 degree rotation with no flip. + /// Coefficients = | 1 0| + /// | 0 1| + // + {{1, 0}, + {0, 1}}, + // + /// R90: 90 degree rotation with no flip. + /// Coefficients = | 0 1| + /// |-1 0| + // + {{0, 1}, + {-1, 0}}, + // + /// R180: 180 degree rotation with no flip. + /// Coefficients = |-1 0| + /// | 0 -1| + // + {{-1, 0}, + {0, -1}}, + // + /// R270: 270 degree rotation with no flip. + /// Coefficients = | 0 -1| + /// | 1 0| + // + {{0, -1}, + {1, 0}}, + // + /// XFlipR0: X flip followed by 0 degree rotation. + /// Coefficients = | 1 0| + /// | 0 -1| + // + {{1, 0}, + {0, -1}}, + // + /// X flip followed by 90 degree rotation. + /// Coefficients = | 0 1| + /// | 1 0| + // + {{0, 1}, + {1, 0}}, + // + /// X flip followed by 180 degree rotation. + /// Coefficients = |-1 0| + /// | 0 1| + // + {{-1, 0}, + {0, 1}}, + // + /// X flip followed by 270 degree rotation. + /// Coefficients = | 0 -1| + /// |-1 0| + // + {{0, -1}, + {-1, 0}} + }; + // + /// Matrix for multiplying standard orientations. + // + const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX] = { + // R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270 + /* R0 */ { R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270}, + /* R90 */ { R90, R180, R270, R0, XFlipR270, XFlipR0, XFlipR90, XFlipR180}, + /* R180 */ { R180, R270, R0, R90, XFlipR180, XFlipR270, XFlipR0, XFlipR90}, + /* R270 */ { R270, R0, R90, R180, XFlipR90, XFlipR180, XFlipR270, XFlipR0}, + /* XFlipR0 */ { XFlipR0, XFlipR90, XFlipR180, XFlipR270, R0, R90, R180, R270}, + /* XFlipR90 */ { XFlipR90, XFlipR180, XFlipR270, XFlipR0, R270, R0, R90, R180}, + /* XFlipR180 */ { XFlipR180, XFlipR270, XFlipR0, XFlipR90, R180, R270, R0, R90}, + /* XFlipR270 */ { XFlipR270, XFlipR0, XFlipR90, XFlipR180, R90, R180, R270, R0} + }; + + + pModifyFunDblToShort modifyDblToShortFunTbl[transformTypeMAX]; + pModifyFunLongToShort modifyLongToShortFunTbl[transformTypeMAX]; + pModifyFunIntToShort modifyIntToShortFunTbl[transformTypeMAX]; + pModifyFunDblToInt modifyDblToIntFunTbl[transformTypeMAX]; + pModifyFunDblToDbl modifyDblToDblFunTbl[transformTypeMAX]; + pModifyFunLongToInt modifyLongToIntFunTbl[transformTypeMAX]; + pModifyFunIntToInt modifyIntToIntFunTbl[transformTypeMAX]; + pModifyFunLongToLong modifyLongToLongFunTbl[transformTypeMAX]; + pModifyRectFunLongToLong modifyRectLongToLongFunTbl[transformTypeMAX]; + pModifyRectFunDblToDbl modifyRectDblToDblFunTbl[transformTypeMAX]; + pModifyRectFunIntToInt modifyRectIntToIntFunTbl[transformTypeMAX]; + + // + /// Table of inverse determining functions by transform type. + // + pGetInverseFun getInverseFnTbl[transformTypeMAX]; + + // + /// Table of multiplication determining functions by transform type. + // + pMultFun multFnTbl[transformTypeMAX*transformTypeMAX]; + + // + /// Modify a point using scale transform. + // + template + pod::point GXX_HIDDEN modifyScale( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + // + /// Modify a point using scale and offset transform. + // + template + pod::point GXX_HIDDEN modifyScaleOffset( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal() + T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + // + /// Modify a point using a general transform. + // + template + pod::point GXX_HIDDEN modifyGeneral( const transform & T, pod::point xy ) + { + pod::point tmp(T.getCol1()*pod::point(xy),T.getCol2()*pod::point(xy)); + tmp += T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::round(tmp.X()),(oC)base::round(tmp.Y())); + } + + template + pod::point GXX_HIDDEN modifyStd ( const transform & T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::round(d.getX()), (oC)base::round(d.getY())); + } + // + /// Modify a point using standard transform with magnification + // + template + pod::point GXX_HIDDEN modifyStdMag( const transform &T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() * T.get11() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::round(d.getX()), (oC)base::round(d.getY())); + } + // + /// Modify a point using resolution transform. + // + template + pod::point GXX_HIDDEN modifyResolution( const transform &T, pod::point xy ) + { + pod::point tmp = xy % T.getDiagonal(); + if (T.getNext()) { + if (std::tr1::is_double::value) { + pod::point tmp2 = pod::point((double)tmp.X(), + (double)tmp.Y()); + return T.getNext()->modifyDblToDbl(tmp2); + } else if (std::tr1::is_long::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToLong(tmp2); + } else if (std::tr1::is_int::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToInt(tmp2); + } else if (std::tr1::is_short::value) { + pod::point tmp2 = pod::point((long)base::round(tmp.X()), + (long)base::round(tmp.Y())); + return T.getNext()->modifyLongToShort(tmp2); + } + } else + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) : + pod::point((oC)base::round(tmp.X()), + (oC)base::round(tmp.Y())); + // Should not get here or something is missing. + throw except::programError(); + return pod::point((oC)0, (oC)0); + } + // + // Modify a rectangle using scale transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScale(T,r.getLowerLeft()), + modifyScale(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using scale and offset transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleOffsetRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScaleOffset(T,r.getLowerLeft()), + modifyScaleOffset(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using a general transform. + // + template + pod::rectangle GXX_HIDDEN modifyGeneralRect( + const transform & T, + const pod::rectangle & r ) + { + // + // We have to transform all four corner points when using a + // general transform in order to figure out what the new corner + // points will be. + // + pod::point p0 = modifyGeneral(T,r.getLowerLeft()); + pod::point p1 = modifyGeneral(T,r.getLowerRight()); + pod::point p2 = modifyGeneral(T,r.getUpperRight()); + pod::point p3 = modifyGeneral(T,r.getUpperLeft()); + pod::rectangle rect; + rect.merge(p0); + rect.merge(p1); + rect.merge(p2); + rect.merge(p3); + return rect; + } + + template + pod::rectangle GXX_HIDDEN modifyStdRect ( + const transform & T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStd(T,r.getLowerLeft()), + modifyStd(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using standard transform with magnification. + // + template + pod::rectangle GXX_HIDDEN modifyStdMagRect( + const transform &T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStdMag(T,r.getLowerLeft()), + modifyStdMag(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using resolution transform. + // + template + pod::rectangle GXX_HIDDEN modifyResolutionRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyResolution(T,r.getLowerLeft()), + modifyResolution(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + + // + /// Initialize the function tables. + // + void transform::initFnTables() + { + // + // double to short + // + modifyDblToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToShortFunTbl[StdTransformType] = &modifyStd; + modifyDblToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to short + // + modifyLongToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToShortFunTbl[StdTransformType] = &modifyStd; + modifyLongToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to short + // + modifyIntToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToShortFunTbl[StdTransformType] = &modifyStd; + modifyIntToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to int + // + modifyDblToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToIntFunTbl[StdTransformType] = &modifyStd; + modifyDblToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to double + // + modifyDblToDblFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToDblFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToDblFunTbl[StdTransformType] = &modifyStd; + modifyDblToDblFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToDblFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToDblFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to int + // + modifyLongToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToIntFunTbl[StdTransformType] = &modifyStd; + modifyLongToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to int + // + modifyIntToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToIntFunTbl[StdTransformType] = &modifyStd; + modifyIntToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // long to long + // + modifyLongToLongFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToLongFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToLongFunTbl[StdTransformType] = &modifyStd; + modifyLongToLongFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToLongFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToLongFunTbl[ResolutionTransformType] = &modifyResolution; + // + /// Init get inverse func table. + // + getInverseFnTbl[ScaleOffsetTransformType] = &getInverseScaleOffset; + getInverseFnTbl[GeneralTransformType] = &getInverseGeneral; + getInverseFnTbl[StdTransformType] = &getInverseStd; + getInverseFnTbl[StdTransformWithMagType] = &getInverseStdWithMag; + getInverseFnTbl[ScaleTransformType] = &getInverseScale; + getInverseFnTbl[ResolutionTransformType] = &getInverseResolution; + // + /// Init the multiply func table. + // + multFnTbl[0] = &multScaleOffsetXScaleOffset; + multFnTbl[1] = &multScaleOffsetXGeneral; + multFnTbl[2] = &multScaleOffsetXStd; + multFnTbl[3] = &multScaleOffsetXStdWithMag; + multFnTbl[4] = &multScaleOffsetXScaleOffset; + multFnTbl[5] = &multScaleOffsetXResolution; + multFnTbl[6] = &multGeneralXScaleOffset; + multFnTbl[7] = &multGeneralXGeneral; + multFnTbl[8] = &multGeneralXStd; + multFnTbl[9] = &multGeneralXStdWithMag; + multFnTbl[10] = &multGeneralXScaleOffset; + multFnTbl[11] = &multGeneralXResolution; + multFnTbl[12] = &multStdXScaleOffset; + multFnTbl[13] = &multStdXGeneral; + multFnTbl[14] = &multStdXStd; + multFnTbl[15] = &multStdXStdWithMag; + multFnTbl[16] = &multStdXScaleOffset; + multFnTbl[17] = &multStdXResolution; + multFnTbl[18] = &multStdWithMagXScaleOffset; + multFnTbl[19] = &multStdWithMagXGeneral; + multFnTbl[20] = &multStdWithMagXStd; + multFnTbl[21] = &multStdWithMagXStdWithMag; + multFnTbl[22] = &multStdWithMagXScaleOffset; + multFnTbl[23] = &multStdWithMagXResolution; + multFnTbl[24] = &multScaleOffsetXScaleOffset; + multFnTbl[25] = &multScaleOffsetXGeneral; + multFnTbl[26] = &multScaleOffsetXStd; + multFnTbl[27] = &multScaleOffsetXStdWithMag; + multFnTbl[28] = &multScaleXScale; + multFnTbl[29] = &multScaleXResolution; + multFnTbl[30] = &multResolutionXAny; + multFnTbl[31] = &multResolutionXAny; + multFnTbl[32] = &multResolutionXAny; + multFnTbl[33] = &multResolutionXAny; + multFnTbl[34] = &multResolutionXAny; + multFnTbl[35] = &multResolutionXAny; + // + // Initialize the rectangle modification function tables. + // + modifyRectLongToLongFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectLongToLongFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectLongToLongFunTbl[StdTransformType] = modifyStdRect; + modifyRectLongToLongFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectLongToLongFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectLongToLongFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectDblToDblFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectDblToDblFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectDblToDblFunTbl[StdTransformType] = modifyStdRect; + modifyRectDblToDblFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectDblToDblFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectDblToDblFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectIntToIntFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectIntToIntFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectIntToIntFunTbl[StdTransformType] = modifyStdRect; + modifyRectIntToIntFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectIntToIntFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectIntToIntFunTbl[ResolutionTransformType] = modifyResolutionRect; + } + + // Value of standard orientation + const struct { bool xflip; double angle;} stdOrientXFlipAngValues[stdOrientMAX]= + { + {false, 0. }, // RO + {false, 90. }, // R90 + {false, 180. }, // R180 + {false, 270. }, // R270 + {true, 0. }, // XFlipR0 + {true, 90. }, //XFlipR90 + {true, 180. }, //XFlipR180 + {true, 270. } //XFlipR270 + }; + + const void transform::getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const + { + + if( type!=GeneralTransformType) + { + // + // standard orientation. Use table + // + int idx= (int) getOrient().getOri(); + isXFlip= stdOrientXFlipAngValues[idx].xflip; + angle = stdOrientXFlipAngValues[idx].angle; + mag = a11; + } + else + { + // From constructor + // double multiplier = 1.0; + // if (inXFlip == true) + // multiplier = -1.0; + // register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + // register double cosine = cos(newAngle); + // register double sine = sin(newAngle); + // a11 = inMag * cosine; + // a12 = inMag * sine; + // a21 = -inMag * multiplier * sine; + // a22 = inMag * multiplier * cosine; + // + // How to get angle, inMage and inXFlip from a11, a12, a21, and a22 + // Let sumProd = a11* a22 - a12*a21 + // = (inMag*consine)(inMag * multiplier * cosine) - (inMag * sine)(-inMag * multiplier * sine) + // = inMag*inMag*multiplier*consine*consine + inMag*inMag*multiplier*sine*sine + // = inMag*inMag*multiplier(consine* consine + sine*sine) + // = inMag*inMag*multiplier + // + // if( sumProd) < 0 ==> inXFlip=true + // inMag= SquareRoot( Abs(sumPro)); + // Angle= ArcCosine(a11/inMag) + + double sumProd= a11*a22 - a12*a21; + + //get inXFlip. + // sumProd= imMag*imMag*multiplier + isXFlip= sumProd < 0; + + // get abs(imMag*imMag) + if(sumProd<0) + sumProd= -sumProd; + + // get mag + mag= sqrt(sumProd); + + // get angle + if(mag> 0) + { + + double angleR= acos(a11/mag); + angle=radiansToDegrees(angleR); + + // aCos funciton range is 0 to 180. + // We need to decide if angle is between 180 to 360 + // + // How to solve it + // Let (Xt, Yt) is the point by applying (1,0) with transformation without xFlip, + // if Yt > 0, then angle is located between 180 and 360 + // + // i.e. + // | a11 a12 | x | 1 | = [a11 a21p ] = (Xt, Yt) + // | a21p a22 | | 0 | + // a21= multiplier * a21p = xFlip + angle + // if a21p > 0 angle is located between 180 and 360 + // + double a21p= isXFlip? -a21: a21; + if( a21p> 0 ) + angle= 360. - angle; + + } + else + angle=0; + }// end else + } + + transform transform::getInverseScaleOffset(const transform & T) + { + return transform( -T.offset.X()/T.a11, + -T.offset.Y()/T.a22, + 1.0/T.a11, + 1.0/T.a22); + } + // + /// Get the inverse of a general transform. + // + transform transform::getInverseGeneral(const transform & T ) + { + // + // compute the determinant + // + double det = T.a11*T.a22 - T.a12*T.a21; + + return transform( (T.offset.Y()*T.a21 - T.offset.X()*T.a22)/det, + (T.offset.X()*T.a12 - T.offset.Y()*T.a11)/det, + T.a22/det, + -T.a12/det, + -T.a21/det, + T.a11/det); + } + // + /// Get the inverse of a standard transform. + // + transform transform::getInverseStd(const transform & T) + { + // + // Transform the offset. + // + pod::point off = - T.offset * stdOrient(inverseStdOrient[T.orient.getOri()]); + // + // Return the inverted standard transform. + // + return transform (off.X(), off.Y(), + inverseStdOrient[T.orient.getOri()]); + } + // + /// Get the inverse of a standard transform with mag. + // + transform transform::getInverseStdWithMag(const transform & T) + { + register double oneOverMag = 1.0/T.a11; + register stdOrientEnum e = inverseStdOrient[T.orient.getOri()]; + // + // Transform the offset. + // + pod::point off = - (T.offset * stdOrient(e)) * oneOverMag; + + return transform( off.X(), + off.Y(), + e, + oneOverMag ); + } + // + /// Get the inverse of a scale transform. + // + transform transform::getInverseScale(const transform & T) + { + return transform( 0.0, + 0.0, + 1.0/T.a11, + 1.0/T.a22); + } + // + // Get the inverse of a resolution transform. + // + transform transform::getInverseResolution(const transform & T) + { + if (T.next) { + transform T1(T.a11, T.a22, false); + transform T2; + T1.mult(*(T.next), T2); + return T2.getInverse(); + } else { + return transform(1.0/T.a11, 1.0/T.a22, false); + } + } + + // + /// Multiply two scale transforms. + // + void transform::multScaleXScale(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point(0.0, 0.0); + } + // + /// Multiply a scale transform with a resolution transform. + // + void transform::multScaleXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp(T1.a11, T1.a22, false); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(0.0); + outT.next->offset.setY(0.0); + } else { + outT.next = new transform(T1.a11, T1.a22, false); + } + } + } + // + // + /// Multiply two scale offset transforms. + // + void transform::multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleOffsetTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( + T2.a11*T1.offset.X() + T2.offset.X(), + T2.a22*T1.offset.Y() + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a general transform. + // + void transform::multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a11*T2.a12; + outT.a21 = T1.a22*T2.a21; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21 + T2.offset.X(), + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22 + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a standard transform. + // + void transform::multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0], + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]) + + T2.offset; + } + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + void transform::multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]), + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1])) + + T2.offset; + } + // + /// Multiply a scale offset transform with a resolution transform. + // + void transform::multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleOffsetTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = 0.0; + outT.next->a21 = 0.0; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + } + } + } + // + /// Multiply a general transform with a scale offset transform. + // + void transform::multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two general transforms. + // + void transform::multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11 + T1.a12*T2.a21; + outT.a12 = T1.a11*T2.a12 + T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11 + T1.a22*T2.a21; + outT.a22 = T1.a21*T2.a12 + T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a general transform with a standard transform. + // + void transform::multGeneralXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + outT.a21 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + void transform::multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a12 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + outT.a21 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a22 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + // + // Transform the offset. + // + outT.offset = (T1.offset * T2.orient) * T2.a11 + T2.offset; + } + // + /// Multiply a general transform with a resolution transform. + // + void transform::multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = GeneralTransformType; + outT.next->a11 = T1.a11; + outT.next->a22 = T1.a22; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + } + } + } + // + /// Multiply a standard transform with a scale and offset transform. + // + void transform::multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with a general transform. + // + void transform::multStdXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two standard transforms. + // + void transform::multStdXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformType; + outT.orient = multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + void transform::multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with a resolution transform. + // + void transform::multStdXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) + { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + tmp.mult(*(T2.next), *(outT.next)); + } + else if (outT.next) + { + outT.next->type = StdTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } + else + { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + } + } + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + void transform::multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + void transform::multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21); + outT.a12 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22); + outT.a21 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21); + outT.a22 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22); + // + // Transfomr the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + void transform::multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply two standard transforms with magnification. + // + void transform::multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11*T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + void transform::multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = StdTransformWithMagType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + } + } + } + // + /// Multiply a resolution transform with any transform. + // + void transform::multResolutionXAny(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T1.a11; + outT.a12 = T1.a12; + outT.a21 = T1.a21; + outT.a22 = T1.a22; + + if(T1.next) { + if (!(outT.next)) + outT.next = new transform; + T1.next->mult(T2, *(outT.next)); + } else { + outT.next = new transform(T2); + } + } + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void transform::modify( const pod::point& rSrc, pod::point& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffset( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneral( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStd( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMag( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScale( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolution( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// This is pod::rectangle version of above function. + // + template + void transform::modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffsetRect( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneralRect( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStdRect( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMagRect( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScaleRect( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolutionRect( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void transform::modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + // + // If we have orthogonal transform? + // First check get12 since most of transform will + // have no rotation factor. + // + if ( !next && (get12() == 0 || get11() == 0)) + modify( rSrc, rDest ); + // + // General case. + // + else + { + rDest.makeInvalid(); + pod::point tmp; + + modify( rSrc.getLowerLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getLowerRight(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperRight(), tmp ); + rDest.merge( tmp ); + } + } + +// +/// Print a transform, mainly for debug purpose. +// +void transform::print(FILE *outStream, const char *linePrefix) const +{ + std::string str = (std::string)(*this); + fprintf(outStream, "%stype = %s.\n", linePrefix, + str.c_str()); + if (getType() != ResolutionTransformType && + getType() != ScaleTransformType) { + fprintf(outStream, "%stx = %f.\n", linePrefix, offset.X()); + fprintf(outStream, "%sty = %f.\n", linePrefix, offset.Y()); + } + switch(type) { + case ScaleOffsetTransformType: + case ScaleTransformType: + fprintf(outStream, "%sscaleX = %f.\n", linePrefix, a11); + fprintf(outStream, "%sscaleY = %f.\n", linePrefix, a22); + break; + + case GeneralTransformType: + fprintf(outStream, "%sa11 = %f.\n", linePrefix, a11); + fprintf(outStream, "%sa12 = %f.\n", linePrefix, a12); + fprintf(outStream, "%sa21 = %f.\n", linePrefix, a21); + fprintf(outStream, "%sa22 = %f.\n", linePrefix, a22); + break; + + case StdTransformType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + break; + + case StdTransformWithMagType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + fprintf(outStream, "%smag = %f.\n", linePrefix, a11); + break; + + case ResolutionTransformType: + fprintf(outStream, "%sscale = %f.\n", linePrefix, a11); + if (next) { + std::string bfr(linePrefix); + bfr += " "; + next->print(outStream, bfr.c_str()); + } + break; + + default: + throw except::outOfRange("base::transform:print: Unknown type."); + } // switch +} + +// +/// Convert a transform type to a string. +// +transform::operator std::string() const +{ + switch(type) { + case ScaleOffsetTransformType: + return std::string("ScaleOffsetTransform"); + break; + case GeneralTransformType: + return std::string("GeneralTransform"); + break; + case StdTransformType: + return std::string("StdTransform"); + break; + case StdTransformWithMagType: + return std::string("StdTransformWithMag"); + break; + case ScaleTransformType: + return std::string("ScaleTransform"); + break; + case ResolutionTransformType: + return std::string("ResolutionTransform"); + break; + default: + throw except::outOfRange("base::transformTypeToString: Unknown type."); + } // switch +} + +std::ostream & operator << (std::ostream & os, const transform & t) +{ + os << "" << std::endl; + os << "" << std::endl; + os << t.getRow1(); + os << t.getRow2(); + os << "" << std::endl; + os << "" << std::endl; + os << t.getOffset(); + os << "" << std::endl; + os << "" << std::endl; + return os; +} + + + +/***************************************************************************** +* Instantiate template with some arguments. +*/ +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +#if defined( _MSC_VER ) +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +#endif + +namespace transformTest +{ + + + /// called by testGetAngleFlipMag() + bool testTran_(int idx, const transform& tr, bool xFlip0, double angle0, double mag0) + { + // Get angle/xflip/mag from tr + bool xFlip; + double angle, mag; + tr.getAngleFlipMag( angle,xFlip, mag); + + // Compare + bool bFlp= xFlip == xFlip0; + bool bAng=(angle - angle0) < absTolerance && + (angle0 -angle) < absTolerance ; + bool bMag= (mag - mag0) < absTolerance && + (mag0 -mag) < absTolerance ; + + // Print error message if there is different + if(!bFlp || !bAng || !bMag) + { + printf(" %-2d tr(xFlop=%s)",idx, (xFlip0?"T":"F")); + if(!bFlp) + printf("!= %s", (xFlip?"T":"F")); + + printf(" (angle=%10.5f)", angle0) ; + if(!bAng) + printf("!= %10.5f", angle); + + printf(" (mag=%5.3f)",mag0); + + if(!bMag) + printf("!= %5.3f", mag); + printf("\n"); + return false; + } + return true; + } + + // + /// Function test getAngelFlipMag() + // + bool testGetAngleFlipMag() + { + struct { bool xFlip; double angle; double mag; } testData[]= + { // xFlip Angle Max index + {false, 0, 1}, //0 standard Orientation + {false, 90, 1.1}, //1 + {false, 180, 1.2}, //2 + {false, 270, 1.3}, //3 + {true, 0, 1.4}, //4 + {true, 90, 1.5}, //5 + {true, 180, 1.6}, //6 + {true, 270, 1.7}, //7 + {false, 23, 1.8}, //8 non-standard Orientation + {true, 23, 1.9}, //9 + {false, 92, 2.1}, //10 + {true, 92, 2.2}, //11 + {false, 192, 2.3}, //12 + {true, 192, 2.4}, //13 + {false, 272, 2.5}, //14 + {true, 272, 2.6} //15 + }; + const int dataCount=16; + int failCtr=0; + int i=0; + for( ;i < dataCount; i++) + { + // Construct transform + transform tr(0,0, + testData[i].xFlip, + testData[i].angle, + testData[i].mag); + if(! testTran_(i, tr, testData[i].xFlip, testData[i].angle, testData[i].mag)) + failCtr++; + } + + /// set a11, a12, a21, a22 directly + transform trR0(101,101, 1, 0, 0, 1); + transform trR90(101,101, 0, 1, -1, 0); + transform trR180(101,101, -1,0, 0, -1); + transform trR270(101,101, 0, -1, 1, 0); + + transform XtrR0(101,101, 1, 0,0, -1); + transform XtrR90(101,101, 0, 1, 1, 0); + transform XtrR180(101,101, -1,0, 0, 1); + transform XtrR270(101,101, 0, -1, -1, 0); + + if(!testTran_(i++, trR0, false, 0, 1)) failCtr++; + if(!testTran_(i++, trR90, false, 90, 1)) failCtr++; + if(!testTran_(i++, trR180, false, 180, 1)) failCtr++; + if(!testTran_(i++, trR270, false, 270, 1)) failCtr++; + if(!testTran_(i++, XtrR0, true, 0, 1)) failCtr++; + if(!testTran_(i++, XtrR90, true, 90, 1)) failCtr++; + if(!testTran_(i++, XtrR180,true, 180, 1)) failCtr++; + if(!testTran_(i++, XtrR270,true, 270, 1)) failCtr++; + + + // Print summary + printf("transformation::testGetAngleFlipMag() test:%s\n", + (failCtr >0 ? " failed":" passed")); + + return failCtr==0; + } + + +}; + +}; // namespace base diff --git a/testTransform/_transform.h b/testTransform/_transform.h new file mode 100644 index 0000000..24d20c7 --- /dev/null +++ b/testTransform/_transform.h @@ -0,0 +1,1408 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#ifndef TRANSFORM_H_ +#define TRANSFORM_H_ + +// _MSC_VER >= 1400 means we deal with VC8 or higher. +#if defined( _MSC_VER ) +/*warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)*/ +#pragma warning( disable: 4290 ) +#endif + +#include +#include +#include + +#include "base/port.h" +#include "base/constants.h" +#include "base/except.h" +#include "base/rectangle.h" +#include "base/round.h" + +/*! + * round() is only defined in XOPEN_EXTENDED. + * Define it for platforms which do not implement the latter. + */ +#ifndef __USE_XOPEN_EXTENDED +namespace +{ + double round(double x) + { + return floor(x + 0.5); + } +} +#endif + +// +/// The transform.h file contains the different transform types. +// +/*! + * Usage of transforms: + * Transforms are applied to row vectors from the right as shown below: + * OV = IV * T + * Here, OV and IV are the output and input row vectors and T is the transform. + * + * Multiplying transforms: + * Suppose we have a chain of transforms. + * OV = IV * T1 * T2 + * OV = IV * T + * Thus, T can be computed as follows: + * Transform T; + * T1.mult(T2, T); + * + * A general 2-D transform can be viewed in matrix form as follows: + * |a11 a12 0| + * |a21 a22 0| + * | tx ty 1| + * A general transform can be viewed as a sequence of 3 steps: + * 1- Scaling with value (Sx, Sy) (i.e. x' = Sx*x, y' = Sy*y). + * 2- rotating with angle A. + * 3- translating with value (tx, ty). + * In other words, the 2-D transform is the multiplication of the 3 transforms + * as follows: + * |Sx 0 0| | cos(A) sin(A) 0| | 1 0 0| + * |0 Sy 0|*|-sin(A) cos(A) 0|*| 0 1 0| + * |0 0 1| | 0 0 1| |tx ty 1| + * + * Using resolution transforms: + * In order to mimic applying resolution transforms to each cell individually, + * a resolution change operation is applied before anything. Suppose we call + * the resolution change transform RES. Also suppose the transform from the + * cell to the screen is TS. Thus: + * OV = IV * RES * TS. + * In order to change the resolution of a layout, we need to insert the + * resolution transform RES in the chain. Hence: + * 1- Create a resolution transform RES(xScale, yScale, true). + * 2- Assuming T is the total transform, T can be computed as follows: + * RES.mult(TS, T). + */ +namespace base +{ + // + /// Enum for types of transforms. + // + enum transformType + { + // + /// ScaleOffsetTransform type. + // + ScaleOffsetTransformType = 0, + // + /// GeneralTransform type. + // + GeneralTransformType, + // + /// StdTransform type. + // + StdTransformType, + // + /// StdTransformWithMag type. + // + StdTransformWithMagType, + // + /// StdTransformWithMag type. + // + ScaleTransformType, + // + /// Resolution type. + // + ResolutionTransformType, + // + /// Always keep this entry as the last enum value. + // + transformTypeMAX + }; // enum transformType + // + /// Inverses of the standard orientations. + // + extern const stdOrientEnum inverseStdOrient[stdOrientMAX]; + // + /// Coefficient matrices for the standard orientations. + // + extern const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2]; + // + /// Matrix holding standard orientations resulting from multiplying + /// different standard orientations. + // + extern const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX]; + + class transform; + // + /// Type definition for determining inverse of various transform types. + // + typedef transform (*pGetInverseFun)(const transform &); + // + /// Table of inverse determining functions by transform type. + // + extern pGetInverseFun getInverseFnTbl[transformTypeMAX]; + + typedef void (*pMultFun)( const transform & T1, + const transform & T2, + transform & outT ); + + extern pMultFun multFnTbl[transformTypeMAX*transformTypeMAX]; + + typedef pod::point (*pModifyFunDblToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunDblToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunDblToDbl)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToLong)(const transform &, pod::point); + // + /// Type definition for for transforming a rectangle of type double to + /// another rectangle of type double. + // + typedef pod::rectangle (*pModifyRectFunDblToDbl)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type long to + /// another rectangle of type long. + // + typedef pod::rectangle (*pModifyRectFunLongToLong)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type int to + /// another rectangle of type int. + // + typedef pod::rectangle (*pModifyRectFunIntToInt)(const transform &, const pod::rectangle &); + + extern pModifyFunDblToShort modifyDblToShortFunTbl[transformTypeMAX]; + extern pModifyFunLongToShort modifyLongToShortFunTbl[transformTypeMAX]; + extern pModifyFunIntToShort modifyIntToShortFunTbl[transformTypeMAX]; + extern pModifyFunDblToInt modifyDblToIntFunTbl[transformTypeMAX]; + extern pModifyFunDblToDbl modifyDblToDblFunTbl[transformTypeMAX]; + extern pModifyFunLongToInt modifyLongToIntFunTbl[transformTypeMAX]; + extern pModifyFunIntToInt modifyIntToIntFunTbl[transformTypeMAX]; + extern pModifyFunLongToLong modifyLongToLongFunTbl[transformTypeMAX]; + extern pModifyRectFunLongToLong modifyRectLongToLongFunTbl[transformTypeMAX]; + extern pModifyRectFunDblToDbl modifyRectDblToDblFunTbl[transformTypeMAX]; + extern pModifyRectFunIntToInt modifyRectIntToIntFunTbl[transformTypeMAX]; + + + // + /// The main transformation class. + // + class GXX_VISIBLE transform + { + // Data + protected: + // + /// 2X2 coefficient submatrix. + /// a11 would be used for Sx for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + /// Also, a11 would be used for magnification in the case of + /// standard transforms with magnification. + /// a22 would be used for Sy for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + // + double a11, a12, a21, a22; + // + // Offset for the transform. + // + pod::point offset; + // + /// Pointer to next transform in chain. This is used by + /// resolution transforms. + // + transform *next; + // + /// Orientation field. + // + base::stdOrient orient; + // + /// Type of transform. + // + unsigned int type : 4; + + // Typedefs + protected: + + typedef pod::point (*pModifyFunDblToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToDbl)( + const transform &T, + pod::point xy ); + + private: + + // + /// Get the inverse of a scale offset transform. + // + static transform getInverseScaleOffset(const transform & T); + // + /// Get the inverse of a general transform. + // + static transform getInverseGeneral(const transform & T ); + // + /// Get the inverse of a standard transform. + // + static transform getInverseStd(const transform & T); + // + /// Get the inverse of a standard transform with mag. + // + static transform getInverseStdWithMag(const transform & T); + // + /// Get the inverse of a scale transform. + // + static transform getInverseScale(const transform & T); + // + // Get the inverse of a resolution transform. + // + static transform getInverseResolution(const transform & T); + // + /// Multiply two scale transforms. + // + static void multScaleXScale(const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale transform with a resolution transform. + // + static void multScaleXResolution( const transform &T1, + const transform &T2, + transform &outT); + // + // + /// Multiply two scale offset transforms. + // + static void multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a general transform. + // + static void multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a standard transform. + // + static void multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + static void multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a resolution transform. + // + static void multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a scale offset transform. + // + static void multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two general transforms. + // + static void multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform. + // + static void multGeneralXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + static void multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a resolution transform. + // + static void multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a scale and offset transform. + // + static void multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a general transform. + // + static void multStdXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms. + // + static void multStdXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + static void multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a resolution transform. + // + static void multStdXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + static void multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + static void multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + static void multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms with magnification. + // + static void multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + static void multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a resolution transform with any transform. + // + static void multResolutionXAny(const transform &T1, + const transform &T2, transform &outT); + + // Construction + public: + + // + /// Initialize the function tables. + // + static void initFnTables(); + + // + /// Default constuctor. + // + transform() + : + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(0.0,0.0), + next(NULL), + orient(R0), + type(StdTransformType) + {} + // + /// Constructor for a scale offset transform. + // + transform( + double offsetX, + double offsetY, + double scaleX, + double scaleY + ) + : + a11(scaleX), + a12(0.0), + a21(0.0), + a22(scaleY), + offset(offsetX,offsetY), + next(NULL), + type(ScaleOffsetTransformType) + { + double xAbs(offsetX > 0.0 ? offsetX : -offsetX); + double yAbs(offsetY > 0.0 ? offsetY : -offsetY); + if (xAbs < absTolerance && yAbs < absTolerance) + type = ScaleTransformType; + } + // + /// Constructor for a general transform. + // + transform( + double offsetX, + double offsetY, + double coeff11, + double coeff12, + double coeff21, + double coeff22 + ) + : + a11(coeff11), + a12(coeff12), + a21(coeff21), + a22(coeff22), + offset(offsetX,offsetY), + next(NULL), + type(GeneralTransformType) + {}; + // + /// Constructor for a rotate transform. + /// @param inCx X coordinate of the center of rotation. + /// @param inCy Y coordinate of the center of rotation. + /// @param angle rotation angle in degrees. + // + transform( + double inCx, + double inCy, + double angle + ) + : + a11(cos(degreesToRadians(angle))), + a12(sin(degreesToRadians(angle))), + a21(-a12), + a22(a11), + offset(inCy * a12 - inCx * a11 + inCx, + - inCy * a11 - inCx * a12 + inCy), + next(NULL), + type(GeneralTransformType) + {} + // + /// Constructor for a standard transform. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient = R0 + ) + : + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformType) + {} + // + /// Constructor for a standard transform with magnification. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient, + double inMag) + : + a11(inMag), + a12(0.0), + a21(0.0), + a22(inMag), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformWithMagType) + {} + // + /// Advanced constructor for typical references. + /// @param offsetX X value of translation offset. + /// @param offsetY Y value of translation offset. + /// @param inXFlip boolean reflecting the presence of an X flip. + /// @param inAngle rotation angle in degrees. + /// @param inMag magnification. + // + transform( + double offsetX, + double offsetY, + bool inXFlip, + double inAngle, + double inMag) + : + offset(offsetX,offsetY), + next(NULL) + { + stdOrient newOrient(inXFlip, inAngle); + if (newOrient.getOri() != UnknownStdOrient) + { + orient = newOrient; + if (inMag > 1.0 + relTolerance || + inMag < 1.0 - relTolerance) + { + a11 = inMag; + a12 = 0.0; + a21 = 0.0; + a22 = inMag; + type = StdTransformWithMagType; + } + else + { + a11 = 1.0; + a12 = 0.0; + a21 = 0.0; + a22 = 1.0; + type = StdTransformType; + } + } + else + { + type = GeneralTransformType; + register double multiplier = 1.0; + if (inXFlip == true) + multiplier = -1.0; + register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + register double cosine = cos(newAngle); + register double sine = sin(newAngle); + a11 = inMag * cosine; + a12 = inMag * sine; + a21 = -inMag * multiplier * sine; + a22 = inMag * multiplier * cosine; + } + } + // + /// Scale or resolution transform. + /// @param xScale X value of the scale factor. + /// @param yScale Y value of the scale factor. + /// @param rouding A true value means it is a resolution transform. + /// A false value will result in a standard scale transform. + // + transform( + double xScale, + double yScale, + bool rounding) + : + a11(xScale), + a12(0.0), + a21(0.0), + a22(yScale), + offset(0.0, 0.0), + next(NULL), + orient(R0), + type(ScaleTransformType) + { + if (rounding) { + // If both scales are whole numbers, it is + // a scale transform. + // If either scale is not close enough to an whole + // number, it is a resolution transform. + double rVal(base::round(xScale)); + double diff(xScale - rVal); + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + else { + rVal = base::round(yScale); + diff = yScale - rVal; + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + } + } + } + // + /// Copy constructor + // + transform(const transform & inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + if ( inT.next ) + next = new transform(*inT.next); + else + next = 0; + } + + // + /// Assignment operator + // + transform & operator = (const transform &inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + + if (inT.next) + { + if (next) + *next = *(inT.next); + else + next = new transform(*(inT.next)); + } + else + { + delete next; + next = NULL; + } + return *this; + } + + // + /// Destructor + // + ~transform() + { + if (next) + delete next; + } + +public: + // + /// Equal operator + // + bool operator == (const transform &inT) + { + if ((inT.type == type) && + (inT.orient.getOri() == orient.getOri()) && + (inT.a11 == a11) && + (inT.a12 == a12) && + (inT.a21 == a21) && + (inT.a22 == a22) && + (inT.offset == offset)) + { + if ( !next ) + return (!inT.next); + else if ( inT.next ) + return (*next == *(inT.next)); + else + return false; + } + + return false; + } + + // + /// Non equal operator + // + bool operator != (const transform &inT) + { + return !(*this == inT); + } + + // + /// Test whether this is an identity transform. + // + bool isIdentityTransform() const + throw (except::outOfRange) + { + const double onePlusTolerance = 1.0 + relTolerance; + const double oneMinusTolerance = 1.0 - relTolerance; + // + // See if the offsets are beyond the origin. + // + if (offset.X() > absTolerance || offset.X() < -absTolerance || + offset.Y() > absTolerance || offset.Y() < -absTolerance) + return false; + // + // Check by transform type. + // + switch((transformType) type) + { + case StdTransformWithMagType: + if (a11 > onePlusTolerance || a11 < oneMinusTolerance) + return false; + + case StdTransformType: + if (orient.getOri() != R0) + return false; + break; + + case GeneralTransformType: + if ( a12 > absTolerance || + a12 < -absTolerance || + a21 > absTolerance || + a21 < -absTolerance) + return false; + + case ScaleOffsetTransformType: + case ScaleTransformType: + if ( a11 > onePlusTolerance || + a11 < oneMinusTolerance || + a22 > onePlusTolerance || + a22 < oneMinusTolerance) + return false; + break; + + case ResolutionTransformType: + return false; + break; + + default: + throw except::outOfRange("base::transform:isIdentityTransform: Unknown type."); + } + return true; + } + + // + /// Returns the type of the transform. + // + transformType getType() const + { + return (transformType) type; + } + // + /// Returns the type of the transform chain. + // + transformType getTypeOfChain() const + { + const transform *t = this; + while (t->getNext() != NULL) + t = t->getNext(); + return (transformType) t->type; + } + // + /// Returns the offset point of the transform. + // + pod::point getOffset() const + { + return offset; + } + // + /// Returns the offset point of the transform taking into account also resolution. + // + pod::point getOffsetRes() const + { + if ( getType() != ResolutionTransformType ) + return offset; + else + { + pod::point zero( 0., 0.); + pod::point off; + modify( zero, off ); + return off; + } + } + // + /// Set the offset of the transform. + // + void setOffset( pod::point off ) + { + offset = off; + } + stdOrient getOrient() const + { + return orient; + } + pod::point getDiagonal() const + { + return pod::point(a11,a22); + } + pod::point getRow1() const + { + return pod::point(a11,a12); + } + pod::point getRow2() const + { + return pod::point(a21,a22); + } + pod::point getCol1() const + { + return pod::point(a11,a21); + } + pod::point getCol2() const + { + return pod::point(a12,a22); + } + // + /// Return the magnitude of the vector (1,0). + // + double getXVectorMag() const + { + if ( a21 == 0.0 ) + return ::fabs(a11); + else if ( a11 == 0.0 ) + return ::fabs(a21); + else + return ::sqrt(a11*a11 + a21*a21); + } + // + /// A special function to return the X scale factor. This + /// is a nonnegative value that reflects the scaling effect + /// in the X direction. + // + double getXScale() const + { + if (type != ResolutionTransformType) + return getXVectorMag(); + else + return getXVectorMag() * (next ? next->getXScale() : 1.0); + } + // + /// Returns the a11 entry of the matrix. If the matrix is a scaling + /// one, then this returns the X-scale factor. + /// The result is not correct for all types of transforms. + // + double get11() const + { + return a11; + } + // + /// Return the a12 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get12() const + { + return a12; + } + // + /// Return the a21 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get21() const + { + return a21; + } + // + /// Returns the a22 entry of the matrix. If the matrix is a scaling + /// one, then this returns the Y-scale factor. + /// The result is not correct for all types of transforms. + // + double get22() const + { + return a22; + } + // + /// Return the next field. + // + const transform *getNext() const + { + return next; + } + // + /// Return the next field. + // + transform *getNext() + { + return next; + } + + // + /// get angle, isXFlip and mag from transformation + // + const void getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const; + +// Complex functions. +public: + // + /// Multiply with another transform. + // + void mult(const transform &T2, transform &outT) const + { + (*(multFnTbl[(type*transformTypeMAX)+T2.type]))(*this,T2,outT); + } + + transform operator *(const transform & T) const + { + transform out; + mult(T,out); + return out; + } + // + /// Scale the transform by the given scalar. + // + transform & operator *= (const double d) + { + if (type != ResolutionTransformType) { + transform tmp(d, d, false); + transform out; + mult(tmp, out); + *this = out; + } else { + if (next) + *next *= d; + else + next = new transform(d, d, false); + } + return *this; + } + + // + /// Return the inverse transform of the transform. + // + transform getInverse() const + { + return (*(getInverseFnTbl[type]))(*this); + } + +#if 1 + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + pod::point modifyDblToDbl(pod::point) const + { return pod::point(); } + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + + //////////////////////////////////////////////////////////////// + + // + /// Modify a single point. + // + pod::point modifyDblToShort(pod::point p) const + { + return (*(modifyDblToShortFunTbl[type]))(*this, p); + } + + pod::point modifyDblToInt(pod::point p) const + { + return (*(modifyDblToIntFunTbl[type]))(*this, p); + } + + // + /// Transform doubles to doubles. + // + pod::point modifyDblToDbl(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + pod::point modify(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } +#ifdef WIN32 +// pod::point modify(pod::point p) const +// { +// return (*(modifyLongToLongFunTbl[type]))(*this, p); +// } +#endif + + template + pod::rectangle modify(pod::rectangle p) const + { + return pod::rectangle( 0, 0, 0, 0 ); + } + + pod::point modifyIntToInt(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + pod::point modify(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + + pod::point modifyIntToShort(pod::point p) const + { + return (*(modifyIntToShortFunTbl[type]))(*this, p); + } + + pod::point modifyLongToShort(pod::point p) const + { + return (*(modifyLongToShortFunTbl[type]))(*this, p); + } + + // + /// Transform longs to ints. + // + pod::point modifyLongToInt(pod::point p) const + { + return (*(modifyLongToIntFunTbl[type]))(*this, p); + } + + // + /// Transform longs to longs. + // + pod::point modifyLongToLong(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::point modify(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } +#endif + + // + // + // +#if 1 + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectDblToDblFunTbl[type]))(*this, r); + } + + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectLongToLongFunTbl[type]))(*this, r); + } + + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectIntToIntFunTbl[type]))(*this, r); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } +#endif + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void modify( const pod::point& rSrc, pod::point& rDest ) const; + + // + /// This is pod::rectangle version of above function. + // + template + void modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Convert a transform type to a string. + // + operator std::string() const; + friend std::ostream & operator << (std::ostream & os, const transform & t); + + // + /// Print a transform, mainly for debug purpose. + // + void print(FILE *outStream, const char *linePrefix) const; + + }; // class transform + +namespace transformTest +{ + + /// API test getAngelFlipmag + bool testGetAngleFlipMag(); +}; + + /*! + * Simple resolution chain implementation. + * Objects of this class can receive the resolution portion of transform + * objects and apply them to double precision points. + */ + class resolutionChain + { + private: + int chainSize; + pod::point *chain; + + // + /// Get the resolution chain from a transform object. + // + void getResFromTransform(const transform &trn) + { + chainSize = 0; + chain = NULL; + // + // Calculate the resolution chain size. + // + const transform *t = &trn; + while (t && t->getType() == ResolutionTransformType) + { + chainSize++; + t = t->getNext(); + } + if (chainSize == 0) + return; + // + // Initialize the resolutions. + // + chain = new pod::point[chainSize]; + t = &trn; + for (int i = 0; i < chainSize; i++) + { + chain[i] = t->getDiagonal(); + t = t->getNext(); + } + } + + public: + // + /// Default do-nothing constructor. + // + resolutionChain() : + chainSize(0), chain(NULL) + {} + // + /// Construct the resolution chain of a transform object. + // + resolutionChain(const transform &trn) : + chainSize(0), chain(NULL) + { + getResFromTransform(trn); + } + // + /// Assign to this the resolution chain of a transform object. + // + resolutionChain &operator = (const transform &trn) + { + if (chain) + delete[] chain; + getResFromTransform(trn); + return *this; + } + // + /// Destroy the chain. + // + ~resolutionChain() + { + if (chain) + delete[] chain; + } + // + /// Check if this is the resolution chain of trn. + // + bool isResChainOf(const transform &trn) const + { + const transform *t = &trn; + for (int i = 0; i < chainSize; i++) + { + if (!t || t->getType() != ResolutionTransformType) + return false; + if (chain[i] != t->getDiagonal()) + return false; + t = t->getNext(); + } + if (t && t->getType() == ResolutionTransformType) + return false; + return true; + } + // + /// Apply the chain to the point p. Round after each + /// resolution change if needed. + // + pod::point apply(pod::point p, bool round = true) const + { + pod::point r = p; + for (int i = 0; i < chainSize; i++) + { + r = r % chain[i]; + if (round) + r = pod::point(::round(r.getX()), + ::round(r.getY())); + } + return r; + } + }; + + /*! + * Simple transformation class. + * This class does not allow resolution change transformations - they + * should be modeled by resolutionChain instead. Objects of this class + * consist of a 2x2 matrix and an offset and can be applied to double + * precision points. + */ + class simpleTransform + { + private: + pod::point col1; + pod::point col2; + pod::point offset; + + public: + // + /// Default identity transformation constructor. + // + simpleTransform() : + col1(1, 0), col2(0, 1), offset(0, 0) + {} + // + /// Construct a transformation from a transform object + /// skipping the resolution chain. + // + simpleTransform(const transform &trn) : + col1(1, 0), col2(0, 1), offset(0, 0) + { + // + // Skip the resolution part + // + const transform *t = &trn; + while (t && t->getType() == base::ResolutionTransformType) + t = t->getNext(); + // + // If there is anything left, dig out the parameters from t. + // + if (t) + { + if (t->getType() != ScaleTransformType) + offset = t->getOffset(); + + switch (t->getType()) + { + case base::ScaleTransformType: + case base::ScaleOffsetTransformType: + col1 = pod::point(t->get11(), 0.0); + col2 = pod::point(0.0, t->get22()); + break; + + case base::GeneralTransformType: + col1 = t->getCol1(); + col2 = t->getCol2(); + break; + + case base::StdTransformType: + case base::StdTransformWithMagType: + if (t->getOrient().getOri() == R90) + { + col1 = pod::point(0.0, -1.0); + col2 = pod::point(1.0, 0.0); + } + if (t->getOrient().getOri() == R180) + { + col1 = pod::point(-1.0, 0.0); + col2 = pod::point(0.0, -1.0); + } + if (t->getOrient().getOri() == R270) + { + col1 = pod::point(0.0, 1.0); + col2 = pod::point(-1.0, 0.0); + } + if (t->getOrient().getOri() == XFlipR0) + { + col1 = pod::point(1.0, 0.0); + col2 = pod::point(0.0, -1.0); + } + if (t->getOrient().getOri() == XFlipR90) + { + col1 = pod::point(0.0, 1.0); + col2 = pod::point(1.0, 0.0); + } + if (t->getOrient().getOri() == XFlipR180) + { + col1 = pod::point(-1.0, 0.0); + col2 = pod::point(0.0, 1.0); + } + if (t->getOrient().getOri() == XFlipR270) + { + col1 = pod::point(0.0, -1.0); + col2 = pod::point(-1.0, 0.0); + } + if (t->getType() == StdTransformWithMagType) + { + col1 *= t->get11(); + col2 *= t->get11(); + } + break; + + default: + break; + } + } + } + // + /// Apply the transformation to a double precision point. + // + pod::point apply(pod::point p) const + { + return pod::point(p * col1, p * col2) + offset; + } + }; + +} // namespace base + +#endif // TRANSFORM_H_ diff --git a/testTransform/main.cpp b/testTransform/main.cpp new file mode 100644 index 0000000..a16e1f9 --- /dev/null +++ b/testTransform/main.cpp @@ -0,0 +1,570 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#include +#include +#include "../getCurrentTime2.h" +#include +#include +#include "transform2.h" + +#ifdef WIN32 +#include +#endif + +// +// Forward declarations. +// +void print_result( double, double ); + +#define SCALE 100 + +//////////////////////////////////////////////////////////////////////////// +// +// The sample transformations. +// +struct tsmpl_s +{ +double xloc; +double yloc; +double mag; +double rot; +bool flip; +} +tsmpl[] = +{ +{0,0,1,0,0}, +{0,0,1,90,0}, +{0,0,1,180,0}, +{0,0,1,270,0}, +{0,0,1,0,1}, +{0,0,1,90,1}, +{0,0,1,180,1}, +{0,0,1,270,1}, + +{1000,1000,1,0,0}, +{1000,1000,1,90,0}, +{1000,1000,1,180,0}, +{1000,1000,1,270,0}, +{1000,1000,1,0,1}, +{1000,1000,1,90,1}, +{1000,1000,1,180,1}, +{1000,1000,1,270,1}, + +{1000,1000,10,0,0}, +{1000,1000,10,90,0}, +{1000,1000,10,180,0}, +{1000,1000,10,270,0}, +{1000,1000,10,0,1}, +{1000,1000,10,90,1}, +{1000,1000,10,180,1}, +{1000,1000,10,270,1}, + +{1000,1000,10,0+45,0}, +{1000,1000,10,90+45,0}, +{1000,1000,10,180+45,0}, +{1000,1000,10,270+45,0}, +{1000,1000,10,0+45,1}, +{1000,1000,10,90+45,1}, +{1000,1000,10,180+45,1}, +{1000,1000,10,270+45,1}, + +{1000,1000,10,0+30,0}, +{1000,1000,10,90+30,1}, + +{1000,1000,10,0+60,0}, +{1000,1000,10,90+60,1}, + +{1000,1000,10,123,1}, +{1000,1000,10,321,1}, +{1000,1000,10,17,1}, +{1000,1000,10,71,1}, + +{1000,1000,1,360,0}, +{0,0,1,0,0} +}; +#define tsmpl_count (sizeof(tsmpl)/sizeof(tsmpl_s)) + +template +T mktrans( int i ) +{ + assert( i < tsmpl_count ); + return T( + tsmpl[i].xloc, + tsmpl[i].yloc, + tsmpl[i].flip != 0, + tsmpl[i].rot, + tsmpl[i].mag + ); +} + +//////////////////////////////////////////////////////////////////////////// +// +// The sample rectangles. +// +struct rsmpl_s +{ +double l; +double b; +double r; +double t; +} +rsmpl[] = +{ +{10000,10000,100000,100000}, +{1000,1000,1000,1000}, +{0,0,1000,1000} +}; +#define rsmpl_count (sizeof(rsmpl)/sizeof(rsmpl_s)) + +template +pod::rectangle mkrect( int i ) +{ + assert( i < rsmpl_count ); + return pod::rectangle( + C(rsmpl[i].l), + C(rsmpl[i].b), + C(rsmpl[i].r), + C(rsmpl[i].t) + ); +} + +//////////////////////////////////////////////////////////////////////////// +// +// The sample points. +// +struct psmpl_s +{ +double x; +double y; +} +psmpl[] = +{ +{100000,100000}, +{10000,10000}, +{1000,1000}, +{1,1}, +{0,0} +}; +#define psmpl_count (sizeof(psmpl)/sizeof(psmpl_s)) + +template +pod::point mkpt( int i ) +{ + assert( i < psmpl_count ); + return pod::point( + C(psmpl[i].x), + C(psmpl[i].y) + ); +} + +//////////////////////////////////////////////////////////////////////////// +// +// log. +// +std::ofstream out; + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +template< class T, class P, int nProbs > +class modify +{ + T trns; + P src; + P dest; + +public: + modify( const T& t, const P& p ) + { + trns = t; + src = p; + } + + __forceinline void operator() () + { + for( int i = nProbs; i; --i ) + trns.modify( src, dest ); + } +}; + +template< class T, class P, int nProbs > +class modify2 +{ + T trns; + P src; + +public: + modify2( const T& t, const P& p ) + { + trns = t; + src = p; + } + + __forceinline void operator() () + { + for( int i = nProbs; i; --i ) + { + volatile P p = trns.modify( src ); + } + } +}; + +template< class P, + int nProbes > +void test( const base::transform& t1, const base2::transform& t2, const P& p ) +{ + const int n = SCALE; + + typedef modify modify1_type; + double dblMin1 = mesure( modify1_type( t1, p ), nProbes ); + dblMin1 /= n; + + typedef modify modify2_type; + double dblMin2 = mesure( modify2_type( t2, p ), nProbes ); + dblMin2 /= n; + + typedef modify2 modify21_type; + double dblMin21 = mesure( modify21_type( t1, p ), nProbes ); + dblMin21 /= n; + + typedef modify2 modify22_type; + double dblMin22 = mesure( modify22_type( t2, p ), nProbes ); + dblMin22 /= n; + + print_result( dblMin1, dblMin2 ); + print_result( dblMin21, dblMin22 ); +} + +template< class P, int nProbes > +void testTrans( int i, const P& p ) +{ + out << ""; +#if 0 + out << "rot:" << tsmpl[i].rot + << " flip:" << tsmpl[i].flip + << " mag:" << tsmpl[i].mag + << " x:" << tsmpl[i].xloc + << " y:" << tsmpl[i].yloc + << ""; +#endif + test(mktrans(i), + mktrans(i), + p); + out << "" << std::endl; +} + +template< class P, + int nProbes > +void testAllTrans( const P& p ) +{ + for ( int i = 0; i < tsmpl_count; ++i ) + testTrans(i,p); +} + +template< class C, + int nProbes > +void testAllPt() +{ + for ( int i = 0; i < psmpl_count; ++i ) + testAllTrans,nProbes>(mkpt(i)); +} + +template< class C, + int nProbes > +void testAllRect() +{ + for ( int i = 0; i < rsmpl_count; ++i ) + testAllTrans,nProbes>(mkrect(i)); +} + + + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +template< class T, int nProbs > +class mult +{ + T trns; + T trns2; + T trns3; + +public: + mult( const T& t, const T& t2 ) + { + trns = t; + trns2 = t2; + } + + __forceinline void operator() () + { + for( int i = nProbs; i; --i ) + trns.mult( trns2, trns3 ); + } +}; + +template< class T, int nProbs > +class mult2 +{ + T trns; + T trns2; + +public: + mult2( const T& t, const T& t2 ) + { + trns = t; + trns2 = t2; + } + + __forceinline void operator() () + { + for( int i = nProbs; i; --i ) + { + volatile T t = trns * trns2; + } + } +}; + +template< int nProbes > +void testMult( const base::transform& t11, const base::transform& t12, + const base2::transform& t21, const base2::transform& t22 ) +{ + const int n = SCALE; + + { + typedef mult mult1_type; + double dblMin1 = mesure( mult1_type( t11, t12 ), nProbes ); + dblMin1 /= n; + + typedef mult mult2_type; + double dblMin2 = mesure( mult2_type( t21, t22 ), nProbes ); + dblMin2 /= n; + + print_result( dblMin1, dblMin2 ); + } + + { + typedef mult2 mult1_type; + double dblMin1 = mesure( mult1_type( t11, t12 ), nProbes ); + dblMin1 /= n; + + typedef mult2 mult2_type; + double dblMin2 = mesure( mult2_type( t21, t22 ), nProbes ); + dblMin2 /= n; + + print_result( dblMin1, dblMin2 ); + } +} + +template< int nProbes > +void testTrans1x1( int i, int j ) +{ + out << ""; +#if 0 + out << "rot:" << tsmpl[i].rot + << " flip:" << tsmpl[i].flip + << " mag:" << tsmpl[i].mag + << " x:" << tsmpl[i].xloc + << " y:" << tsmpl[i].yloc + << ""; + out << "rot:" << tsmpl[j].rot + << " flip:" << tsmpl[j].flip + << " mag:" << tsmpl[j].mag + << " x:" << tsmpl[j].xloc + << " y:" << tsmpl[j].yloc + << ""; +#endif + testMult(mktrans(i), mktrans(j), + mktrans(i), mktrans(j) ); + out << "" << std::endl; +} + +template< int nProbes > +void testAllTrans1x1() +{ + for ( int i = 0; i < tsmpl_count; ++i ) + for ( int j = 0; j < tsmpl_count; ++j ) + testTrans1x1(i,j); +} + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + +template< class T, int nProbs > +class inverse +{ + T trns; + T trns2; + +public: + inverse( const T& t ) + { + trns = t; + } + + __forceinline void operator() () + { + for( int i = nProbs; i; --i ) + trns2 = trns.getInverse(); + } +}; + +template< int nProbes > +void testInverse( const base::transform& t1, const base2::transform& t2 ) +{ + const int n = SCALE; + + typedef inverse inverse1_type; + double dblMin1 = mesure( inverse1_type( t1 ), nProbes ); + dblMin1 /= n; + + typedef inverse inverse2_type; + double dblMin2 = mesure( inverse2_type( t2 ), nProbes ); + dblMin2 /= n; + + print_result( dblMin1, dblMin2 ); +} + +template< int nProbes > +void testTransInverse( int i ) +{ + out << ""; +#if 0 + out << "rot:" << tsmpl[i].rot + << " flip:" << tsmpl[i].flip + << " mag:" << tsmpl[i].mag + << " x:" << tsmpl[i].xloc + << " y:" << tsmpl[i].yloc + << ""; + out << "rot:" << tsmpl[j].rot + << " flip:" << tsmpl[j].flip + << " mag:" << tsmpl[j].mag + << " x:" << tsmpl[j].xloc + << " y:" << tsmpl[j].yloc + << ""; +#endif + testInverse(mktrans(i), + mktrans(i) ); + out << "" << std::endl; +} + +template< int nProbes > +void testAllTransInverse() +{ + for ( int i = 0; i < tsmpl_count; ++i ) + testTransInverse(i); +} + +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////// + + +void print_result( double time1, double time2 ) +{ + out << "" << std::setiosflags( std::ios::fixed ) << std::setprecision( 12 ) << time1 + << "" << time2 + << "" << std::setprecision( 6 ) << (1. - time2/time1 )*100 + << "%"; +// printf( "t1 %f t2 %f fast %.3f%%\n", dblDiff1/nProbes, dblDiff2/nProbes, (dblDiff1/dblDiff2-1.)*100, nProbes ); +} + +template< int nProbes > +void testTransform() +{ + out << "pod::point<int32>
" + << "pod::point<int64>
" + << "pod::point<double>
" + << "pod::rectangle<int32>
" + << "pod::rectangle<int64>
" + << "pod::rectangle<double>
" + << "trans*trans
" + << "trans-1


"; +#if 0 + std::cout << "pod::point" << std::endl; + out << "

pod::point<int32>

" << std::endl; + testAllPt(); + out << "

"; +#endif + +#if 0 + std::cout << "pod::point" << std::endl; + out << "

pod::point<int64>

" << std::endl; + testAllPt(); + out << "

"; +#endif + +#if 0 + std::cout << "pod::point" << std::endl; + out << "

pod::point<double>

" << std::endl; + testAllPt(); + out << "

"; +#endif + +#if 1 + std::cout << "pod::rectangle" << std::endl; + out << "

pod::rectangle<int32>

" << std::endl; + testAllRect(); + out << "

"; +#endif + +#if 0 + std::cout << "pod::rectangle" << std::endl; + out << "

pod::rectangle<int64>

" << std::endl; + testAllRect(); + out << "

"; +#endif + +#if 0 + std::cout << "pod::rectangle" << std::endl; + out << "

pod::rectangle<double>

" << std::endl; + testAllRect(); + out << "

"; +#endif + +#if 0 + std::cout << "trans*trans" << std::endl; + out << "

trans*trans

" << std::endl; + testAllTrans1x1(); + out << "

"; +#endif + +#if 0 + std::cout << "inverse trans" << std::endl; + out << "

trans-1

" << std::endl; + testAllTransInverse(); + out << "

"; +#endif +} + +void main ( ) +{ + out.open( "result.html" ); + out << "" << std::endl; + + // Init + perf_init(); + base::transform::initFnTables(); + base2::transform::initFnTables(); + + testTransform<100>(); + + out << ""; + out.close(); + +#ifdef WIN32 + PROCESS_INFORMATION pi; + STARTUPINFO si; + memset( &pi, 0, sizeof( pi ) ); + memset( &si, 0, sizeof( si ) ); + BOOL b = CreateProcess( L"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", L"IEXPLORE.EXE file:///D:/work/prj/test/testTransform/result.html", 0, 0, false, 0, 0, 0, &si, &pi ); +#endif +} \ No newline at end of file diff --git a/testTransform/sseprim.h b/testTransform/sseprim.h new file mode 100644 index 0000000..4a12d5f --- /dev/null +++ b/testTransform/sseprim.h @@ -0,0 +1,198 @@ +// +// +// +#ifndef __SSE_PRIM__H__ +#define __SSE_PRIM__H__ + +#ifdef SSE_OPTIMIZATIONS + +#include "ssetypes.h" + +#if defined( _MSC_VER ) + +/* +Checking for the DAZ Flag in the MXCSR Register +The denormals-are-zero flag in the MXCSR register is available in most of the +Pentium 4 processors and in the Intel Xeon processor, with the exception of some +early steppings. To check for the presence of the DAZ flag in the MXCSR register, do +the following: +1. Establish a 512-byte FXSAVE area in memory. +2. Clear the FXSAVE area to all 0s. +3. Execute the FXSAVE instruction, using the address of the first byte of the cleared +FXSAVE area as a source operand. See “FXSAVE—Save x87 FPU, MMX, SSE, and +SSE2 State” in Chapter 3 of the Intel® 64 and IA-32 Architectures Software +Developer’s Manual, Volume 2A, for a description of the FXSAVE instruction and +the layout of the FXSAVE image. +4. Check the value in the MXCSR_MASK field in the FXSAVE image (bytes 28 +through 31). +— If the value of the MXCSR_MASK field is 00000000H, the DAZ flag and +denormals-are-zero mode are not supported. +Vol. 1 11-29 +PROGRAMMING WITH STREAMING SIMD EXTENSIONS 2 (SSE2) +— If the value of the MXCSR_MASK field is non-zero and bit 6 is set, the DAZ +flag and denormals-are-zero mode are supported. +If the DAZ flag is not supported, then it is a reserved bit and attempting to write a 1 +to it will cause a general-protection exception (#GP). See Section 11.6.6, “Guidelines +for Writing to the MXCSR Register,” for general guidelines for preventing generalprotection +exceptions when writing to the MXCSR register. + +11.6.4 Initialization of SSE/SE2 Extensions +The SSE and SSE2 state is contained in the XMM and MXCSR registers. Upon a hardware +reset of the processor, this state is initialized as follows (see Table 11-2): +• All SIMD floating-point exceptions are masked (bits 7 through 12 of the MXCSR +register is set to 1). +• All SIMD floating-point exception flags are cleared (bits 0 through 5 of the MXCSR +register is set to 0). +• The rounding control is set to round-nearest (bits 13 and 14 of the MXCSR +register are set to 00B). +• The flush-to-zero mode is disabled (bit 15 of the MXCSR register is set to 0). +• The denormals-are-zeros mode is disabled (bit 6 of the MXCSR register is set to +0). If the denormals-are-zeros mode is not supported, this bit is reserved and will +be set to 0 on initialization. +• Each of the XMM registers is cleared (set to all zeros). + +to read + +HT Technology + +Intel® 64 and IA-32 Architectures Optimization Reference Manual + +FTZ and DAZ flags in the MXCSR +oprof +*/ + +/* +1. Check that the processor supports the CPUID instruction. Bit 21 of the EFLAGS +register can be used to check processor’s support the CPUID instruction. +2. Check that the processor supports the SSE and/or SSE2 extensions (true if +CPUID.01H:EDX.SSE[bit 25] = 1 and/or CPUID.01H:EDX.SSE2[bit 26] = 1). +*/ +inline bool sse2_available() +{ +} + +/* +Check that the processor supports the SIMD and x87 SSE3 extensions (if +CPUID.01H:ECX.SSE3[bit 0] = 1). +*/ +inline bool sse3_available() +{ +} + +/* +Before an application attempts to use the SSSE3 extensions, the application should +follow the steps illustrated in Section 11.6.2, “Checking for SSE/SSE2 Support.” +Next, use the additional step provided below: +• Check that the processor supports SSSE3 (if CPUID.01H:ECX.SSSE3[bit 9] = 1). +*/ +inline bool ssse3_available() +{ +} + +/* +12.12.2 Checking for SSE4.1 Support +Before an application attempts to use SSE4.1 instructions, the application should +follow the steps illustrated in Section 11.6.2, “Checking for SSE/SSE2 Support.” +Next, use the additional step provided below: +Check that the processor supports SSE4.1 (if CPUID.01H:ECX.SSE4_1[bit 19] = 1), +SSE3 (if CPUID.01H:ECX.SSE3[bit 0] = 1), and SSSE3 (if CPUID.01H:ECX.SSSE3[bit +9] = 1). +*/ +inline bool sse4_1_available() +{ +} + +/* +Before an application attempts to use the following SSE4.2 instructions: +PCMPESTRI/PCMPESTRM/PCMPISTRI/PCMPISTRM, PCMPGTQ;the application should +follow the steps illustrated in Section 11.6.2, “Checking for SSE/SSE2 Support.” +Next, use the additional step provided below: +Check that the processor supports SSE4.2 (if CPUID.01H:ECX.SSE4_2[bit 20] = 1), +SSE4.1 (if CPUID.01H:ECX.SSE4_1[bit 19] = 1), and SSSE3 (if +CPUID.01H:ECX.SSSE3[bit 9] = 1). +Before an application attempts to use the CRC32 instruction, it must check that the +processor supports SSE4.2 (if CPUID.01H:ECX.SSE4_2[bit 20] = 1). +Before an application attempts to use the POPCNT instruction, it must check that the +processor supports SSE4.2 (if CPUID.01H:ECX.POPCNT[bit 23] = 1). +*/ +inline bool sse4_2_available() +{ +} + +#if 1 +// +// Make vector. +// + +__forceinline v2pd get_v2pd( const short* p ) +{ + double tmp[2]; + tmp[0] = double( p[0] ); + tmp[1] = double( p[1] ); + return _mm_loadu_pd( tmp ); +} + +__forceinline v2pd get_v2pd( const int32* p ) +{ + __declspec(align(16)) double tmp[2]; + tmp[0] = double( p[0] ); + tmp[1] = double( p[1] ); + return _mm_loadu_pd( tmp ); +} + +__forceinline v2pd get_v2pd( const int64* p ) +{ + double tmp[2]; + tmp[0] = double( p[0] ); + tmp[1] = double( p[1] ); + return _mm_loadu_pd( tmp ); +} + +__forceinline v2pd get_v2pd( const double* p ) +{ + return _mm_loadu_pd( p ); +// movupd reg, p[0] +} + +// +// Make regular types. +// + +__forceinline void set_v2pd( short* p, register v2pd reg ) +{ + double tmp[2]; + _mm_storeu_pd( tmp, reg ); + p[0] = short( tmp[0] ); + p[1] = short( tmp[1] ); +} + +__forceinline void set_v2pd( int32* p, register v2pd reg ) +{ + __declspec(align(16)) double tmp[2]; + _mm_storeu_pd( tmp, reg ); + p[0] = int32( tmp[0] ); + p[1] = int32( tmp[1] ); +} + +__forceinline void set_v2pd( int64* p, register v2pd reg ) +{ + double tmp[2]; + _mm_storeu_pd( tmp, reg ); + p[0] = int64( tmp[0] ); + p[1] = int64( tmp[1] ); +} + +__forceinline void set_v2pd( double* p, register v2pd reg ) +{ + _mm_storeu_pd( p, reg ); +// movupd [p], reg +} + +#endif + +#elif defined( __GNUC__ ) + +#endif + +#endif//SSE_OPTIMIZATIONS +#endif//__SSE_PRIM__H__ diff --git a/testTransform/ssetypes.h b/testTransform/ssetypes.h new file mode 100644 index 0000000..7ace937 --- /dev/null +++ b/testTransform/ssetypes.h @@ -0,0 +1,48 @@ +// +// +// +#ifndef __SSE_TYPE__H__ +#define __SSE_TYPE__H__ + +#if defined( _MSC_VER ) + +#include + +// +// Intager types +// +typedef int int32; +typedef unsigned int uint32; +typedef __int64 int64; +typedef unsigned __int64 uint64; + +// +// Vector types. +// +typedef __m128i v4dw; +typedef __m128i v4dw; +typedef __m128i v2qw; +typedef __m128d v4ps; +typedef __m128d v2pd; + +#elif defined( __GNUC__ ) + +// +// Intager types +// +typedef int int32; +typedef unsigned int uint32; +typedef long int64; +typedef unsigned long uint64; + +// +// Vector types. +// +typedef int v4dw __attribute__ ((vector_size (16))); +typedef long v2qw __attribute__ ((vector_size (16))); +typedef float v2ps __attribute__ ((vector_size (16))); +typedef double v2pd __attribute__ ((vector_size (16))); + +#endif + +#endif//__SSE_TYPE__H__ \ No newline at end of file diff --git a/testTransform/testTransform.sln b/testTransform/testTransform.sln new file mode 100644 index 0000000..b4844a5 --- /dev/null +++ b/testTransform/testTransform.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testTransform", "testTransform.vcproj", "{5390B9E5-D4C7-45C1-AFDE-8140E5B01134}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5390B9E5-D4C7-45C1-AFDE-8140E5B01134}.Debug|Win32.ActiveCfg = Debug|Win32 + {5390B9E5-D4C7-45C1-AFDE-8140E5B01134}.Debug|Win32.Build.0 = Debug|Win32 + {5390B9E5-D4C7-45C1-AFDE-8140E5B01134}.Release|Win32.ActiveCfg = Release|Win32 + {5390B9E5-D4C7-45C1-AFDE-8140E5B01134}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testTransform/testTransform.vcproj b/testTransform/testTransform.vcproj new file mode 100644 index 0000000..77fbfd8 --- /dev/null +++ b/testTransform/testTransform.vcproj @@ -0,0 +1,362 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testTransform/transform.cpp b/testTransform/transform.cpp new file mode 100644 index 0000000..27ff3ec --- /dev/null +++ b/testTransform/transform.cpp @@ -0,0 +1,1593 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#include "base/type-traits2.h" +//#include "ssetypes.h" + +#include "transform.h" +#include "base/constants.h" + +namespace base +{ + + const stdOrientEnum inverseStdOrient[stdOrientMAX] = + { + R0, + R270, + R180, + R90, + XFlipR0, + XFlipR90, + XFlipR180, + XFlipR270 + }; + /* In Aix64 platform char is by default unsigned this causes difference in values, ensuring signed char array */ + const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2] = + { + // + /// R0: 0 degree rotation with no flip. + /// Coefficients = | 1 0| + /// | 0 1| + // + {{1, 0}, + {0, 1}}, + // + /// R90: 90 degree rotation with no flip. + /// Coefficients = | 0 1| + /// |-1 0| + // + {{0, 1}, + {-1, 0}}, + // + /// R180: 180 degree rotation with no flip. + /// Coefficients = |-1 0| + /// | 0 -1| + // + {{-1, 0}, + {0, -1}}, + // + /// R270: 270 degree rotation with no flip. + /// Coefficients = | 0 -1| + /// | 1 0| + // + {{0, -1}, + {1, 0}}, + // + /// XFlipR0: X flip followed by 0 degree rotation. + /// Coefficients = | 1 0| + /// | 0 -1| + // + {{1, 0}, + {0, -1}}, + // + /// X flip followed by 90 degree rotation. + /// Coefficients = | 0 1| + /// | 1 0| + // + {{0, 1}, + {1, 0}}, + // + /// X flip followed by 180 degree rotation. + /// Coefficients = |-1 0| + /// | 0 1| + // + {{-1, 0}, + {0, 1}}, + // + /// X flip followed by 270 degree rotation. + /// Coefficients = | 0 -1| + /// |-1 0| + // + {{0, -1}, + {-1, 0}} + }; + // + /// Matrix for multiplying standard orientations. + // + const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX] = { + // R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270 + /* R0 */ { R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270}, + /* R90 */ { R90, R180, R270, R0, XFlipR270, XFlipR0, XFlipR90, XFlipR180}, + /* R180 */ { R180, R270, R0, R90, XFlipR180, XFlipR270, XFlipR0, XFlipR90}, + /* R270 */ { R270, R0, R90, R180, XFlipR90, XFlipR180, XFlipR270, XFlipR0}, + /* XFlipR0 */ { XFlipR0, XFlipR90, XFlipR180, XFlipR270, R0, R90, R180, R270}, + /* XFlipR90 */ { XFlipR90, XFlipR180, XFlipR270, XFlipR0, R270, R0, R90, R180}, + /* XFlipR180 */ { XFlipR180, XFlipR270, XFlipR0, XFlipR90, R180, R270, R0, R90}, + /* XFlipR270 */ { XFlipR270, XFlipR0, XFlipR90, XFlipR180, R90, R180, R270, R0} + }; + + + pModifyFunDblToShort modifyDblToShortFunTbl[transformTypeMAX]; + pModifyFunLongToShort modifyLongToShortFunTbl[transformTypeMAX]; + pModifyFunIntToShort modifyIntToShortFunTbl[transformTypeMAX]; + pModifyFunDblToInt modifyDblToIntFunTbl[transformTypeMAX]; + pModifyFunDblToDbl modifyDblToDblFunTbl[transformTypeMAX]; + pModifyFunLongToInt modifyLongToIntFunTbl[transformTypeMAX]; + pModifyFunIntToInt modifyIntToIntFunTbl[transformTypeMAX]; + pModifyFunLongToLong modifyLongToLongFunTbl[transformTypeMAX]; + pModifyFunLongLongToLongLong modifyLongLongToLongLongFunTbl[transformTypeMAX]; + + pModifyRectFunLongToLong modifyRectLongToLongFunTbl[transformTypeMAX]; + pModifyRectFunDblToDbl modifyRectDblToDblFunTbl[transformTypeMAX]; + pModifyRectFunIntToInt modifyRectIntToIntFunTbl[transformTypeMAX]; + + // + /// Table of inverse determining functions by transform type. + // + pGetInverseFun getInverseFnTbl[transformTypeMAX]; + + // + /// Table of multiplication determining functions by transform type. + // + pMultFun multFnTbl[transformTypeMAX*transformTypeMAX]; + + // + /// Modify a point using scale transform. + // + template + pod::point GXX_HIDDEN modifyScale( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::setSaturated(tmp.X()),(oC)base::setSaturated(tmp.Y())); + } + // + /// Modify a point using scale and offset transform. + // + template + pod::point GXX_HIDDEN modifyScaleOffset( + const transform & T, pod::point xy) + { + pod::point tmp = xy % T.getDiagonal() + T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::setSaturated(tmp.X()),(oC)base::setSaturated(tmp.Y())); + } + // + /// Modify a point using a general transform. + // + template + pod::point GXX_HIDDEN modifyGeneral( const transform & T, pod::point xy ) + { + pod::point tmp(T.getCol1()*pod::point(xy),T.getCol2()*pod::point(xy)); + tmp += T.getOffset(); + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) + : + pod::point((oC)base::setSaturated(tmp.X()),(oC)base::setSaturated(tmp.Y())); + } + + template + pod::point GXX_HIDDEN modifyStd ( const transform & T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::setSaturated(d.getX()), (oC)base::setSaturated(d.getY())); + } + // + /// Modify a point using standard transform with magnification + // + template + pod::point GXX_HIDDEN modifyStdMag( const transform &T, pod::point xy ) + { + // + // Transform the point. + // + pod::point d = xy * T.getOrient() * T.get11() + T.getOffset(); + // + // Convert to target coordinate type. + // + return std::tr1::is_floating_point::value ? + pod::point( (oC)(d.getX()), (oC)(d.getY())) + : + pod::point( (oC)base::setSaturated(d.getX()), (oC)base::setSaturated(d.getY())); + } + // + /// Modify a point using resolution transform. + // + template + pod::point GXX_HIDDEN modifyResolution( const transform &T, pod::point xy ) + { + pod::point tmp = xy % T.getDiagonal(); + if (T.getNext()) + { + if ( std::tr1::is_double::value ) + { + pod::point tmp2((double)tmp.X(), + (double)tmp.Y()); + return T.getNext()->modifyDblToDbl(tmp2); + } + else if ( std::tr1::is_i64::value ) + { + pod::point tmp2((i64)base::setSaturated(tmp.X()), + (i64)base::setSaturated(tmp.Y())); + return T.getNext()->modifyLongToLong(tmp2); + } + else if ( std::tr1::is_int::value ) + { + pod::point tmp2((i64)base::setSaturated(tmp.X()), + (i64)base::setSaturated(tmp.Y())); + return T.getNext()->modifyLongToInt(tmp2); + } + else if ( std::tr1::is_short::value ) + { + pod::point tmp2((i64)base::setSaturated(tmp.X()), + (i64)base::setSaturated(tmp.Y())); + return T.getNext()->modifyLongToShort(tmp2); + } + } + else + return std::tr1::is_floating_point::value ? + pod::point((oC)tmp.X(),(oC)tmp.Y()) : + pod::point((oC)base::setSaturated(tmp.X()), + (oC)base::setSaturated(tmp.Y())); + // Should not get here or something is missing. + throw except::programError(); + return pod::point((oC)0, (oC)0); + } + // + // Modify a rectangle using scale transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScale(T,r.getLowerLeft()), + modifyScale(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using scale and offset transform. + // + template + pod::rectangle GXX_HIDDEN modifyScaleOffsetRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyScaleOffset(T,r.getLowerLeft()), + modifyScaleOffset(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using a general transform. + // + template + pod::rectangle GXX_HIDDEN modifyGeneralRect( + const transform & T, + const pod::rectangle & r ) + { + // + // We have to transform all four corner points when using a + // general transform in order to figure out what the new corner + // points will be. + // + pod::point p0 = modifyGeneral(T,r.getLowerLeft()); + pod::point p1 = modifyGeneral(T,r.getLowerRight()); + pod::point p2 = modifyGeneral(T,r.getUpperRight()); + pod::point p3 = modifyGeneral(T,r.getUpperLeft()); + pod::rectangle rect; + rect.merge(p0); + rect.merge(p1); + rect.merge(p2); + rect.merge(p3); + return rect; + } + + template + pod::rectangle GXX_HIDDEN modifyStdRect ( + const transform & T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStd(T,r.getLowerLeft()), + modifyStd(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using standard transform with magnification. + // + template + pod::rectangle GXX_HIDDEN modifyStdMagRect( + const transform &T, + const pod::rectangle & r ) + { + pod::rectangle rect(modifyStdMag(T,r.getLowerLeft()), + modifyStdMag(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + // + // Modify a rectangle using resolution transform. + // + template + pod::rectangle GXX_HIDDEN modifyResolutionRect( + const transform & T, + const pod::rectangle & r) + { + pod::rectangle rect(modifyResolution(T,r.getLowerLeft()), + modifyResolution(T,r.getUpperRight())); + rect.makeValid(); + return rect; + } + + // + /// Initialize the function tables. + // + void transform::initFnTables() + { + // + // double to short + // + modifyDblToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToShortFunTbl[StdTransformType] = &modifyStd; + modifyDblToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // i64 to short + // + modifyLongToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToShortFunTbl[StdTransformType] = &modifyStd; + modifyLongToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to short + // + modifyIntToShortFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToShortFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToShortFunTbl[StdTransformType] = &modifyStd; + modifyIntToShortFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToShortFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToShortFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to int + // + modifyDblToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToIntFunTbl[StdTransformType] = &modifyStd; + modifyDblToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // double to double + // + modifyDblToDblFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyDblToDblFunTbl[GeneralTransformType] = &modifyGeneral; + modifyDblToDblFunTbl[StdTransformType] = &modifyStd; + modifyDblToDblFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyDblToDblFunTbl[ScaleTransformType] = &modifyScale; + modifyDblToDblFunTbl[ResolutionTransformType] = &modifyResolution; + // + // i64 to int + // + modifyLongToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToIntFunTbl[StdTransformType] = &modifyStd; + modifyLongToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // int to int + // + modifyIntToIntFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyIntToIntFunTbl[GeneralTransformType] = &modifyGeneral; + modifyIntToIntFunTbl[StdTransformType] = &modifyStd; + modifyIntToIntFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyIntToIntFunTbl[ScaleTransformType] = &modifyScale; + modifyIntToIntFunTbl[ResolutionTransformType] = &modifyResolution; + // + // i64 to i64 + // + modifyLongToLongFunTbl[ScaleOffsetTransformType] = &modifyScaleOffset; + modifyLongToLongFunTbl[GeneralTransformType] = &modifyGeneral; + modifyLongToLongFunTbl[StdTransformType] = &modifyStd; + modifyLongToLongFunTbl[StdTransformWithMagType] = &modifyStdMag; + modifyLongToLongFunTbl[ScaleTransformType] = &modifyScale; + modifyLongToLongFunTbl[ResolutionTransformType] = &modifyResolution; + // + /// Init get inverse func table. + // + getInverseFnTbl[ScaleOffsetTransformType] = &getInverseScaleOffset; + getInverseFnTbl[GeneralTransformType] = &getInverseGeneral; + getInverseFnTbl[StdTransformType] = &getInverseStd; + getInverseFnTbl[StdTransformWithMagType] = &getInverseStdWithMag; + getInverseFnTbl[ScaleTransformType] = &getInverseScale; + getInverseFnTbl[ResolutionTransformType] = &getInverseResolution; + // + /// Init the multiply func table. + // + multFnTbl[0] = &multScaleOffsetXScaleOffset; + multFnTbl[1] = &multScaleOffsetXGeneral; + multFnTbl[2] = &multScaleOffsetXStd; + multFnTbl[3] = &multScaleOffsetXStdWithMag; + multFnTbl[4] = &multScaleOffsetXScaleOffset; + multFnTbl[5] = &multScaleOffsetXResolution; + multFnTbl[6] = &multGeneralXScaleOffset; + multFnTbl[7] = &multGeneralXGeneral; + multFnTbl[8] = &multGeneralXStd; + multFnTbl[9] = &multGeneralXStdWithMag; + multFnTbl[10] = &multGeneralXScaleOffset; + multFnTbl[11] = &multGeneralXResolution; + multFnTbl[12] = &multStdXScaleOffset; + multFnTbl[13] = &multStdXGeneral; + multFnTbl[14] = &multStdXStd; + multFnTbl[15] = &multStdXStdWithMag; + multFnTbl[16] = &multStdXScaleOffset; + multFnTbl[17] = &multStdXResolution; + multFnTbl[18] = &multStdWithMagXScaleOffset; + multFnTbl[19] = &multStdWithMagXGeneral; + multFnTbl[20] = &multStdWithMagXStd; + multFnTbl[21] = &multStdWithMagXStdWithMag; + multFnTbl[22] = &multStdWithMagXScaleOffset; + multFnTbl[23] = &multStdWithMagXResolution; + multFnTbl[24] = &multScaleOffsetXScaleOffset; + multFnTbl[25] = &multScaleOffsetXGeneral; + multFnTbl[26] = &multScaleOffsetXStd; + multFnTbl[27] = &multScaleOffsetXStdWithMag; + multFnTbl[28] = &multScaleXScale; + multFnTbl[29] = &multScaleXResolution; + multFnTbl[30] = &multResolutionXAny; + multFnTbl[31] = &multResolutionXAny; + multFnTbl[32] = &multResolutionXAny; + multFnTbl[33] = &multResolutionXAny; + multFnTbl[34] = &multResolutionXAny; + multFnTbl[35] = &multResolutionXAny; + // + // Initialize the rectangle modification function tables. + // + modifyRectLongToLongFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectLongToLongFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectLongToLongFunTbl[StdTransformType] = modifyStdRect; + modifyRectLongToLongFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectLongToLongFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectLongToLongFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectDblToDblFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectDblToDblFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectDblToDblFunTbl[StdTransformType] = modifyStdRect; + modifyRectDblToDblFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectDblToDblFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectDblToDblFunTbl[ResolutionTransformType] = modifyResolutionRect; + + modifyRectIntToIntFunTbl[ScaleOffsetTransformType] = modifyScaleOffsetRect; + modifyRectIntToIntFunTbl[GeneralTransformType] = modifyGeneralRect; + modifyRectIntToIntFunTbl[StdTransformType] = modifyStdRect; + modifyRectIntToIntFunTbl[StdTransformWithMagType] = modifyStdMagRect; + modifyRectIntToIntFunTbl[ScaleTransformType] = modifyScaleRect; + modifyRectIntToIntFunTbl[ResolutionTransformType] = modifyResolutionRect; + } + + // Value of standard orientation + const struct { bool xflip; double angle;} stdOrientXFlipAngValues[stdOrientMAX]= + { + {false, 0. }, // RO + {false, 90. }, // R90 + {false, 180. }, // R180 + {false, 270. }, // R270 + {true, 0. }, // XFlipR0 + {true, 90. }, //XFlipR90 + {true, 180. }, //XFlipR180 + {true, 270. } //XFlipR270 + }; + + const void transform::getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const + { + + if( type!=GeneralTransformType) + { + // + // standard orientation. Use table + // + int idx= (int) getOrient().getOri(); + isXFlip= stdOrientXFlipAngValues[idx].xflip; + angle = stdOrientXFlipAngValues[idx].angle; + mag = a11; + } + else + { + // From constructor + // double multiplier = 1.0; + // if (inXFlip == true) + // multiplier = -1.0; + // register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + // register double cosine = cos(newAngle); + // register double sine = sin(newAngle); + // a11 = inMag * cosine; + // a12 = inMag * sine; + // a21 = -inMag * multiplier * sine; + // a22 = inMag * multiplier * cosine; + // + // How to get angle, inMage and inXFlip from a11, a12, a21, and a22 + // Let sumProd = a11* a22 - a12*a21 + // = (inMag*consine)(inMag * multiplier * cosine) - (inMag * sine)(-inMag * multiplier * sine) + // = inMag*inMag*multiplier*consine*consine + inMag*inMag*multiplier*sine*sine + // = inMag*inMag*multiplier(consine* consine + sine*sine) + // = inMag*inMag*multiplier + // + // if( sumProd) < 0 ==> inXFlip=true + // inMag= SquareRoot( Abs(sumPro)); + // Angle= ArcCosine(a11/inMag) + + double sumProd= a11*a22 - a12*a21; + + //get inXFlip. + // sumProd= imMag*imMag*multiplier + isXFlip= sumProd < 0; + + // get abs(imMag*imMag) + if(sumProd<0) + sumProd= -sumProd; + + // get mag + mag= sqrt(sumProd); + + // get angle + if(mag> 0) + { + + double angleR= acos(a11/mag); + angle=radiansToDegrees(angleR); + + // aCos funciton range is 0 to 180. + // We need to decide if angle is between 180 to 360 + // + // How to solve it + // Let (Xt, Yt) is the point by applying (1,0) with transformation without xFlip, + // if Yt > 0, then angle is located between 180 and 360 + // + // i.e. + // | a11 a12 | x | 1 | = [a11 a21p ] = (Xt, Yt) + // | a21p a22 | | 0 | + // a21= multiplier * a21p = xFlip + angle + // if a21p > 0 angle is located between 180 and 360 + // + double a21p= isXFlip? -a21: a21; + if( a21p> 0 ) + angle= 360. - angle; + + } + else + angle=0; + }// end else + } + + transform transform::getInverseScaleOffset(const transform & T) + { + return transform( -T.offset.X()/T.a11, + -T.offset.Y()/T.a22, + 1.0/T.a11, + 1.0/T.a22); + } + // + /// Get the inverse of a general transform. + // + transform transform::getInverseGeneral(const transform & T ) + { + // + // compute the determinant + // + double det = T.a11*T.a22 - T.a12*T.a21; + + return transform( (T.offset.Y()*T.a21 - T.offset.X()*T.a22)/det, + (T.offset.X()*T.a12 - T.offset.Y()*T.a11)/det, + T.a22/det, + -T.a12/det, + -T.a21/det, + T.a11/det); + } + // + /// Get the inverse of a standard transform. + // + transform transform::getInverseStd(const transform & T) + { + // + // Transform the offset. + // + pod::point off = - T.offset * stdOrient(inverseStdOrient[T.orient.getOri()]); + // + // Return the inverted standard transform. + // + return transform (off.X(), off.Y(), + inverseStdOrient[T.orient.getOri()]); + } + // + /// Get the inverse of a standard transform with mag. + // + transform transform::getInverseStdWithMag(const transform & T) + { + register double oneOverMag = 1.0/T.a11; + register stdOrientEnum e = inverseStdOrient[T.orient.getOri()]; + // + // Transform the offset. + // + pod::point off = - (T.offset * stdOrient(e)) * oneOverMag; + + return transform( off.X(), + off.Y(), + e, + oneOverMag ); + } + // + /// Get the inverse of a scale transform. + // + transform transform::getInverseScale(const transform & T) + { + return transform( 0.0, + 0.0, + 1.0/T.a11, + 1.0/T.a22); + } + // + // Get the inverse of a resolution transform. + // + transform transform::getInverseResolution(const transform & T) + { + if (T.next) { + transform T1(T.a11, T.a22, false); + transform T2; + T1.mult(*(T.next), T2); + return T2.getInverse(); + } else { + return transform(1.0/T.a11, 1.0/T.a22, false); + } + } + + // + /// Multiply two scale transforms. + // + void transform::multScaleXScale(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point(0.0, 0.0); + } + // + /// Multiply a scale transform with a resolution transform. + // + void transform::multScaleXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp(T1.a11, T1.a22, false); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(0.0); + outT.next->offset.setY(0.0); + } else { + outT.next = new transform(T1.a11, T1.a22, false); + } + } + } + // + // + /// Multiply two scale offset transforms. + // + void transform::multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleOffsetTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( + T2.a11*T1.offset.X() + T2.offset.X(), + T2.a22*T1.offset.Y() + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a general transform. + // + void transform::multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a11*T2.a12; + outT.a21 = T1.a22*T2.a21; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21 + T2.offset.X(), + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22 + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a standard transform. + // + void transform::multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0], + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]) + + T2.offset; + } + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + void transform::multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]), + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1])) + + T2.offset; + } + // + /// Multiply a scale offset transform with a resolution transform. + // + void transform::multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleOffsetTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = 0.0; + outT.next->a21 = 0.0; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + } + } + } + // + /// Multiply a general transform with a scale offset transform. + // + void transform::multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two general transforms. + // + void transform::multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11 + T1.a12*T2.a21; + outT.a12 = T1.a11*T2.a12 + T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11 + T1.a22*T2.a21; + outT.a22 = T1.a21*T2.a12 + T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a general transform with a standard transform. + // + void transform::multGeneralXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + outT.a21 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + void transform::multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a12 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + outT.a21 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a22 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + // + // Transform the offset. + // + outT.offset = (T1.offset * T2.orient) * T2.a11 + T2.offset; + } + // + /// Multiply a general transform with a resolution transform. + // + void transform::multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = GeneralTransformType; + outT.next->a11 = T1.a11; + outT.next->a22 = T1.a22; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + } + } + } + // + /// Multiply a standard transform with a scale and offset transform. + // + void transform::multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with a general transform. + // + void transform::multStdXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two standard transforms. + // + void transform::multStdXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformType; + outT.orient = multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + void transform::multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with a resolution transform. + // + void transform::multStdXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) + { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + tmp.mult(*(T2.next), *(outT.next)); + } + else if (outT.next) + { + outT.next->type = StdTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } + else + { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + } + } + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + void transform::multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + void transform::multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21); + outT.a12 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22); + outT.a21 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21); + outT.a22 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22); + // + // Transfomr the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + void transform::multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply two standard transforms with magnification. + // + void transform::multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11*T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + void transform::multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = StdTransformWithMagType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + } + } + } + // + /// Multiply a resolution transform with any transform. + // + void transform::multResolutionXAny(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T1.a11; + outT.a12 = T1.a12; + outT.a21 = T1.a21; + outT.a22 = T1.a22; + + if(T1.next) { + if (!(outT.next)) + outT.next = new transform; + T1.next->mult(T2, *(outT.next)); + } else { + outT.next = new transform(T2); + } + } + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void transform::modify( const pod::point& rSrc, pod::point& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffset( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneral( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStd( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMag( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScale( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolution( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// This is pod::rectangle version of above function. + // + template + void transform::modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + switch ( type ) + { + case ScaleOffsetTransformType: + rDest = modifyScaleOffsetRect( *this, rSrc ); + break; + + case GeneralTransformType: + rDest = modifyGeneralRect( *this, rSrc ); + break; + + case StdTransformType: + rDest = modifyStdRect( *this, rSrc ); + break; + + case StdTransformWithMagType: + rDest = modifyStdMagRect( *this, rSrc ); + break; + + case ScaleTransformType: + rDest = modifyScaleRect( *this, rSrc ); + break; + + case ResolutionTransformType: + rDest = modifyResolutionRect( *this, rSrc ); + break; + + default: + throw except::outOfRange("base::modify: Unknown type."); + } // switch + } + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void transform::modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + // + // If we have orthogonal transform? + // First check get12 since most of transform will + // have no rotation factor. + // + if ( !next && (get12() == 0 || get11() == 0)) + modify( rSrc, rDest ); + // + // General case. + // + else + { + rDest.makeInvalid(); + pod::point tmp; + + modify( rSrc.getLowerLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getLowerRight(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperLeft(), tmp ); + rDest.merge( tmp ); + + modify( rSrc.getUpperRight(), tmp ); + rDest.merge( tmp ); + } + } + +// +/// Print a transform, mainly for debug purpose. +// +void transform::print(FILE *outStream, const char *linePrefix) const +{ + std::string str = (std::string)(*this); + fprintf(outStream, "%stype = %s.\n", linePrefix, + str.c_str()); + if (getType() != ResolutionTransformType && + getType() != ScaleTransformType) { + fprintf(outStream, "%stx = %f.\n", linePrefix, offset.X()); + fprintf(outStream, "%sty = %f.\n", linePrefix, offset.Y()); + } + switch(type) { + case ScaleOffsetTransformType: + case ScaleTransformType: + fprintf(outStream, "%sscaleX = %f.\n", linePrefix, a11); + fprintf(outStream, "%sscaleY = %f.\n", linePrefix, a22); + break; + + case GeneralTransformType: + fprintf(outStream, "%sa11 = %f.\n", linePrefix, a11); + fprintf(outStream, "%sa12 = %f.\n", linePrefix, a12); + fprintf(outStream, "%sa21 = %f.\n", linePrefix, a21); + fprintf(outStream, "%sa22 = %f.\n", linePrefix, a22); + break; + + case StdTransformType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + break; + + case StdTransformWithMagType: + str = (std::string)orient; + fprintf(outStream, "%sorient = %s.\n", linePrefix, str.c_str()); + fprintf(outStream, "%smag = %f.\n", linePrefix, a11); + break; + + case ResolutionTransformType: + fprintf(outStream, "%sscale = %f.\n", linePrefix, a11); + if (next) { + std::string bfr(linePrefix); + bfr += " "; + next->print(outStream, bfr.c_str()); + } + break; + + default: + throw except::outOfRange("base::transform:print: Unknown type."); + } // switch +} + +// +/// Convert a transform type to a string. +// +transform::operator std::string() const +{ + switch(type) { + case ScaleOffsetTransformType: + return std::string("ScaleOffsetTransform"); + break; + case GeneralTransformType: + return std::string("GeneralTransform"); + break; + case StdTransformType: + return std::string("StdTransform"); + break; + case StdTransformWithMagType: + return std::string("StdTransformWithMag"); + break; + case ScaleTransformType: + return std::string("ScaleTransform"); + break; + case ResolutionTransformType: + return std::string("ResolutionTransform"); + break; + default: + throw except::outOfRange("base::transformTypeToString: Unknown type."); + } // switch +} + +std::ostream & operator << (std::ostream & os, const transform & t) +{ + os << "" << std::endl; + os << "" << std::endl; + os << t.getRow1(); + os << t.getRow2(); + os << "" << std::endl; + os << "" << std::endl; + os << t.getOffset(); + os << "" << std::endl; + os << "" << std::endl; + return os; +} + + + +/***************************************************************************** +* Instantiate template with some arguments. +*/ +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; + +#if 0 +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; +template void transform::modify( const pod::point&, pod::point& ) const; + +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modify( const pod::rectangle&, pod::rectangle& ) const; + +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +template void transform::modifyBBox( const pod::rectangle&, pod::rectangle& ) const; +#endif + +namespace transformTest +{ + + + /// called by testGetAngleFlipMag() + bool testTran_(int idx, const transform& tr, bool xFlip0, double angle0, double mag0) + { + // Get angle/xflip/mag from tr + bool xFlip; + double angle, mag; + tr.getAngleFlipMag( angle,xFlip, mag); + + // Compare + bool bFlp= xFlip == xFlip0; + bool bAng=(angle - angle0) < absTolerance && + (angle0 -angle) < absTolerance ; + bool bMag= (mag - mag0) < absTolerance && + (mag0 -mag) < absTolerance ; + + // Print error message if there is different + if(!bFlp || !bAng || !bMag) + { + printf(" %-2d tr(xFlop=%s)",idx, (xFlip0?"T":"F")); + if(!bFlp) + printf("!= %s", (xFlip?"T":"F")); + + printf(" (angle=%10.5f)", angle0) ; + if(!bAng) + printf("!= %10.5f", angle); + + printf(" (mag=%5.3f)",mag0); + + if(!bMag) + printf("!= %5.3f", mag); + printf("\n"); + return false; + } + return true; + } + + // + /// Function test getAngelFlipMag() + // + bool testGetAngleFlipMag() + { + struct { bool xFlip; double angle; double mag; } testData[]= + { // xFlip Angle Max index + {false, 0, 1}, //0 standard Orientation + {false, 90, 1.1}, //1 + {false, 180, 1.2}, //2 + {false, 270, 1.3}, //3 + {true, 0, 1.4}, //4 + {true, 90, 1.5}, //5 + {true, 180, 1.6}, //6 + {true, 270, 1.7}, //7 + {false, 23, 1.8}, //8 non-standard Orientation + {true, 23, 1.9}, //9 + {false, 92, 2.1}, //10 + {true, 92, 2.2}, //11 + {false, 192, 2.3}, //12 + {true, 192, 2.4}, //13 + {false, 272, 2.5}, //14 + {true, 272, 2.6} //15 + }; + const int dataCount=16; + int failCtr=0; + int i=0; + for( ;i < dataCount; i++) + { + // Construct transform + transform tr(0,0, + testData[i].xFlip, + testData[i].angle, + testData[i].mag); + if(! testTran_(i, tr, testData[i].xFlip, testData[i].angle, testData[i].mag)) + failCtr++; + } + + /// set a11, a12, a21, a22 directly + transform trR0(101,101, 1, 0, 0, 1); + transform trR90(101,101, 0, 1, -1, 0); + transform trR180(101,101, -1,0, 0, -1); + transform trR270(101,101, 0, -1, 1, 0); + + transform XtrR0(101,101, 1, 0,0, -1); + transform XtrR90(101,101, 0, 1, 1, 0); + transform XtrR180(101,101, -1,0, 0, 1); + transform XtrR270(101,101, 0, -1, -1, 0); + + if(!testTran_(i++, trR0, false, 0, 1)) failCtr++; + if(!testTran_(i++, trR90, false, 90, 1)) failCtr++; + if(!testTran_(i++, trR180, false, 180, 1)) failCtr++; + if(!testTran_(i++, trR270, false, 270, 1)) failCtr++; + if(!testTran_(i++, XtrR0, true, 0, 1)) failCtr++; + if(!testTran_(i++, XtrR90, true, 90, 1)) failCtr++; + if(!testTran_(i++, XtrR180,true, 180, 1)) failCtr++; + if(!testTran_(i++, XtrR270,true, 270, 1)) failCtr++; + + + // Print summary + printf("transformation::testGetAngleFlipMag() test:%s\n", + (failCtr >0 ? " failed":" passed")); + + return failCtr==0; + } + + +}; + +}; // namespace base diff --git a/testTransform/transform.h b/testTransform/transform.h new file mode 100644 index 0000000..a216dd4 --- /dev/null +++ b/testTransform/transform.h @@ -0,0 +1,1493 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#ifndef TRANSFORM_H_ +#define TRANSFORM_H_ + +// _MSC_VER >= 1400 means we deal with VC8 or higher. +#if defined( _MSC_VER ) +/*warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)*/ +#pragma warning( disable: 4290 ) +#endif + +#include +#include +#include + +#include "base/port.h" +#include "base/types.h" +#include "base/constants.h" +#include "base/except.h" +#include "base/rectangle.h" +#include "base/round.h" + +/*! + * round() is only defined in XOPEN_EXTENDED. + * Define it for platforms which do not implement the latter. + */ +#ifndef __USE_XOPEN_EXTENDED +namespace +{ + double round(double x) + { + return floor(x + 0.5); + } +} +#endif + +// +/// The transform.h file contains the different transform types. +// +/*! + * Usage of transforms: + * Transforms are applied to row vectors from the right as shown below: + * OV = IV * T + * Here, OV and IV are the output and input row vectors and T is the transform. + * + * Multiplying transforms: + * Suppose we have a chain of transforms. + * OV = IV * T1 * T2 + * OV = IV * T + * Thus, T can be computed as follows: + * Transform T; + * T1.mult(T2, T); + * + * A general 2-D transform can be viewed in matrix form as follows: + * |a11 a12 0| + * |a21 a22 0| + * | tx ty 1| + * A general transform can be viewed as a sequence of 3 steps: + * 1- Scaling with value (Sx, Sy) (i.e. x' = Sx*x, y' = Sy*y). + * 2- rotating with angle A. + * 3- translating with value (tx, ty). + * In other words, the 2-D transform is the multiplication of the 3 transforms + * as follows: + * |Sx 0 0| | cos(A) sin(A) 0| | 1 0 0| + * |0 Sy 0|*|-sin(A) cos(A) 0|*| 0 1 0| + * |0 0 1| | 0 0 1| |tx ty 1| + * + * Using resolution transforms: + * In order to mimic applying resolution transforms to each cell individually, + * a resolution change operation is applied before anything. Suppose we call + * the resolution change transform RES. Also suppose the transform from the + * cell to the screen is TS. Thus: + * OV = IV * RES * TS. + * In order to change the resolution of a layout, we need to insert the + * resolution transform RES in the chain. Hence: + * 1- Create a resolution transform RES(xScale, yScale, true). + * 2- Assuming T is the total transform, T can be computed as follows: + * RES.mult(TS, T). + */ +namespace base +{ + // + /// Enum for types of transforms. + // + enum transformType + { + // + /// ScaleOffsetTransform type. + // + ScaleOffsetTransformType = 0, + // + /// GeneralTransform type. + // + GeneralTransformType, + // + /// StdTransform type. + // + StdTransformType, + // + /// StdTransformWithMag type. + // + StdTransformWithMagType, + // + /// StdTransformWithMag type. + // + ScaleTransformType, + // + /// Resolution type. + // + ResolutionTransformType, + // + /// Always keep this entry as the last enum value. + // + transformTypeMAX + }; // enum transformType + // + /// Inverses of the standard orientations. + // + extern const stdOrientEnum inverseStdOrient[stdOrientMAX]; + // + /// Coefficient matrices for the standard orientations. + // + extern const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2]; + // + /// Matrix holding standard orientations resulting from multiplying + /// different standard orientations. + // + extern const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX]; + + class transform; + // + /// Type definition for determining inverse of various transform types. + // + typedef transform (*pGetInverseFun)(const transform &); + // + /// Table of inverse determining functions by transform type. + // + extern pGetInverseFun getInverseFnTbl[transformTypeMAX]; + + typedef void (*pMultFun)( const transform & T1, + const transform & T2, + transform & outT ); + + extern pMultFun multFnTbl[transformTypeMAX*transformTypeMAX]; + + typedef pod::point (*pModifyFunDblToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToShort)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToShort)(const transform &, pod::point); + + typedef pod::point (*pModifyFunDblToDbl)(const transform &, pod::point); + + typedef pod::point (*pModifyFunDblToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongToInt)(const transform &, pod::point); + typedef pod::point (*pModifyFunIntToInt)(const transform &, pod::point); + + typedef pod::point (*pModifyFunLongToLong)(const transform &, pod::point); + typedef pod::point (*pModifyFunLongLongToLongLong)(const transform &, pod::point); + + // + /// Type definition for for transforming a rectangle of type double to + /// another rectangle of type double. + // + typedef pod::rectangle (*pModifyRectFunDblToDbl)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type i64 to + /// another rectangle of type i64. + // + typedef pod::rectangle (*pModifyRectFunLongToLong)(const transform &, const pod::rectangle &); + typedef pod::rectangle (*pModifyRectFunLongLongToLongLong)(const transform &, const pod::rectangle &); + // + /// Type definition for for transforming a rectangle of type int to + /// another rectangle of type int. + // + typedef pod::rectangle (*pModifyRectFunIntToInt)(const transform &, const pod::rectangle &); + + extern pModifyFunDblToShort modifyDblToShortFunTbl[transformTypeMAX]; + extern pModifyFunLongToShort modifyLongToShortFunTbl[transformTypeMAX]; + extern pModifyFunIntToShort modifyIntToShortFunTbl[transformTypeMAX]; + extern pModifyFunDblToInt modifyDblToIntFunTbl[transformTypeMAX]; + extern pModifyFunDblToDbl modifyDblToDblFunTbl[transformTypeMAX]; + extern pModifyFunLongToInt modifyLongToIntFunTbl[transformTypeMAX]; + extern pModifyFunIntToInt modifyIntToIntFunTbl[transformTypeMAX]; + extern pModifyFunLongToLong modifyLongToLongFunTbl[transformTypeMAX]; + extern pModifyFunLongLongToLongLong modifyLongLongToLongLongFunTbl[transformTypeMAX]; + extern pModifyRectFunLongToLong modifyRectLongToLongFunTbl[transformTypeMAX]; + extern pModifyRectFunLongLongToLongLong modifyRectLongLongToLongLongFunTbl[transformTypeMAX]; + extern pModifyRectFunDblToDbl modifyRectDblToDblFunTbl[transformTypeMAX]; + extern pModifyRectFunIntToInt modifyRectIntToIntFunTbl[transformTypeMAX]; + + + // + /// The main transformation class. + // + class GXX_VISIBLE transform + { + // Data + protected: + // + /// 2X2 coefficient submatrix. + /// a11 would be used for Sx for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + /// Also, a11 would be used for magnification in the case of + /// standard transforms with magnification. + /// a22 would be used for Sy for scale and offset transforms. + /// It would also be used for resolution change for resolution + /// transforms. + // + double a11, a12, a21, a22; + // + // Offset for the transform. + // + pod::point offset; + // + /// Pointer to next transform in chain. This is used by + /// resolution transforms. + // + transform *next; + // + /// Orientation field. + // + base::stdOrient orient; + // + /// Type of transform. + // + unsigned int type : 4; + + // Typedefs + protected: + + typedef pod::point (*pModifyFunDblToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToShort)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToInt)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongLongToLongLong)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunDblToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunIntToDbl)( + const transform &T, + pod::point xy ); + + typedef pod::point (*pModifyFunLongToDbl)( + const transform &T, + pod::point xy ); + + private: + + // + /// Get the inverse of a scale offset transform. + // + static transform getInverseScaleOffset(const transform & T); + // + /// Get the inverse of a general transform. + // + static transform getInverseGeneral(const transform & T ); + // + /// Get the inverse of a standard transform. + // + static transform getInverseStd(const transform & T); + // + /// Get the inverse of a standard transform with mag. + // + static transform getInverseStdWithMag(const transform & T); + // + /// Get the inverse of a scale transform. + // + static transform getInverseScale(const transform & T); + // + // Get the inverse of a resolution transform. + // + static transform getInverseResolution(const transform & T); + // + /// Multiply two scale transforms. + // + static void multScaleXScale(const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale transform with a resolution transform. + // + static void multScaleXResolution( const transform &T1, + const transform &T2, + transform &outT); + // + // + /// Multiply two scale offset transforms. + // + static void multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a general transform. + // + static void multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a scale offset transform with a standard transform. + // + static void multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + static void multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT); + // + /// Multiply a scale offset transform with a resolution transform. + // + static void multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a scale offset transform. + // + static void multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two general transforms. + // + static void multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform. + // + static void multGeneralXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + static void multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a general transform with a resolution transform. + // + static void multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a scale and offset transform. + // + static void multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a general transform. + // + static void multStdXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms. + // + static void multStdXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + static void multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with a resolution transform. + // + static void multStdXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + static void multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + static void multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + static void multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply two standard transforms with magnification. + // + static void multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + static void multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT); + // + /// Multiply a resolution transform with any transform. + // + static void multResolutionXAny(const transform &T1, + const transform &T2, transform &outT); + + // Construction + public: + + // + /// Initialize the function tables. + // + /*! + Attention please: Since base is (currently) linked statically all + the global variables in transform.h get instantiated multiple times + in Windows (Linux is smarter here), hence all the shared libraries + (that intend to be running on Windows) should consider calling + initFnTables() in their initialization code. + */ + static void initFnTables(); + + // + /// Default constuctor. + // + transform() + : + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(0.0,0.0), + next(NULL), + orient(R0), + type(StdTransformType) + {} + // + /// Constructor for a scale offset transform. + // + transform( + double offsetX, + double offsetY, + double scaleX, + double scaleY + ) + : + a11(scaleX), + a12(0.0), + a21(0.0), + a22(scaleY), + offset(offsetX,offsetY), + next(NULL), + type(ScaleOffsetTransformType) + { + double xAbs(offsetX > 0.0 ? offsetX : -offsetX); + double yAbs(offsetY > 0.0 ? offsetY : -offsetY); + if (xAbs < absTolerance && yAbs < absTolerance) + type = ScaleTransformType; + } + // + /// Constructor for a general transform. + // + transform( + double offsetX, + double offsetY, + double coeff11, + double coeff12, + double coeff21, + double coeff22 + ) + : + a11(coeff11), + a12(coeff12), + a21(coeff21), + a22(coeff22), + offset(offsetX,offsetY), + next(NULL), + type(GeneralTransformType) + {}; + // + /// Constructor for a rotate transform. + /// @param inCx X coordinate of the center of rotation. + /// @param inCy Y coordinate of the center of rotation. + /// @param angle rotation angle in degrees. + // + transform( + double inCx, + double inCy, + double angle + ) + : + a11(cos(degreesToRadians(angle))), + a12(sin(degreesToRadians(angle))), + a21(-a12), + a22(a11), + offset(inCy * a12 - inCx * a11 + inCx, + - inCy * a11 - inCx * a12 + inCy), + next(NULL), + type(GeneralTransformType) + {} + // + /// Constructor for a standard transform. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient = R0 + ) + : + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformType) + {} + // + /// Constructor for a standard transform with magnification. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient, + double inMag) + : + a11(inMag), + a12(0.0), + a21(0.0), + a22(inMag), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformWithMagType) + {} + // + /// Advanced constructor for typical references. + /// @param offsetX X value of translation offset. + /// @param offsetY Y value of translation offset. + /// @param inXFlip boolean reflecting the presence of an X flip. + /// @param inAngle rotation angle in degrees. + /// @param inMag magnification. + // + transform( + double offsetX, + double offsetY, + bool inXFlip, + double inAngle, + double inMag) + : + offset(offsetX,offsetY), + next(NULL) + { + stdOrient newOrient(inXFlip, inAngle); + if (newOrient.getOri() != UnknownStdOrient) + { + orient = newOrient; + if (inMag > 1.0 + relTolerance || + inMag < 1.0 - relTolerance) + { + a11 = inMag; + a12 = 0.0; + a21 = 0.0; + a22 = inMag; + type = StdTransformWithMagType; + } + else + { + a11 = 1.0; + a12 = 0.0; + a21 = 0.0; + a22 = 1.0; + type = StdTransformType; + } + } + else + { + type = GeneralTransformType; + register double multiplier = 1.0; + if (inXFlip == true) + multiplier = -1.0; + register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + register double cosine = cos(newAngle); + register double sine = sin(newAngle); + a11 = inMag * cosine; + a12 = inMag * sine; + a21 = -inMag * multiplier * sine; + a22 = inMag * multiplier * cosine; + } + } + // + /// Scale or resolution transform. + /// @param xScale X value of the scale factor. + /// @param yScale Y value of the scale factor. + /// @param rouding A true value means it is a resolution transform. + /// A false value will result in a standard scale transform. + // + transform( + double xScale, + double yScale, + bool rounding) + : + a11(xScale), + a12(0.0), + a21(0.0), + a22(yScale), + offset(0.0, 0.0), + next(NULL), + orient(R0), + type(ScaleTransformType) + { + if (rounding) { + // If both scales are whole numbers, it is + // a scale transform. + // If either scale is not close enough to an whole + // number, it is a resolution transform. + double rVal(base::round(xScale)); + double diff(xScale - rVal); + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + else { + rVal = base::round(yScale); + diff = yScale - rVal; + diff = diff > 0.0 ? diff : -diff; + if (diff > absTolerance) + type = ResolutionTransformType; + } + } + } + // + /// Copy constructor + // + transform(const transform & inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + if ( inT.next ) + next = new transform(*inT.next); + else + next = 0; + } + + // + /// Assignment operator + // + transform & operator = (const transform &inT) + { + type = inT.type; + orient = inT.orient; + offset = inT.offset; + a11 = inT.a11; + a12 = inT.a12; + a21 = inT.a21; + a22 = inT.a22; + + if (inT.next) + { + if (next) + *next = *(inT.next); + else + next = new transform(*(inT.next)); + } + else + { + delete next; + next = NULL; + } + return *this; + } + + // + /// Destructor + // + ~transform() + { + if (next) + delete next; + } + +public: + // + /// Equal operator + // + bool operator == (const transform &inT) + { + if ((inT.type == type) && + (inT.orient.getOri() == orient.getOri()) && + (inT.a11 == a11) && + (inT.a12 == a12) && + (inT.a21 == a21) && + (inT.a22 == a22) && + (inT.offset == offset)) + { + if ( !next ) + return (!inT.next); + else if ( inT.next ) + return (*next == *(inT.next)); + else + return false; + } + + return false; + } + + // + /// Non equal operator + // + bool operator != (const transform &inT) + { + return !(*this == inT); + } + + // + /// Test whether this is an identity transform. + // + bool isIdentityTransform() const + throw (except::outOfRange) + { + const double onePlusTolerance = 1.0 + relTolerance; + const double oneMinusTolerance = 1.0 - relTolerance; + // + // See if the offsets are beyond the origin. + // + if (offset.X() > absTolerance || offset.X() < -absTolerance || + offset.Y() > absTolerance || offset.Y() < -absTolerance) + return false; + // + // Check by transform type. + // + switch((transformType) type) + { + case StdTransformWithMagType: + if (a11 > onePlusTolerance || a11 < oneMinusTolerance) + return false; + + case StdTransformType: + if (orient.getOri() != R0) + return false; + break; + + case GeneralTransformType: + if ( a12 > absTolerance || + a12 < -absTolerance || + a21 > absTolerance || + a21 < -absTolerance) + return false; + + case ScaleOffsetTransformType: + case ScaleTransformType: + if ( a11 > onePlusTolerance || + a11 < oneMinusTolerance || + a22 > onePlusTolerance || + a22 < oneMinusTolerance) + return false; + break; + + case ResolutionTransformType: + return false; + break; + + default: + throw except::outOfRange("base::transform:isIdentityTransform: Unknown type."); + } + return true; + } + + // + /// Returns the type of the transform. + // + transformType getType() const + { + return (transformType) type; + } + // + /// Returns the type of the transform chain. + // + transformType getTypeOfChain() const + { + const transform *t = this; + while (t->getNext() != NULL) + t = t->getNext(); + return (transformType) t->type; + } + // + /// Returns the offset point of the transform. + // + pod::point getOffset() const + { + return offset; + } + // + /// Returns the offset point of the transform taking into account also resolution. + // + pod::point getOffsetRes() const + { + if ( getType() != ResolutionTransformType ) + return offset; + else + { + pod::point zero( 0., 0.); + pod::point off; + modify( zero, off ); + return off; + } + } + // + /// Set the offset of the transform. + // + void setOffset( pod::point off ) + { + offset = off; + } + stdOrient getOrient() const + { + return orient; + } + pod::point getDiagonal() const + { + return pod::point(a11,a22); + } + pod::point getRow1() const + { + return pod::point(a11,a12); + } + pod::point getRow2() const + { + return pod::point(a21,a22); + } + pod::point getCol1() const + { + return pod::point(a11,a21); + } + pod::point getCol2() const + { + return pod::point(a12,a22); + } + // + /// Return the magnitude of the vector (1,0). + // + double getXVectorMag() const + { + if ( a21 == 0.0 ) + return ::fabs(a11); + else if ( a11 == 0.0 ) + return ::fabs(a21); + else + return ::sqrt(a11*a11 + a21*a21); + } + // + /// A special function to return the X scale factor. This + /// is a nonnegative value that reflects the scaling effect + /// in the X direction. + // + double getXScale() const + { + if (type != ResolutionTransformType) + return getXVectorMag(); + else + return getXVectorMag() * (next ? next->getXScale() : 1.0); + } + // + /// Returns the a11 entry of the matrix. If the matrix is a scaling + /// one, then this returns the X-scale factor. + /// The result is not correct for all types of transforms. + // + double get11() const + { + return a11; + } + // + /// Return the a12 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get12() const + { + return a12; + } + // + /// Return the a21 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get21() const + { + return a21; + } + // + /// Returns the a22 entry of the matrix. If the matrix is a scaling + /// one, then this returns the Y-scale factor. + /// The result is not correct for all types of transforms. + // + double get22() const + { + return a22; + } + // + /// Return the next field. + // + const transform *getNext() const + { + return next; + } + // + /// Return the next field. + // + transform *getNext() + { + return next; + } + + // + /// get angle, isXFlip and mag from transformation + // + const void getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const; + +// Complex functions. +public: + // + /// Multiply with another transform. + // + void mult(const transform &T2, transform &outT) const + { + (*(multFnTbl[(type*transformTypeMAX)+T2.type]))(*this,T2,outT); + } + + transform operator *(const transform & T) const + { + transform out; + mult(T,out); + return out; + } + // + /// Scale the transform by the given scalar. + // + transform & operator *= (const double d) + { + if (type != ResolutionTransformType) { + transform tmp(d, d, false); + transform out; + mult(tmp, out); + *this = out; + } else { + if (next) + *next *= d; + else + next = new transform(d, d, false); + } + return *this; + } + + // + /// Return the inverse transform of the transform. + // + transform getInverse() const + { + return (*(getInverseFnTbl[type]))(*this); + } + +#if 1 + // + /// Do nothing method for syntactic completeness. + // + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + pod::point modifyDblToInt(pod::point) const + { return pod::point(); } + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + pod::point modifyDblToShort(pod::point) const + { return pod::point(); } + pod::point modifyDblToDbl(pod::point) const + { return pod::point(); } + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + pod::point modifyIntToInt(pod::point) const + { return pod::point(); } + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + pod::point modifyIntToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToShort(pod::point) const + { return pod::point(); } + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + pod::point modifyLongToInt(pod::point) const + { return pod::point(); } + + //////////////////////////////////////////////////////////////// + + // + /// Modify a single point. + // + pod::point modifyDblToShort(pod::point p) const + { + return (*(modifyDblToShortFunTbl[type]))(*this, p); + } + + pod::point modifyDblToInt(pod::point p) const + { + return (*(modifyDblToIntFunTbl[type]))(*this, p); + } + + // + /// Transform doubles to doubles. + // + pod::point modifyDblToDbl(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + pod::point modify(pod::point p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + + template + pod::rectangle modify(pod::rectangle p) const + { + return pod::rectangle( 0, 0, 0, 0 ); + } + + pod::point modifyIntToInt(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + pod::point modify(pod::point p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } + + pod::point modifyIntToShort(pod::point p) const + { + return (*(modifyIntToShortFunTbl[type]))(*this, p); + } + + pod::point modifyLongToShort(pod::point p) const + { + return (*(modifyLongToShortFunTbl[type]))(*this, p); + } + + // + /// Transform longs to ints. + // + pod::point modifyLongToInt(pod::point p) const + { + return (*(modifyLongToIntFunTbl[type]))(*this, p); + } + + // + /// Transform longs to longs. + // + pod::point modifyLongToLong(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + // + /// Transform longs to longs. + // + pod::point modifyLongLongToLongLong(pod::point p) const + { + return (*(modifyLongLongToLongLongFunTbl[type]))(*this, p); + } + + pod::point modify(pod::point p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } +#endif + + // + // + // +#if 1 + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectDblToDblFunTbl[type]))(*this, r); + } + + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectLongToLongFunTbl[type]))(*this, r); + } + + pod::rectangle operator()(const pod::rectangle & r) const + { + return (*(modifyRectIntToIntFunTbl[type]))(*this, r); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyDblToDblFunTbl[type]))(*this, p); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyLongToLongFunTbl[type]))(*this, p); + } + + pod::point operator()(const pod::point & p) const + { + return (*(modifyIntToIntFunTbl[type]))(*this, p); + } +#endif + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + void modify( const pod::point& rSrc, pod::point& rDest ) const; + + // + /// This is pod::rectangle version of above function. + // + template + void modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + void modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const; + + // + /// Convert a transform type to a string. + // + operator std::string() const; + friend std::ostream & operator << (std::ostream & os, const transform & t); + + // + /// Print a transform, mainly for debug purpose. + // + void print(FILE *outStream, const char *linePrefix) const; + // + /// Dump transform. + // + void dump( std::ostream& ) const; + + }; // class transform + +namespace transformTest +{ + + /// API test getAngelFlipmag + bool testGetAngleFlipMag(); +}; + + /*! + * Simple resolution chain implementation. + * Objects of this class can receive the resolution portion of transform + * objects and apply them to double precision points. + */ + class resolutionChain + { + private: + int chainSize; + pod::point *chain; + + // + /// Get the resolution chain from a transform object. + // + void getResFromTransform(const transform &trn) + { + chainSize = 0; + chain = NULL; + // + // Calculate the resolution chain size. + // + const transform *t = &trn; + while (t && t->getType() == ResolutionTransformType) + { + chainSize++; + t = t->getNext(); + } + if (chainSize == 0) + return; + // + // Initialize the resolutions. + // + chain = new pod::point[chainSize]; + t = &trn; + for (int i = 0; i < chainSize; i++) + { + chain[i] = t->getDiagonal(); + t = t->getNext(); + } + } + + public: + // + /// Default do-nothing constructor. + // + resolutionChain() : + chainSize(0), chain(NULL) + {} + // + /// Construct the resolution chain of a transform object. + // + resolutionChain(const transform &trn) : + chainSize(0), chain(NULL) + { + getResFromTransform(trn); + } + // + /// Assign to this the resolution chain of a transform object. + // + resolutionChain &operator = (const transform &trn) + { + if (chain) + delete[] chain; + getResFromTransform(trn); + return *this; + } + // + /// Destroy the chain. + // + ~resolutionChain() + { + if (chain) + delete[] chain; + } + // + /// Check if this is the resolution chain of trn. + // + bool isResChainOf(const transform &trn) const + { + const transform *t = &trn; + for (int i = 0; i < chainSize; i++) + { + if (!t || t->getType() != ResolutionTransformType) + return false; + if (chain[i] != t->getDiagonal()) + return false; + t = t->getNext(); + } + if (t && t->getType() == ResolutionTransformType) + return false; + return true; + } + // + /// Apply the chain to the point p. Round after each + /// resolution change if needed. + // + pod::point apply(pod::point p, bool round = true) const + { + pod::point r = p; + for (int i = 0; i < chainSize; i++) + { + r = r % chain[i]; + if (round) + r = pod::point(::round(r.getX()), + ::round(r.getY())); + } + return r; + } + // + /// Apply the chain to the rectangle r. Round after each + /// resolution change if needed. + // + pod::rectangle apply(const pod::rectangle &r, bool round = true) const + { + pod::point ll = r.getLowerLeft(); + pod::point ur = r.getUpperRight(); + for (int i = 0; i < chainSize; i++) + { + ll = ll % chain[i]; + ur = ur % chain[i]; + if (round) + { + ll = pod::point(::round(ll.getX()), + ::round(ll.getY())); + ur = pod::point(::round(ur.getX()), + ::round(ur.getY())); + } + } + return pod::rectangle(ll, ur); + } + // + /// Dump transform. + // + void dump( std::ostream& ) const; + }; + + /*! + * Simple transformation class. + * This class does not allow resolution change transformations - they + * should be modeled by resolutionChain instead. Objects of this class + * consist of a 2x2 matrix and an offset and can be applied to double + * precision points. + */ + class simpleTransform + { + private: + pod::point col1; + pod::point col2; + pod::point offset; + + public: + // + /// Default identity transformation constructor. + // + simpleTransform() : + col1(1, 0), col2(0, 1), offset(0, 0) + {} + // + /// Construct a transformation from a transform object + /// skipping the resolution chain. + // + simpleTransform(const transform &trn) : + col1(1, 0), col2(0, 1), offset(0, 0) + { + // + // Skip the resolution part + // + const transform *t = &trn; + while (t && t->getType() == base::ResolutionTransformType) + t = t->getNext(); + // + // If there is anything left, dig out the parameters from t. + // + if (t) + { + if (t->getType() != ScaleTransformType) + offset = t->getOffset(); + + switch (t->getType()) + { + case base::ScaleTransformType: + case base::ScaleOffsetTransformType: + col1 = pod::point(t->get11(), 0.0); + col2 = pod::point(0.0, t->get22()); + break; + + case base::GeneralTransformType: + col1 = t->getCol1(); + col2 = t->getCol2(); + break; + + case base::StdTransformType: + case base::StdTransformWithMagType: + if (t->getOrient().getOri() == R90) + { + col1 = pod::point(0.0, -1.0); + col2 = pod::point(1.0, 0.0); + } + if (t->getOrient().getOri() == R180) + { + col1 = pod::point(-1.0, 0.0); + col2 = pod::point(0.0, -1.0); + } + if (t->getOrient().getOri() == R270) + { + col1 = pod::point(0.0, 1.0); + col2 = pod::point(-1.0, 0.0); + } + if (t->getOrient().getOri() == XFlipR0) + { + col1 = pod::point(1.0, 0.0); + col2 = pod::point(0.0, -1.0); + } + if (t->getOrient().getOri() == XFlipR90) + { + col1 = pod::point(0.0, 1.0); + col2 = pod::point(1.0, 0.0); + } + if (t->getOrient().getOri() == XFlipR180) + { + col1 = pod::point(-1.0, 0.0); + col2 = pod::point(0.0, 1.0); + } + if (t->getOrient().getOri() == XFlipR270) + { + col1 = pod::point(0.0, -1.0); + col2 = pod::point(-1.0, 0.0); + } + if (t->getType() == StdTransformWithMagType) + { + col1 *= t->get11(); + col2 *= t->get11(); + } + break; + + default: + break; + } + } + } + // + /// Apply the transformation to a double precision point. + // + pod::point apply(pod::point p) const + { + return pod::point(p * col1, p * col2) + offset; + } + // + /// Apply the transformation to a double precision rectangle. + /// The result is the bounding rectangle of the transformed corners. + // + pod::rectangle apply(const pod::rectangle &r) const + { + using std::min; + using std::max; + + pod::point ll = pod::point(r.getLowerLeft() * col1, + r.getLowerLeft() * col2); + pod::point lr = pod::point(r.getLowerRight() * col1, + r.getLowerRight() * col2); + pod::point ul = pod::point(r.getUpperLeft() * col1, + r.getUpperLeft() * col2); + pod::point ur = pod::point(r.getUpperRight() * col1, + r.getUpperRight() * col2); + double x1 = min(min(ll.getX(), lr.getX()), + min(ul.getX(), ur.getX())); + double y1 = min(min(ll.getY(), lr.getY()), + min(ul.getY(), ur.getY())); + double x2 = max(max(ll.getX(), lr.getX()), + max(ul.getX(), ur.getX())); + double y2 = max(max(ll.getY(), lr.getY()), + max(ul.getY(), ur.getY())); + + return pod::rectangle(x1 + offset.getX(), y1 + offset.getY(), + x2 + offset.getX(), y2 + offset.getY()); + } + // + /// Dump transform. + // + void dump( std::ostream& os ) const; + }; + +} // namespace base + +#endif // TRANSFORM_H_ diff --git a/testTransform/transform2.cpp b/testTransform/transform2.cpp new file mode 100644 index 0000000..95fbb89 --- /dev/null +++ b/testTransform/transform2.cpp @@ -0,0 +1,845 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#include "base/type-traits2.h" +#include "ssetypes.h" + +#include "transform2.h" +#include "base/constants.h" + +namespace base2 +{ + +#if 0 + const stdOrientEnum inverseStdOrient[stdOrientMAX] = + { + R0, + R270, + R180, + R90, + XFlipR0, + XFlipR90, + XFlipR180, + XFlipR270 + }; + /* + In Aix64 platform char is by default unsigned this causes + difference in values, ensuring signed char array + */ + const signed char stdOrientCoeffMatrix[stdOrientMAX][2][2] = + { + // + /// R0: 0 degree rotation with no flip. + /// Coefficients = | 1 0| + /// | 0 1| + // + {{1, 0}, + {0, 1}}, + // + /// R90: 90 degree rotation with no flip. + /// Coefficients = | 0 1| + /// |-1 0| + // + {{0, 1}, + {-1, 0}}, + // + /// R180: 180 degree rotation with no flip. + /// Coefficients = |-1 0| + /// | 0 -1| + // + {{-1, 0}, + {0, -1}}, + // + /// R270: 270 degree rotation with no flip. + /// Coefficients = | 0 -1| + /// | 1 0| + // + {{0, -1}, + {1, 0}}, + // + /// XFlipR0: X flip followed by 0 degree rotation. + /// Coefficients = | 1 0| + /// | 0 -1| + // + {{1, 0}, + {0, -1}}, + // + /// X flip followed by 90 degree rotation. + /// Coefficients = | 0 1| + /// | 1 0| + // + {{0, 1}, + {1, 0}}, + // + /// X flip followed by 180 degree rotation. + /// Coefficients = |-1 0| + /// | 0 1| + // + {{-1, 0}, + {0, 1}}, + // + /// X flip followed by 270 degree rotation. + /// Coefficients = | 0 -1| + /// |-1 0| + // + {{0, -1}, + {-1, 0}} + }; + // + /// Matrix for multiplying standard orientations. + // + const stdOrientEnum multStdOrientMatrix[stdOrientMAX][stdOrientMAX] = { + // R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270 + /* R0 */ { R0, R90, R180, R270, XFlipR0, XFlipR90, XFlipR180, XFlipR270}, + /* R90 */ { R90, R180, R270, R0, XFlipR270, XFlipR0, XFlipR90, XFlipR180}, + /* R180 */ { R180, R270, R0, R90, XFlipR180, XFlipR270, XFlipR0, XFlipR90}, + /* R270 */ { R270, R0, R90, R180, XFlipR90, XFlipR180, XFlipR270, XFlipR0}, + /* XFlipR0 */ { XFlipR0, XFlipR90, XFlipR180, XFlipR270, R0, R90, R180, R270}, + /* XFlipR90 */ { XFlipR90, XFlipR180, XFlipR270, XFlipR0, R270, R0, R90, R180}, + /* XFlipR180 */ { XFlipR180, XFlipR270, XFlipR0, XFlipR90, R180, R270, R0, R90}, + /* XFlipR270 */ { XFlipR270, XFlipR0, XFlipR90, XFlipR180, R90, R180, R270, R0} + } +#endif + + // + /// Initialize the function tables. + // + void transform::initFnTables() + { + } + + // Value of standard orientation + const struct { bool xflip; double angle;} stdOrientXFlipAngValues[stdOrientMAX]= + { + {false, 0. }, // RO + {false, 90. }, // R90 + {false, 180. }, // R180 + {false, 270. }, // R270 + {true, 0. }, // XFlipR0 + {true, 90. }, //XFlipR90 + {true, 180. }, //XFlipR180 + {true, 270. } //XFlipR270 + }; + + const void transform::getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const + { +#if 0 + if( type!=GeneralTransformType) + { + // + // standard orientation. Use table + // + int idx= (int) getOrient().getOri(); + isXFlip= stdOrientXFlipAngValues[idx].xflip; + angle = stdOrientXFlipAngValues[idx].angle; + mag = a11; + } + else +#endif + { + // From constructor + // double multiplier = 1.0; + // if (inXFlip == true) + // multiplier = -1.0; + // register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + // register double cosine = cos(newAngle); + // register double sine = sin(newAngle); + // a11 = inMag * cosine; + // a12 = inMag * sine; + // a21 = -inMag * multiplier * sine; + // a22 = inMag * multiplier * cosine; + // + // How to get angle, inMage and inXFlip from a11, a12, a21, and a22 + // Let sumProd = a11* a22 - a12*a21 + // = (inMag*consine)(inMag * multiplier * cosine) - (inMag * sine)(-inMag * multiplier * sine) + // = inMag*inMag*multiplier*consine*consine + inMag*inMag*multiplier*sine*sine + // = inMag*inMag*multiplier(consine* consine + sine*sine) + // = inMag*inMag*multiplier + // + // if( sumProd) < 0 ==> inXFlip=true + // inMag= SquareRoot( Abs(sumPro)); + // Angle= ArcCosine(a11/inMag) + + double sumProd= a11()*a22() - a12()*a21(); + + //get inXFlip. + // sumProd= imMag*imMag*multiplier + isXFlip= sumProd < 0; + + // get abs(imMag*imMag) + if(sumProd<0) + sumProd= -sumProd; + + // get mag + mag= sqrt(sumProd); + + // get angle + if(mag> 0) + { + + double angleR= acos(a11()/mag); + angle=radiansToDegrees(angleR); + + // aCos funciton range is 0 to 180. + // We need to decide if angle is between 180 to 360 + // + // How to solve it + // Let (Xt, Yt) is the point by applying (1,0) with transformation without xFlip, + // if Yt > 0, then angle is located between 180 and 360 + // + // i.e. + // | a11 a12 | x | 1 | = [a11 a21p ] = (Xt, Yt) + // | a21p a22 | | 0 | + // a21= multiplier * a21p = xFlip + angle + // if a21p > 0 angle is located between 180 and 360 + // + double a21p= isXFlip? -a21(): a21(); + if( a21p> 0 ) + angle= 360. - angle; + + } + else + angle=0; + }// end else + } + +#if 0 + transform transform::getInverseScaleOffset(const transform & T) + { + return transform( -T.offset.X()/T.a11, + -T.offset.Y()/T.a22, + 1.0/T.a11, + 1.0/T.a22); + } + // + /// Get the inverse of a general transform. + // + transform transform::getInverseGeneral(const transform & T ) + { + // + // compute the determinant + // + double det = T.a11*T.a22 - T.a12*T.a21; + + return transform( (T.offset.Y()*T.a21 - T.offset.X()*T.a22)/det, + (T.offset.X()*T.a12 - T.offset.Y()*T.a11)/det, + T.a22/det, + -T.a12/det, + -T.a21/det, + T.a11/det); + } + // + /// Get the inverse of a standard transform. + // + transform transform::getInverseStd(const transform & T) + { + // + // Transform the offset. + // + pod::point off = - T.offset * stdOrient(inverseStdOrient[T.orient.getOri()]); + // + // Return the inverted standard transform. + // + return transform (off.X(), off.Y(), + inverseStdOrient[T.orient.getOri()]); + } + // + /// Get the inverse of a standard transform with mag. + // + transform transform::getInverseStdWithMag(const transform & T) + { + register double oneOverMag = 1.0/T.a11; + register stdOrientEnum e = inverseStdOrient[T.orient.getOri()]; + // + // Transform the offset. + // + pod::point off = - (T.offset * stdOrient(e)) * oneOverMag; + + return transform( off.X(), + off.Y(), + e, + oneOverMag ); + } + // + /// Get the inverse of a scale transform. + // + transform transform::getInverseScale(const transform & T) + { + return transform( 0.0, + 0.0, + 1.0/T.a11, + 1.0/T.a22); + } + // + // Get the inverse of a resolution transform. + // + transform transform::getInverseResolution(const transform & T) + { + if (T.next) { + transform T1(T.a11, T.a22, false); + transform T2; + T1.mult(*(T.next), T2); + return T2.getInverse(); + } else { + return transform(1.0/T.a11, 1.0/T.a22, false); + } + } +#endif + +#if 0 + // + /// Multiply two scale transforms. + // + void transform::multScaleXScale(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point(0.0, 0.0); + } + // + /// Multiply a scale transform with a resolution transform. + // + void transform::multScaleXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp(T1.a11, T1.a22, false); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(0.0); + outT.next->offset.setY(0.0); + } else { + outT.next = new transform(T1.a11, T1.a22, false); + } + } + } + // + // + /// Multiply two scale offset transforms. + // + void transform::multScaleOffsetXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ScaleOffsetTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( + T2.a11*T1.offset.X() + T2.offset.X(), + T2.a22*T1.offset.Y() + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a general transform. + // + void transform::multScaleOffsetXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a11*T2.a12; + outT.a21 = T1.a22*T2.a21; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21 + T2.offset.X(), + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22 + T2.offset.Y()); + } + // + /// Multiply a scale offset transform with a standard transform. + // + void transform::multScaleOffsetXStd( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0], + T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]) + + T2.offset; + } + // + /// Multiply a scale offset transform with a standard transform + /// with magnification. + // + void transform::multScaleOffsetXStdWithMag( const transform &T1, + const transform &T2, + transform &outT) + { + // + // If we have uniform magnification, then we do not have to go to + // a general transform. + // + if ( T1.a11 == T1.a22 ) + { + outT.type = StdTransformWithMagType; + outT.orient = T2.orient; + outT.a11 = T1.a11*T2.a11; + } + else + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0]; + outT.a12 = T1.a11*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1]; + outT.a21 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a22*T2.a11*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + } + outT.offset = pod::point( + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]), + T2.a11*(T1.offset.X()*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.offset.Y()*stdOrientCoeffMatrix[T2.orient.getOri()][1][1])) + + T2.offset; + } + // + /// Multiply a scale offset transform with a resolution transform. + // + void transform::multScaleOffsetXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = ScaleOffsetTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = 0.0; + outT.next->a21 = 0.0; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a22); + } + } + } + // + /// Multiply a general transform with a scale offset transform. + // + void transform::multGeneralXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11; + outT.a12 = T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11; + outT.a22 = T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two general transforms. + // + void transform::multGeneralXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*T2.a11 + T1.a12*T2.a21; + outT.a12 = T1.a11*T2.a12 + T1.a12*T2.a22; + outT.a21 = T1.a21*T2.a11 + T1.a22*T2.a21; + outT.a22 = T1.a21*T2.a12 + T1.a22*T2.a22; + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a general transform with a standard transform. + // + void transform::multGeneralXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + outT.a21 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]; + outT.a22 = T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a general transform with a standard transform + /// with magnification. + // + void transform::multGeneralXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a12 = T2.a11*(T1.a11*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a12*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + outT.a21 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][0] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][0]); + outT.a22 = T2.a11*(T1.a21*stdOrientCoeffMatrix[T2.orient.getOri()][0][1] + + T1.a22*stdOrientCoeffMatrix[T2.orient.getOri()][1][1]); + // + // Transform the offset. + // + outT.offset = (T1.offset * T2.orient) * T2.a11 + T2.offset; + } + // + /// Multiply a general transform with a resolution transform. + // + void transform::multGeneralXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = GeneralTransformType; + outT.next->a11 = T1.a11; + outT.next->a22 = T1.a22; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.a11, T1.a12, T1.a21, T1.a22); + } + } + } + // + /// Multiply a standard transform with a scale and offset transform. + // + void transform::multStdXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with a general transform. + // + void transform::multStdXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21; + outT.a12 = stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21; + outT.a22 = stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply two standard transforms. + // + void transform::multStdXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformType; + outT.orient = multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply a standard transform with a standard transform + /// with magnification. + // + void transform::multStdXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with a resolution transform. + // + void transform::multStdXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) + { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + tmp.mult(*(T2.next), *(outT.next)); + } + else if (outT.next) + { + outT.next->type = StdTransformType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } + else + { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri()); + } + } + // + /// Multiply a standard transform with magnification with a + /// scale and offset transform. + // + void transform::multStdWithMagXScaleOffset(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11; + outT.a12 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22; + outT.a21 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11; + outT.a22 = T1.a11*stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22; + // + // Transform the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11, + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a general transform. + // + void transform::multStdWithMagXGeneral(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = GeneralTransformType; + outT.a11 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a21); + outT.a12 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][0][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][0][1]*T2.a22); + outT.a21 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a11 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a21); + outT.a22 = T1.a11*( stdOrientCoeffMatrix[T1.orient.getOri()][1][0]*T2.a12 + + stdOrientCoeffMatrix[T1.orient.getOri()][1][1]*T2.a22); + // + // Transfomr the offset. + // + outT.offset = pod::point( T1.offset.X()*T2.a11 + T1.offset.Y()*T2.a21, + T1.offset.X()*T2.a12 + T1.offset.Y()*T2.a22) + + T2.offset; + } + // + /// Multiply a standard transform with magnification with + /// a standard transform. + // + void transform::multStdWithMagXStd(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient + T2.offset; + } + // + /// Multiply two standard transforms with magnification. + // + void transform::multStdWithMagXStdWithMag(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = StdTransformWithMagType; + outT.orient = stdOrient(multStdOrientMatrix[T1.orient.getOri()][T2.orient.getOri()]); + outT.a11 = T1.a11*T2.a11; + // + // Transform the offset. + // + outT.offset = T1.offset * T2.orient * T2.a11 + T2.offset; + } + // + /// Multiply a standard transform with magnification with a + /// resolution transform. + // + void transform::multStdWithMagXResolution(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T2.a11; + outT.a12 = T2.a12; + outT.a21 = T2.a21; + outT.a22 = T2.a22; + + if (T2.next) { + if (!outT.next) + outT.next = new transform; + transform tmp( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + tmp.mult(*(T2.next), *(outT.next)); + } else { + if (outT.next) { + outT.next->type = StdTransformWithMagType; + outT.next->a11 = T1.a11; + outT.next->a12 = T1.a12; + outT.next->a21 = T1.a21; + outT.next->a22 = T1.a22; + outT.next->offset.setX(T1.offset.getX()*T2.a11); + outT.next->offset.setY(T1.offset.getY()*T2.a22); + outT.next->orient = T1.orient; + } else { + outT.next = new transform( + T1.offset.getX()*T2.a11, + T1.offset.getY()*T2.a22, + T1.orient.getOri(), T1.a11); + } + } + } + // + /// Multiply a resolution transform with any transform. + // + void transform::multResolutionXAny(const transform &T1, + const transform &T2, transform &outT) + { + outT.type = ResolutionTransformType; + outT.a11 = T1.a11; + outT.a12 = T1.a12; + outT.a21 = T1.a21; + outT.a22 = T1.a22; + + if(T1.next) { + if (!(outT.next)) + outT.next = new transform; + T1.next->mult(T2, *(outT.next)); + } else { + outT.next = new transform(T2); + } + } + +#endif + +// +/// Print a transform, mainly for debug purpose. +// +void transform::print(FILE *outStream, const char *linePrefix) const +{ + fprintf(outStream, "%sa11 = %f.\n", linePrefix, a11() ); + fprintf(outStream, "%sa12 = %f.\n", linePrefix, a12() ); + fprintf(outStream, "%sa21 = %f.\n", linePrefix, a21() ); + fprintf(outStream, "%sa22 = %f.\n", linePrefix, a22() ); + + fprintf(outStream, "%stx = %f.\n", linePrefix, offset_x() ); + fprintf(outStream, "%sty = %f.\n", linePrefix, offset_y() ); +} + +std::ostream & operator << (std::ostream & os, const transform & t) +{ + os << "" << std::endl; + os << "" << std::endl; + os << t.getRow1(); + os << t.getRow2(); + os << "" << std::endl; + os << "" << std::endl; + os << t.getOffset(); + os << "" << std::endl; + os << "" << std::endl; + return os; +} + +}; // namespace base diff --git a/testTransform/transform2.h b/testTransform/transform2.h new file mode 100644 index 0000000..91cf06a --- /dev/null +++ b/testTransform/transform2.h @@ -0,0 +1,912 @@ +/* + * SYNOPSYS CONFIDENTIAL - This is an unpublished, proprietary work of Synopsys, + * Inc., and is fully protected under copyright and trade secret laws. You may + * not view, use, disclose, copy, or distribute this file or any information + * contained herein except pursuant to a valid written license from Synopsys. + */ + +#ifndef TRANSFORM2_H_ +#define TRANSFORM2_H_ + +// _MSC_VER >= 1400 means we deal with VC8 or higher. +#if defined( _MSC_VER ) +/*warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)*/ +#pragma warning( disable: 4290 ) +#endif + +#include +#include +#include + +#include "base/port.h" +#include "base/constants.h" +#include "base/except.h" +#include "base/rectangle.h" +#include "base/round.h" + + +// +/// The transform.h file contains the different transform types. +// +/*! + * Usage of transforms: + * Transforms are applied to row vectors from the right as shown below: + * OV = IV * T + * Here, OV and IV are the output and input row vectors and T is the transform. + * + * Multiplying transforms: + * Suppose we have a chain of transforms. + * OV = IV * T1 * T2 + * OV = IV * T + * Thus, T can be computed as follows: + * Transform T; + * T1.mult(T2, T); + * + * A general 2-D transform can be viewed in matrix form as follows: + * |a11 a12 0| + * |a21 a22 0| + * | tx ty 1| + * A general transform can be viewed as a sequence of 3 steps: + * 1- Scaling with value (Sx, Sy) (i.e. x' = Sx*x, y' = Sy*y). + * 2- rotating with angle A. + * 3- translating with value (tx, ty). + * In other words, the 2-D transform is the multiplication of the 3 transforms + * as follows: + * |Sx 0 0| | cos(A) sin(A) 0| | 1 0 0| + * |0 Sy 0|*|-sin(A) cos(A) 0|*| 0 1 0| + * |0 0 1| | 0 0 1| |tx ty 1| + * + * Using resolution transforms: + * In order to mimic applying resolution transforms to each cell individually, + * a resolution change operation is applied before anything. Suppose we call + * the resolution change transform RES. Also suppose the transform from the + * cell to the screen is TS. Thus: + * OV = IV * RES * TS. + * In order to change the resolution of a layout, we need to insert the + * resolution transform RES in the chain. Hence: + * 1- Create a resolution transform RES(xScale, yScale, true). + * 2- Assuming T is the total transform, T can be computed as follows: + * RES.mult(TS, T). + */ +namespace base2 +{ +using namespace base; + +// +/// The main transformation class. +// +class GXX_VISIBLE transform +{ +// Data +protected: + // + /// 2X2 coefficient submatrix. + // + v2pd a11_a22; + v2pd a21_a12; + // + // Offset for the transform. + // + v2pd voffset; + +// Typedefs +protected: + + inline double& a11() + { + return *(reinterpret_cast(&a11_a22)); + } + inline double& a21() + { + return *(reinterpret_cast(&a21_a12)); + } + inline double& a12() + { + return *(reinterpret_cast(&a21_a12)+1); + } + inline double& a22() + { + return *(reinterpret_cast(&a11_a22)+1); + } + inline double& offset_x() + { + return *(reinterpret_cast(&voffset)); + } + inline double& offset_y() + { + return *(reinterpret_cast(&voffset)+1); + } + + inline double a11() const + { + return *(reinterpret_cast(&a11_a22)); + } + inline double a21() const + { + return *(reinterpret_cast(&a21_a12)); + } + inline double a12() const + { + return *(reinterpret_cast(&a21_a12)+1); + } + inline double a22() const + { + return *(reinterpret_cast(&a11_a22)+1); + } + inline double offset_x() const + { + return *(reinterpret_cast(&voffset)); + } + inline double offset_y() const + { + return *(reinterpret_cast(&voffset)+1); + } + +// Construction +public: + + // + /// Initialize the function tables. + // + static void initFnTables(); + + // + /// Default constuctor. + // + transform() + { + a11() = 1.0; + a22() = 1.0; + a21() = 0.0; + a12() = 0.0; + offset_x() = 0.0; + offset_y() = 0.0; + } + // + /// Default constuctor. + // + transform( v2pd a1122, + v2pd a2112, + v2pd o ) + { + a11_a22 = a1122; + a21_a12 = a2112; + voffset = o; + } + // + /// Constructor for a scale offset transform. + // + transform( + double offsetX, + double offsetY, + double scaleX, + double scaleY + ) + { + a11() = scaleX; + a22() = scaleY; + a21() = 0.0; + a12() = 0.0; + offset_x() = offsetX; + offset_y() = offsetY; + } + // + /// Constructor for a general transform. + // + transform( + double offsetX, + double offsetY, + double coeff11, + double coeff12, + double coeff21, + double coeff22 + ) + { + a11() = coeff11; + a22() = coeff22; + a21() = coeff21; + a12() = coeff12; + offset_x() = offsetX; + offset_y() = offsetY; + } + // + /// Constructor for a rotate transform. + /// @param inCx X coordinate of the center of rotation. + /// @param inCy Y coordinate of the center of rotation. + /// @param angle rotation angle in degrees. + // + transform( + double inCx, + double inCy, + double angle + ) + { + a11() = cos(degreesToRadians(angle)); + a22() = a11(); + a12() = sin(degreesToRadians(angle)); + a21() = -a12(); + offset_x() = inCy * a12() - inCx * a11() + inCx; + offset_y() = - inCy * a11() - inCx * a12() + inCy; + } +#if 0 + // + /// Constructor for a standard transform. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient = R0 + ) + : + a11(1.0), + a12(0.0), + a21(0.0), + a22(1.0), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformType) + {} + // + /// Constructor for a standard transform with magnification. + // + transform( + double offsetX, + double offsetY, + stdOrientEnum inOrient, + double inMag) + : + a11(inMag), + a12(0.0), + a21(0.0), + a22(inMag), + offset(offsetX,offsetY), + next(NULL), + orient(inOrient), + type(StdTransformWithMagType) + {} +#endif + // + /// Advanced constructor for typical references. + /// @param offsetX X value of translation offset. + /// @param offsetY Y value of translation offset. + /// @param inXFlip boolean reflecting the presence of an X flip. + /// @param inAngle rotation angle in degrees. + /// @param inMag magnification. + // + transform( + double offsetX, + double offsetY, + bool inXFlip, + double inAngle, + double inMag) + { + register double multiplier = ( inXFlip ) ? -1.0 : 1.0; + register double newAngle = degreesToRadians(normalizeAngle(inAngle)); + register double cosine = cos(newAngle); + register double sine = sin(newAngle); + + a11() = inMag * cosine; + a12() = inMag * sine; + a21() = -inMag * multiplier * sine; + a22() = inMag * multiplier * cosine; + offset_x() = offsetX; + offset_y() = offsetY; + } + // + /// Scale or resolution transform. + /// @param xScale X value of the scale factor. + /// @param yScale Y value of the scale factor. + /// @param rouding A true value means it is a resolution transform. + /// A false value will result in a standard scale transform. + // + transform( + double xScale, + double yScale, + bool rounding ) + { + a11() = xScale; + a22() = yScale; + a21() = 0.; + a12() = 0.; + offset_x() = 0.; + offset_y() = 0.; + } + + // + /// Copy constructor + // + transform( const transform & inT) + { + a11_a22 = inT.a11_a22; + a21_a12 = inT.a21_a12; + voffset = inT.voffset; + } + // + /// Assignment operator + // + transform & operator = (const transform &inT) + { + a11_a22 = inT.a11_a22; + a21_a12 = inT.a21_a12; + voffset = inT.voffset; + return *this; + } + + // + /// Destructor + // + ~transform() + { + } + +public: + // + /// Equal operator + // + bool operator == (const transform &inT) + { +// register v2pd cmp = _mm_cmpeq_pd( vx, inT.vx ); +// register v2pd tmp = _mm_cmpeq_pd( vy, inT.vy ); +// cmp = _mm_and_pd( cmp, tmp ); +// tmp = _mm_cmpeq_pd( voffset, inT.voffset ); +// cmp = _mm_and_pd( cmp, tmp ); + + return false; + } + + // + /// Non equal operator + // + bool operator != (const transform &inT) + { +// register v2pd cmp = _mm_cmpneq_pd( vx, inT.vx ); +// register v2pd tmp = _mm_cmpneq_pd( vy, inT.vy ); +// cmp = _mm_or_pd( cmp, tmp ); +// tmp = _mm_cmpneq_pd( voffset, inT.voffset ); +// cmp = _mm_or_pd( cmp, tmp ); + + return true; + } + +#if 0 + // + /// Test whether this is an identity transform. + // + bool isIdentityTransform() const + throw (except::outOfRange) + { + const double onePlusTolerance = 1.0 + relTolerance; + const double oneMinusTolerance = 1.0 - relTolerance; + // + // See if the offsets are beyond the origin. + // + if (offset.X() > absTolerance || offset.X() < -absTolerance || + offset.Y() > absTolerance || offset.Y() < -absTolerance) + return false; + // + // Check by transform type. + // + switch((transformType) type) + { + case StdTransformWithMagType: + if (a11 > onePlusTolerance || a11 < oneMinusTolerance) + return false; + + case StdTransformType: + if (orient.getOri() != R0) + return false; + break; + + case GeneralTransformType: + if ( a12 > absTolerance || + a12 < -absTolerance || + a21 > absTolerance || + a21 < -absTolerance) + return false; + + case ScaleOffsetTransformType: + case ScaleTransformType: + if ( a11 > onePlusTolerance || + a11 < oneMinusTolerance || + a22 > onePlusTolerance || + a22 < oneMinusTolerance) + return false; + break; + + case ResolutionTransformType: + return false; + break; + + default: + throw except::outOfRange("base::transform:isIdentityTransform: Unknown type."); + } + return true; + } + + // + /// Returns the type of the transform. + // + transformType getType() const + { + return (transformType) type; + } + + stdOrient getOrient() const + { + return orient; + } + + // + /// Return the next field. + // + const transform *getNext() const + { + return next; + } + // + /// Return the next field. + // + transform *getNext() + { + return next; + } +#endif + + // + /// Returns the offset point of the transform. + // + pod::point getOffset() const + { + return pod::point( offset_x(), offset_y() ); + } + // + /// Returns the offset point of the transform taking into account also resolution. + // + pod::point getOffsetRes() const + { + return pod::point( offset_x(), offset_y() ); + } + // + /// Set the offset of the transform. + // + void setOffset( pod::point off ) + { + voffset = off.get_pd(); + } + pod::point getDiagonal() const + { + return pod::point(a11(),a22()); + } + pod::point getRow1() const + { + return pod::point(a11(),a12()); + } + pod::point getRow2() const + { + return pod::point(a21(),a22()); + } + pod::point getCol1() const + { + return pod::point(a11(),a21()); + } + pod::point getCol2() const + { + return pod::point(a12(),a22()); + } + // + /// Return the magnitude of the vector (1,0). + // + double getXVectorMag() const + { + if ( a21() == 0.0 ) + return ::fabs(a11()); + else if ( a11() == 0.0 ) + return ::fabs(a21()); + else + return ::sqrt(a11()*a11() + a21()*a21()); + } + // + /// A special function to return the X scale factor. This + /// is a nonnegative value that reflects the scaling effect + /// in the X direction. + // + double getXScale() const + { + return getXVectorMag(); + } + // + /// Returns the a11 entry of the matrix. If the matrix is a scaling + /// one, then this returns the X-scale factor. + /// The result is not correct for all types of transforms. + // + double get11() const + { + return a11(); + } + // + /// Return the a12 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get12() const + { + return a12(); + } + // + /// Return the a21 entry of the matrix. + /// The result is only valid for general transforms. + /// The result is not correct for all types of transforms. + // + double get21() const + { + return a21(); + } + // + /// Returns the a22 entry of the matrix. If the matrix is a scaling + /// one, then this returns the Y-scale factor. + /// The result is not correct for all types of transforms. + // + double get22() const + { + return a22(); + } + + // + /// get angle, isXFlip and mag from transformation + // + const void getAngleFlipMag( double& angle, bool& isXFlip, double& mag) const; + +// Complex functions. +public: + + + //////////////////////////////////////////////////////////////// + + // + /// Modify a single point. + // + template + pod::point modifyDblToShort(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyDblToInt(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyDblToDbl(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyIntToShort(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyIntToInt(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyLongToShort(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyLongToInt(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::point modifyLongToLong(pod::point p) const + { + pod::rectangle tmp; + modify( r, tmp ); + return tmp; + } + + template + pod::rectangle operator()(const pod::rectangle & r) const + { + return modify( r ); + } + + template + pod::point operator()(const pod::point & p) const + { + return modify( p ); + } + + transform operator *(const transform & t2 ) const + { + return mult( t2 ); + } + + /////////////////////////////////////////////////////////////////////////// + + // + /// Multiply with another transform. + // + void mult(const transform &T2, transform &outT) const + { + // + // new_a11 = t1_a11*t2_a11 + t1_a12*t2_a21 + // new_a22 = t1_a22*t2_a22 + t1_a21*t2_a12 + // + v2pd m1 = _mm_mul_pd( a11_a22, T2.a11_a22 ); + v2pd m2 = a21_a12; + m2 = _mm_shuffle_pd( m2, m2, 1 ); + m2 = _mm_mul_pd( m2, T2.a21_a12 ); + outT.a11_a22 = _mm_add_pd( m1, m2 ); + // + // new_a21 = t1_a21*t2_a11 + t1_a22*t2_a21 + // new_a12 = t1_a12*t2_a22 + t1_a11*t2_a12 + // + v2pd m3 = _mm_mul_pd( a21_a12, T2.a11_a22 ); + v2pd m4 = a11_a22; + m4 = _mm_shuffle_pd( m4, m4, 1 ); + m4 = _mm_mul_pd( m4, T2.a21_a12 ); + outT.a21_a12 = _mm_add_pd( m3, m4 ); + // + // new_xoffset = t1_xoffset*t2_a11 + t1_yoffset*t2_a21+t2_xoffset + // new_yoffset = t1_yoffset*t2_a22 + t1_xoffset*t2_a12+t2_yoffset + // + v2pd m5 = _mm_mul_pd( voffset, T2.a11_a22 ); + v2pd m6 = voffset; + m6 = _mm_shuffle_pd( m6, m6, 1 ); + m6 = _mm_mul_pd( voffset, T2.a21_a12 ); + + m5 = _mm_add_pd( m5, m6 ); + outT.voffset = _mm_add_pd( m5, T2.voffset ); + } + + // + /// Multiply with another transform. + // + transform mult(const transform &T2) const + { + // + // new_a11 = t1_a11*t2_a11 + t1_a12*t2_a21 + // new_a22 = t1_a22*t2_a22 + t1_a21*t2_a12 + // + v2pd m1 = _mm_mul_pd( a11_a22, T2.a11_a22 ); + v2pd m2 = a21_a12; + m2 = _mm_shuffle_pd( m2, m2, 1 ); + m2 = _mm_mul_pd( m2, T2.a21_a12 ); + v2pd t_a11_a22 = _mm_add_pd( m1, m2 ); + // + // new_a21 = t1_a21*t2_a11 + t1_a22*t2_a21 + // new_a12 = t1_a12*t2_a22 + t1_a11*t2_a12 + // + v2pd m3 = _mm_mul_pd( a21_a12, T2.a11_a22 ); + v2pd m4 = a11_a22; + m4 = _mm_shuffle_pd( m4, m4, 1 ); + m4 = _mm_mul_pd( m4, T2.a21_a12 ); + v2pd t_a21_a12 = _mm_add_pd( m3, m4 ); + // + // new_xoffset = t1_xoffset*t2_a11 + t1_yoffset*t2_a21+t2_xoffset + // new_yoffset = t1_yoffset*t2_a22 + t1_xoffset*t2_a12+t2_yoffset + // + v2pd m5 = _mm_mul_pd( voffset, T2.a11_a22 ); + v2pd m6 = voffset; + m6 = _mm_shuffle_pd( m6, m6, 1 ); + m6 = _mm_mul_pd( voffset, T2.a21_a12 ); + + m5 = _mm_add_pd( m5, m6 ); + v2pd t_voffset = _mm_add_pd( m5, T2.voffset ); + // + // Return the result + // + return transform( t_a11_a22, t_a21_a12, t_voffset ); + } + + // + /// Scale the transform by the given scalar. + // + transform & operator *= (const double d) + { + v2pd m = _mm_set1_pd( d ); + a11_a22 = _mm_mul_pd( a11_a22, m ); + a21_a12 = _mm_mul_pd( a21_a12, m ); + voffset = _mm_mul_pd( voffset, m ); + return *this; + } + + // + /// Return the inverse transform of the transform. + // + transform getInverse() const + { + // + // Get determinant. + // + double det = a11()*a22()-a21()*a12(); + v2pd detx2 = _mm_set1_pd( det ); + // + // Get inv_a11 and inv_a22 + // + // inv_a11 = a22/det + // inv_a11 = a11/det + // + v2pd t_a11_a22 = a11_a22; + t_a11_a22 = _mm_shuffle_pd( t_a11_a22, t_a11_a22, 1 ); + t_a11_a22 = _mm_div_pd( t_a11_a22, detx2 ); + // + // inv_a21 = -a21/det + // inv_a12 = -a12/det + // + v2pd t_a21_a12 = _mm_set1_pd( 0.0 ); + t_a21_a12 = _mm_sub_pd( t_a21_a12, a21_a12 ); + t_a21_a12 = _mm_div_pd( t_a21_a12, detx2 ); + // + // inv_xoffset = -xoffset*inv_a11 -yoffset*inv_a21 + // inv_yoffset = -yoffset*inv_a22 -xoffset*inv_a12 + // + v2pd t_voffset = _mm_set1_pd( 0.0 ); + t_voffset = _mm_sub_pd( t_voffset, voffset ); + t_voffset = _mm_mul_pd( t_voffset, t_a11_a22 ); + + v2pd r_voffset = voffset; + r_voffset = _mm_shuffle_pd( r_voffset, r_voffset, 1 ); + r_voffset = _mm_mul_pd( r_voffset, t_a21_a12 ); + t_voffset = _mm_sub_pd( t_voffset, r_voffset ); + // + // Return the result. + // + return transform( t_a11_a22, t_a21_a12, t_voffset ); + } + + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + __forceinline void modify( const pod::point& rSrc, pod::point& rDest ) const + { +// rDest = modify( rSrc ); + // + // x = x*a11 + y*a21 + // y = y*a22 + x*a12 + // + v2pd d = rSrc.get_pd(); + v2pd d_rev = d; + d_rev = _mm_shuffle_pd( d_rev, d, 1 ); + d = _mm_mul_pd( d, a11_a22 ); + d_rev = _mm_mul_pd( d_rev, a21_a12 ); + d = _mm_add_pd( d, voffset ); + d = _mm_add_pd( d, d_rev ); + rDest.set_pd( d ); + } + + // + /// This is a convinient function converting coordinate types without loss of precision. + // + /*! + We try to not loss precision and use available functionality + provided by transform maximally. This function does what + all modifyXxxxToYyyyy does and is very helpful in generic programming. + */ + template + __forceinline pod::point modify( const pod::point& rSrc ) const + { + // + // x = x*a11 + y*a21 + // y = y*a22 + x*a12 + // + v2pd d = rSrc.get_pd(); + v2pd d_rev = d; + d_rev = _mm_shuffle_pd( d_rev, d, 1 ); + d = _mm_mul_pd( d, a11_a22 ); + d_rev = _mm_mul_pd( d_rev, a21_a12 ); + d = _mm_add_pd( d, voffset ); + d = _mm_add_pd( d, d_rev ); + return pod::point( d ); + } + + // + /// This is pod::rectangle version of above function. + // + template + __forceinline void modify( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + modifyBBox( rSrc, rDest ); + } + + // + /// This is pod::rectangle version of above function. + // + template + __forceinline pod::rectangle modify( const pod::rectangle& rSrc ) const + { + pod::rectangle dest; + modifyBBox( rSrc, dest ); + return dest; + } + + // + /// Transform given bbox. + // + /*! + While we transform bbox, the usual approach of transforming + lower left and upper right is not satisfactory. In case of + rotations we need to transform and merge all four vertices + of bbox to get one of bbox rectangles of a shape which bbox we + want to transform. The bbox transformed this way will not be the + smallest bbox of the shape, yet at least this will be a bbox. + While if we use usual approach, then we will get (in case of rotation) + a rectangle that is not nessecarily a bbox of original shape. + + The function also optimizes cases when transform has + only orthogonal transforms. + */ + template + __forceinline void modifyBBox( const pod::rectangle& rSrc, pod::rectangle& rDest ) const + { + pod::point b1 = modify( rSrc.getLowerLeftRef() ); + pod::point b2 = modify( rSrc.getUpperRightRef() ); + + rDest.setRect( b1, b2 ); + rDest.makeValid(); + + // + // If we have orthogonal transform? + // First check get12 since most of transform will + // have no rotation factor. + // +// v2pd a1112 = _mm_shuffle_pd( a11_a22, a21_a12, 1 ) +// v2pd a1112 = _mm_shuffle_pd( a11_a22, a21_a12, 1 ) + if ( a12() != 0. && a11() != 0. ) + { + pod::point b3 = modify( rSrc.getUpperLeft() ); + rDest.merge( b3 ); + + pod::point b4 = modify( rSrc.getLowerRight() ); + rDest.merge( b4 ); + } + } + + // + /// Convert a transform type to a string. + // + friend std::ostream & operator << (std::ostream & os, const transform & t); + + // + /// Print a transform, mainly for debug purpose. + // + void print(FILE *outStream, const char *linePrefix) const; + +}; // class transform + +} // namespace base + +#endif // TRANSFORM_H_ diff --git a/testVC_ENV_CL/stdafx.cpp b/testVC_ENV_CL/stdafx.cpp new file mode 100644 index 0000000..fbf5d52 --- /dev/null +++ b/testVC_ENV_CL/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// testVC_ENV_CL.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/testVC_ENV_CL/stdafx.h b/testVC_ENV_CL/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/testVC_ENV_CL/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/testVC_ENV_CL/testVC_ENV_CL.cpp b/testVC_ENV_CL/testVC_ENV_CL.cpp new file mode 100644 index 0000000..8ea7b4c --- /dev/null +++ b/testVC_ENV_CL/testVC_ENV_CL.cpp @@ -0,0 +1,16 @@ +// testVC_ENV_CL.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ +#ifdef VAHAGN + puts("VAHAGN_EXPERIMENT"); +#else + puts("kkkkkk"); +#endif + return 0; +} + diff --git a/testVC_ENV_CL/testVC_ENV_CL.sln b/testVC_ENV_CL/testVC_ENV_CL.sln new file mode 100644 index 0000000..48d83a4 --- /dev/null +++ b/testVC_ENV_CL/testVC_ENV_CL.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testVC_ENV_CL", "testVC_ENV_CL.vcproj", "{EED5AD2E-DCE1-4477-9207-AD8DBC348588}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EED5AD2E-DCE1-4477-9207-AD8DBC348588}.Debug|Win32.ActiveCfg = Debug|Win32 + {EED5AD2E-DCE1-4477-9207-AD8DBC348588}.Debug|Win32.Build.0 = Debug|Win32 + {EED5AD2E-DCE1-4477-9207-AD8DBC348588}.Release|Win32.ActiveCfg = Release|Win32 + {EED5AD2E-DCE1-4477-9207-AD8DBC348588}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/testVC_ENV_CL/testVC_ENV_CL.vcproj b/testVC_ENV_CL/testVC_ENV_CL.vcproj new file mode 100644 index 0000000..b2cc349 --- /dev/null +++ b/testVC_ENV_CL/testVC_ENV_CL.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testX11.cpp b/testX11.cpp new file mode 100644 index 0000000..60fb595 --- /dev/null +++ b/testX11.cpp @@ -0,0 +1,215 @@ +/* first include the standard headers that we're likely to need */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class threadDrawing +{ +public: + Display* d; + Drawable w; + Pixmap p; + GC gc; + pthread_t t; + + threadDrawing() + : + d( 0 ), + w( 0 ), + p( 0 ), + gc( 0 ) + { + } + + ~threadDrawing() + { + deinit(); + } + + void init( const char * dname ) + { + d = XOpenDisplay( dname ); + + int screen_num = XDefaultScreen(d); + unsigned long bg = XBlackPixel(d, screen_num); + unsigned long fg = XWhitePixel(d, screen_num); + w = XCreateSimpleWindow(d, XDefaultRootWindow(d), + 0, 0, 1, 1, + 0, fg, bg ); + + p = XCreatePixmap( d, w, 50, 50, + XDefaultDepth( d, XDefaultScreen( d ) ) ); + gc = XCreateGC( d, w, 0, 0 ); + XSetForeground( d, gc, fg ); + XSetBackground( d, gc, bg ); + } + + void deinit() + { + if ( gc ) + { + XFreeGC( d, gc ); + gc = 0; + } + if ( p ) + { + XFreePixmap( d, p ); + p = 0; + } + if ( w ) + { + XDestroyWindow( d, w ); + w = 0; + } + if ( d ) + { + XCloseDisplay( d ); + d = 0; + } + } + + static void* entry_point( void * pData) + { + threadDrawing* pThis = reinterpret_cast(pData); + pThis->run(); + return 0; + } + + void start() + { + int rc = pthread_create( &t, 0, &entry_point, (void*)this ); + std::cout << "Thread " << t << " created." << std::endl ; + } + + void join() + { + void * s; + pthread_join( t, &s ); + std::cout << "Thread " << t << " joined." << std::endl ; + } + + void run() + { +// p = XCreatePixmap( d, w, 50, 50, +// XDefaultDepth( d, XDefaultScreen( d ) ) ); +// GC gc = XCreateGC( d, w, 0, 0 ); + XFillRectangle( d, p, gc, 0, 0, 50, 50 ); + for (; true ; ) + { + XDrawLine( d, p, gc, 0, 0, 50, 50 ); + XDrawLine( d, p, gc, 0, 50, 50, 0 ); + } + XFlush( d ); + XSync( d, True ); + } +}; + + +void createThreads( Display* d, Drawable w ) +{ + const int tsize = 16; + typedef std::vector threads_type; + threads_type threads( tsize ); + + const char * dname = XDisplayString( d ); + + threads_type::iterator it = threads.begin(); + threads_type::iterator itEnd = threads.end(); + for ( ; it != itEnd; ++it ) + { + it->init( dname ); + it->start(); + } + + for ( it = threads.begin(); it != itEnd; ++it ) + { + it->join(); + } +} + +int error_handler( Display* d, XErrorEvent* err ) +{ + puts( "error." ); +} + +int io_error_handler( Display* d ) +{ + puts( "io error." ); +} + +int main(int argc, char ** argv) +{ + int screen_num, width, height; + unsigned long background, border; + Window win; + XEvent ev; + Display *dpy; + + XSetErrorHandler( error_handler ); + XSetIOErrorHandler( io_error_handler ); + + /* First connect to the display server, as specified in the DISPLAY + environment variable. */ + dpy = XOpenDisplay(NULL); + if (!dpy) + { + fprintf(stderr, "unable to connect to display"); + return 7; + } + + /* these are macros that pull useful data out of the display object */ + /* we use these bits of info enough to want them in their own variables */ + screen_num = DefaultScreen(dpy); + background = BlackPixel(dpy, screen_num); + border = WhitePixel(dpy, screen_num); + + width = 400; /* start with a small window */ + height = 400; + + win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */ + 0,0, /* x, y: the window manager will place the window elsewhere */ + width, height, /* width, height */ + 2, border, /* border width & colour, unless you have a window manager */ + background); /* background colour */ + + /* tell the display server what kind of events we would like to see */ + XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask ); + + /* okay, put the window on the screen, please */ + XMapWindow(dpy, win); + + // + // + // + createThreads( dpy, win ); + + /* as each event that we asked about occurs, we respond. In this + * case we note if the window's shape changed, and exit if a button + * is pressed inside the window */ + while(1) + { + XNextEvent(dpy, &ev); + switch(ev.type) + { + case ConfigureNotify: + if (width != ev.xconfigure.width + || height != ev.xconfigure.height) + { + width = ev.xconfigure.width; + height = ev.xconfigure.height; + printf("Size changed to: %d by %d\n", width, height); + } + break; + case ButtonPress: + XCloseDisplay(dpy); + return 0; + } + } +} + diff --git a/test_array_init.cpp b/test_array_init.cpp new file mode 100644 index 0000000..2806e04 --- /dev/null +++ b/test_array_init.cpp @@ -0,0 +1,26 @@ +#include + +class a +{ +public: + void* array[16]; + int a2[16]; + + a() + : array() + , a2() + { + } +}; + +int main( ) +{ + a o; + for ( int i = 0; i < 16; ++i ) + std::cout << o.array[i] << std::endl; + for ( int i = 0; i < 16; ++i ) + std::cout << o.a2[i] << std::endl; + return 1; + +} + diff --git a/test_autoname_obj.cpp b/test_autoname_obj.cpp new file mode 100644 index 0000000..ecaac8e --- /dev/null +++ b/test_autoname_obj.cpp @@ -0,0 +1,59 @@ + +#include +#include +#include + +#define FILELINE( l ) __FILE__ #l + +struct fileline +{ + virtual std::string msg() + { + return std::string(); + } +}; + +template +struct filelineT +{ + virtual std::string msg() + { + std::ostringstream ss; + ss << file << ':' << line; + return ss.str(); + } +}; + +std::string flfunc( const char * f = __FILE__, int l = __LINE__ ) +{ + std::ostringstream ss; + ss << f << ':' << l; + return ss.str(); +} + +#define FLFUNC flfunc( __FILE__, __LINE__ ) + +//#define filelineM {static const char * tmp = __FILE__; filelineT} + +//template < + +struct A +{ + std::string myName; + + + A( std::string n = FLFUNC ) + : myName( n ) + {} +}; + +int main () +{ + A a1( FLFUNC ); + A a2( FLFUNC ); + std::cout << a1.myName << std::endl; + std::cout << a2.myName << std::endl; + + return 0; +} + diff --git a/test_const_arg.cpp b/test_const_arg.cpp new file mode 100644 index 0000000..b99b424 --- /dev/null +++ b/test_const_arg.cpp @@ -0,0 +1,52 @@ + +#include + +void f ( int& i ) +{ + std::cout << "int" << std::endl; +} + +void f ( const int& i ) +{ + std::cout << "const int" << std::endl; +} + +#if 0 +void f ( volatile int& i ) +{ + std::cout << "volatile int" << std::endl; +} + +void f ( const volatile int& i ) +{ + std::cout << "const volatile int" << std::endl; +} +#endif + +int g ( ) +{ + int i = 2; + return i; +} + +int main( void ) +{ +#if 0 + const volatile int cvi = 1; + f( cvi ); + + volatile int vi = 1; + f( vi ); +#endif + + const int ci = 1; + f( ci ); + + int i = 1; + f( i ); + + f( g() ); + + return 0; +} + diff --git a/test_copy_elision.cpp b/test_copy_elision.cpp new file mode 100644 index 0000000..fd00b1d --- /dev/null +++ b/test_copy_elision.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +class copy_tracker +{ + int v; +public: + copy_tracker() + : v(0) + { + std::cout << "copy_tracker::copy_tracker()" << std::endl; + } + + copy_tracker( const copy_tracker& c ) + : v( c.v ) + { + std::cout << "copy_tracker::copy_tracker( copy_tracker& c )" << std::endl; + } + + void use_object() + { + std::cout << v << std::endl; + } +}; + +copy_tracker copy_tracker_return_by_value2() +{ + return copy_tracker(); +} + +copy_tracker copy_tracker_return_by_value() +{ + return copy_tracker_return_by_value2(); +} + +void copy_tracker_pass_by_value2(copy_tracker o) +{ + return o.use_object(); +} + +void copy_tracker_pass_by_value(copy_tracker o) +{ + return copy_tracker_pass_by_value2(o); +} + +void test_copy_tracker() +{ + std::cout << "Return by value and assign." << std::endl; + copy_tracker o = copy_tracker_return_by_value(); + std::cout << "Pass lvalue." << std::endl; + copy_tracker_pass_by_value( o ); + std::cout << "Pass rvalue." << std::endl; + const copy_tracker& o2 = copy_tracker_return_by_value(); + copy_tracker_pass_by_value2( o2 ); + std::cout << "Pass rvalue 2." << std::endl; + copy_tracker_pass_by_value2( copy_tracker_return_by_value() ); +} + +int main ( void ) +{try{ + + test_copy_tracker(); + return 0; +} +catch ( const std::exception& e ) +{ + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; +} +catch ( ... ) +{ + std::cerr << std::endl + << "unknown exception." << std::endl; +}} + diff --git a/test_expression.cpp b/test_expression.cpp new file mode 100644 index 0000000..b4a7281 --- /dev/null +++ b/test_expression.cpp @@ -0,0 +1,10 @@ +#include + +int main ( void ) +{ + int a = 1; + std::cout << a++ << " " << a++ << std::endl; + std::cout << ++a << " " << ++a << std::endl; + + return 0; +} diff --git a/test_lib/stdafx.cpp b/test_lib/stdafx.cpp new file mode 100644 index 0000000..6f587d3 --- /dev/null +++ b/test_lib/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test_lib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test_lib/stdafx.h b/test_lib/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/test_lib/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/test_lib/test_lib.cpp b/test_lib/test_lib.cpp new file mode 100644 index 0000000..d051d41 --- /dev/null +++ b/test_lib/test_lib.cpp @@ -0,0 +1,11 @@ +// test_lib.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + return 0; +} + diff --git a/test_lib/test_lib.sln b/test_lib/test_lib.sln new file mode 100644 index 0000000..8ee333a --- /dev/null +++ b/test_lib/test_lib.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib", "test_lib.vcproj", "{E313785C-8B92-4288-8EA9-E50D7DDA3F4C}" + ProjectSection(ProjectDependencies) = postProject + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4} = {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_static", "..\test_lib_static\test_lib_static.vcproj", "{FA488743-714C-4D14-9A9F-6BE3205B9E4F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_dyn", "..\test_lib_dyn\test_lib_dyn.vcproj", "{0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}" + ProjectSection(ProjectDependencies) = postProject + {FA488743-714C-4D14-9A9F-6BE3205B9E4F} = {FA488743-714C-4D14-9A9F-6BE3205B9E4F} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Debug|Win32.ActiveCfg = Debug|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Debug|Win32.Build.0 = Debug|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Release|Win32.ActiveCfg = Release|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Release|Win32.Build.0 = Release|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Debug|Win32.Build.0 = Debug|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Release|Win32.ActiveCfg = Release|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Release|Win32.Build.0 = Release|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Debug|Win32.ActiveCfg = Debug|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Debug|Win32.Build.0 = Debug|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Release|Win32.ActiveCfg = Release|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test_lib/test_lib.vcproj b/test_lib/test_lib.vcproj new file mode 100644 index 0000000..6520772 --- /dev/null +++ b/test_lib/test_lib.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_lib/test_lib/stdafx.cpp b/test_lib/test_lib/stdafx.cpp new file mode 100644 index 0000000..6f587d3 --- /dev/null +++ b/test_lib/test_lib/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test_lib.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test_lib/test_lib/stdafx.h b/test_lib/test_lib/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/test_lib/test_lib/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/test_lib/test_lib/test_lib.cpp b/test_lib/test_lib/test_lib.cpp new file mode 100644 index 0000000..d051d41 --- /dev/null +++ b/test_lib/test_lib/test_lib.cpp @@ -0,0 +1,11 @@ +// test_lib.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" + + +int _tmain(int argc, _TCHAR* argv[]) +{ + return 0; +} + diff --git a/test_lib/test_lib/test_lib.sln b/test_lib/test_lib/test_lib.sln new file mode 100644 index 0000000..8ee333a --- /dev/null +++ b/test_lib/test_lib/test_lib.sln @@ -0,0 +1,38 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib", "test_lib.vcproj", "{E313785C-8B92-4288-8EA9-E50D7DDA3F4C}" + ProjectSection(ProjectDependencies) = postProject + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4} = {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_static", "..\test_lib_static\test_lib_static.vcproj", "{FA488743-714C-4D14-9A9F-6BE3205B9E4F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_lib_dyn", "..\test_lib_dyn\test_lib_dyn.vcproj", "{0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}" + ProjectSection(ProjectDependencies) = postProject + {FA488743-714C-4D14-9A9F-6BE3205B9E4F} = {FA488743-714C-4D14-9A9F-6BE3205B9E4F} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Debug|Win32.ActiveCfg = Debug|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Debug|Win32.Build.0 = Debug|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Release|Win32.ActiveCfg = Release|Win32 + {E313785C-8B92-4288-8EA9-E50D7DDA3F4C}.Release|Win32.Build.0 = Release|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Debug|Win32.Build.0 = Debug|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Release|Win32.ActiveCfg = Release|Win32 + {FA488743-714C-4D14-9A9F-6BE3205B9E4F}.Release|Win32.Build.0 = Release|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Debug|Win32.ActiveCfg = Debug|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Debug|Win32.Build.0 = Debug|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Release|Win32.ActiveCfg = Release|Win32 + {0BCAEBC5-C3A9-4E7F-BBAE-7B48AEB42BD4}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test_lib/test_lib/test_lib.vcproj b/test_lib/test_lib/test_lib.vcproj new file mode 100644 index 0000000..6520772 --- /dev/null +++ b/test_lib/test_lib/test_lib.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_lib/test_lib_dyn/stdafx.cpp b/test_lib/test_lib_dyn/stdafx.cpp new file mode 100644 index 0000000..beba62b --- /dev/null +++ b/test_lib/test_lib_dyn/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test_lib_dyn.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test_lib/test_lib_dyn/stdafx.h b/test_lib/test_lib_dyn/stdafx.h new file mode 100644 index 0000000..c3afe5b --- /dev/null +++ b/test_lib/test_lib_dyn/stdafx.h @@ -0,0 +1,32 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows XP or later. +#define WINVER 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later. +#define _WIN32_IE 0x0600 // Change this to the appropriate value to target other versions of IE. +#endif + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here diff --git a/test_lib/test_lib_dyn/test_lib_dyn.cpp b/test_lib/test_lib_dyn/test_lib_dyn.cpp new file mode 100644 index 0000000..0a353f4 --- /dev/null +++ b/test_lib/test_lib_dyn/test_lib_dyn.cpp @@ -0,0 +1,54 @@ +// test_lib_dyn.cpp : Defines the entry point for the DLL application. +// + + +#include "../test_lib_static/test_static.h" + +#ifdef WIN32 + +#include "test_lib_dyn.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + A* p = new A; + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + func1(); + p->method1(); + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} + +// This is an example of an exported variable +TEST_LIB_DYN_API int ntest_lib_dyn=0; + +// This is an example of an exported function. +TEST_LIB_DYN_API int fntest_lib_dyn(void) +{ + return 42; +} + +// This is the constructor of a class that has been exported. +// see test_lib_dyn.h for the class definition +Ctest_lib_dyn::Ctest_lib_dyn() +{ + return; +} +#else +void init() +{ + A* p = new A; + func1(); + p->method1(); +} +#endif + diff --git a/test_lib/test_lib_dyn/test_lib_dyn.h b/test_lib/test_lib_dyn/test_lib_dyn.h new file mode 100644 index 0000000..f496437 --- /dev/null +++ b/test_lib/test_lib_dyn/test_lib_dyn.h @@ -0,0 +1,22 @@ +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the TEST_LIB_DYN_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// TEST_LIB_DYN_API functions as being imported from a DLL, whereas this DLL sees symbols +// defined with this macro as being exported. +#ifdef TEST_LIB_DYN_EXPORTS +#define TEST_LIB_DYN_API __declspec(dllexport) +#else +#define TEST_LIB_DYN_API __declspec(dllimport) +#endif + +// This class is exported from the test_lib_dyn.dll +class TEST_LIB_DYN_API Ctest_lib_dyn { +public: + Ctest_lib_dyn(void); + // TODO: add your methods here. +}; + +extern TEST_LIB_DYN_API int ntest_lib_dyn; + +TEST_LIB_DYN_API int fntest_lib_dyn(void); diff --git a/test_lib/test_lib_dyn/test_lib_dyn.vcproj b/test_lib/test_lib_dyn/test_lib_dyn.vcproj new file mode 100644 index 0000000..b0e0823 --- /dev/null +++ b/test_lib/test_lib_dyn/test_lib_dyn.vcproj @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_lib/test_lib_static/method1.cpp b/test_lib/test_lib_static/method1.cpp new file mode 100644 index 0000000..3d94a62 --- /dev/null +++ b/test_lib/test_lib_static/method1.cpp @@ -0,0 +1,9 @@ +#include +#include "test_static.h" + +void A::method1() +{ + puts( "A::method1() which calls A::method2()" ); + method2(); +} + diff --git a/test_lib/test_lib_static/method2.cpp b/test_lib/test_lib_static/method2.cpp new file mode 100644 index 0000000..9648b64 --- /dev/null +++ b/test_lib/test_lib_static/method2.cpp @@ -0,0 +1,13 @@ +#include +#include "test_static.h" + +void A::method2() +{ + puts( "A::method2()" ); +} + +void A::method2_1() +{ + puts( "A::method2_1()" ); +} + diff --git a/test_lib/test_lib_static/method3.cpp b/test_lib/test_lib_static/method3.cpp new file mode 100644 index 0000000..501bca3 --- /dev/null +++ b/test_lib/test_lib_static/method3.cpp @@ -0,0 +1,8 @@ +#include +#include "test_static.h" + +void A::method3() +{ + puts( "A::method3()" ); +} + diff --git a/test_lib/test_lib_static/obj1.cpp b/test_lib/test_lib_static/obj1.cpp new file mode 100644 index 0000000..8c6db01 --- /dev/null +++ b/test_lib/test_lib_static/obj1.cpp @@ -0,0 +1,10 @@ + +#include +#include "test_static.h" + +void func1() +{ + puts( "func1 which calls func2" ); + func2(); +} + diff --git a/test_lib/test_lib_static/obj2.cpp b/test_lib/test_lib_static/obj2.cpp new file mode 100644 index 0000000..fe669de --- /dev/null +++ b/test_lib/test_lib_static/obj2.cpp @@ -0,0 +1,13 @@ +#include +#include "test_static.h" + +void func2() +{ + puts( "func2" ); +} + +void func2_1() +{ + puts( "func2_1" ); +} + diff --git a/test_lib/test_lib_static/obj3.cpp b/test_lib/test_lib_static/obj3.cpp new file mode 100644 index 0000000..a12b8c0 --- /dev/null +++ b/test_lib/test_lib_static/obj3.cpp @@ -0,0 +1,8 @@ +#include +#include "test_static.h" + +void func3() +{ + puts( "func3" ); +} + diff --git a/test_lib/test_lib_static/test_lib_static.vcproj b/test_lib/test_lib_static/test_lib_static.vcproj new file mode 100644 index 0000000..37cd4d6 --- /dev/null +++ b/test_lib/test_lib_static/test_lib_static.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_lib/test_lib_static/test_static.h b/test_lib/test_lib_static/test_static.h new file mode 100644 index 0000000..e7ec97c --- /dev/null +++ b/test_lib/test_lib_static/test_static.h @@ -0,0 +1,25 @@ +#ifdef WIN32 +# define DYN_EXPORTS +# ifdef DYN_EXPORTS +# define DYN_EXPORT __declspec(dllexport) +# else +# define DYN_EXPORT __declspec(dllimport) +# endif +#else +# define DYN_EXPORT +#endif + +extern "C" DYN_EXPORT void func1(); +extern "C" DYN_EXPORT void func2(); +extern "C" DYN_EXPORT void func2_1(); +extern "C" DYN_EXPORT void func3(); + +class DYN_EXPORT A +{ +public: + + void method1(); + void method2(); + void method2_1(); + void method3(); +}; diff --git a/test_locale/testLocale.sln b/test_locale/testLocale.sln new file mode 100644 index 0000000..6096408 --- /dev/null +++ b/test_locale/testLocale.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testLocale", "testLocale\testLocale.vcproj", "{4641F4BE-34B9-4C3A-9EC4-2E18C7E1CD12}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4641F4BE-34B9-4C3A-9EC4-2E18C7E1CD12}.Debug|Win32.ActiveCfg = Debug|Win32 + {4641F4BE-34B9-4C3A-9EC4-2E18C7E1CD12}.Debug|Win32.Build.0 = Debug|Win32 + {4641F4BE-34B9-4C3A-9EC4-2E18C7E1CD12}.Release|Win32.ActiveCfg = Release|Win32 + {4641F4BE-34B9-4C3A-9EC4-2E18C7E1CD12}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test_locale/testLocale/testLocale.cpp b/test_locale/testLocale/testLocale.cpp new file mode 100644 index 0000000..13ba59b --- /dev/null +++ b/test_locale/testLocale/testLocale.cpp @@ -0,0 +1,18 @@ + +#include +#include + +int main(int argc, const char* argv[]) +{ + std::cout << "name of current global locale: " << std::locale().name() << "\n"; + std::cout << "name of classic C locale: " << std::locale::classic().name() << "\n"; + std::cout << "name of \"user's preferred locale\": " << std::locale("").name () << "\n"; + + std::cout.imbue( std::locale( "fr" ) ); + std::cerr.imbue( std::locale( "en_US" ) ); + + std::cout << "fr: " << 1.1 << std::endl; + std::cerr << "us: " << 1.1 << std::endl; + return 0; +} + diff --git a/test_locale/testLocale/testLocale.vcproj b/test_locale/testLocale/testLocale.vcproj new file mode 100644 index 0000000..347ef7b --- /dev/null +++ b/test_locale/testLocale/testLocale.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_public_parent/test_public_parent.sln b/test_public_parent/test_public_parent.sln new file mode 100644 index 0000000..64beef1 --- /dev/null +++ b/test_public_parent/test_public_parent.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_public_parent", "test_public_parent\test_public_parent.vcproj", "{0E3AF00F-C958-4AB9-8A65-02E2C51BDF87}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {0E3AF00F-C958-4AB9-8A65-02E2C51BDF87}.Debug|Win32.ActiveCfg = Debug|Win32 + {0E3AF00F-C958-4AB9-8A65-02E2C51BDF87}.Debug|Win32.Build.0 = Debug|Win32 + {0E3AF00F-C958-4AB9-8A65-02E2C51BDF87}.Release|Win32.ActiveCfg = Release|Win32 + {0E3AF00F-C958-4AB9-8A65-02E2C51BDF87}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test_public_parent/test_public_parent/stdafx.cpp b/test_public_parent/test_public_parent/stdafx.cpp new file mode 100644 index 0000000..dd621ff --- /dev/null +++ b/test_public_parent/test_public_parent/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// test_public_parent.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/test_public_parent/test_public_parent/stdafx.h b/test_public_parent/test_public_parent/stdafx.h new file mode 100644 index 0000000..0be0e6f --- /dev/null +++ b/test_public_parent/test_public_parent/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later. +#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows. +#endif + +#include +#include + + + +// TODO: reference additional headers your program requires here diff --git a/test_public_parent/test_public_parent/test_public_parent.cpp b/test_public_parent/test_public_parent/test_public_parent.cpp new file mode 100644 index 0000000..78f82e7 --- /dev/null +++ b/test_public_parent/test_public_parent/test_public_parent.cpp @@ -0,0 +1,44 @@ +// test_public_parent.cpp : Defines the entry point for the console application. +// + +#include "stdafx.h" +#include + +struct a +{ + virtual void f() + { std::cout << "a::f()\n" ; } +}; + +struct b : public a +{ + virtual void g() + { std::cout << "b::g()\n" ; } +}; + +struct c : public a +{ + virtual void g() + { std::cout << "c::g()\n" ; } +}; + +struct d : public b, protected c +{ + virtual void g() + { std::cout << "d::g()\n" ; } +}; + + +int _tmain(int argc, _TCHAR* argv[]) +{ + d o; + + d * pd = &o; + + a * pa = static_cast(pd); + + pd->f(); + + return 0; +} + diff --git a/test_public_parent/test_public_parent/test_public_parent.vcproj b/test_public_parent/test_public_parent/test_public_parent.vcproj new file mode 100644 index 0000000..59ca56b --- /dev/null +++ b/test_public_parent/test_public_parent/test_public_parent.vcproj @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test_rvalue_ref.cpp b/test_rvalue_ref.cpp new file mode 100644 index 0000000..8b02eb6 --- /dev/null +++ b/test_rvalue_ref.cpp @@ -0,0 +1,68 @@ + +#include +#include + +class copy_tracker +{ + int v; +public: + copy_tracker() + : v(0) + { + std::cout << "copy_tracker::copy_tracker()" << std::endl; + } + + copy_tracker( const copy_tracker& c ) + : v( c.v ) + { + std::cout << "copy_tracker::copy_tracker( copy_tracker& c )" << std::endl; + } + + void use_object() const + { + std::cout << v << std::endl; + } +}; + +copy_tracker create_rvalue() +{ + return copy_tracker(); +} + +const copy_tracker create_const_rvalue() +{ + return copy_tracker(); +} + +void f ( copy_tracker&& o ) +{ + o.use_object(); +} + +void f_const ( const copy_tracker&& o ) +{ + o.use_object(); +} + +void aaa( const std::string& s ) +{ + std::cout << s << std::endl; +} + +int main( void ) +{ + + f( create_rvalue() ); + + f_const( create_rvalue() ); + f_const( create_const_rvalue() ); + + copy_tracker lvalue; + f( std::move(lvalue) ); + f_const( std::move(lvalue) ); + + aaa( "aaaa"); + + return 0; +} + diff --git a/test_static_double.cpp b/test_static_double.cpp new file mode 100644 index 0000000..8bb70f1 --- /dev/null +++ b/test_static_double.cpp @@ -0,0 +1,18 @@ +#include + + +#include "test_static_double.h" + + +int main ( void ) +{ + A a; + A b; + + std::cout << a._st_double << std::endl; + std::cout << b._st_double << std::endl; + + + return main2(); +} + diff --git a/test_static_double.h b/test_static_double.h new file mode 100644 index 0000000..fdccde2 --- /dev/null +++ b/test_static_double.h @@ -0,0 +1,19 @@ +#include + +template < class C> +class A +{ +public: + static double _st_double; + +static double init_fun() +{ + puts( __FILE__ ); + return 8.; +} + +}; + +template double A::_st_double = A::init_fun(); +int main2(); + diff --git a/test_static_double2.cpp b/test_static_double2.cpp new file mode 100644 index 0000000..be6ef82 --- /dev/null +++ b/test_static_double2.cpp @@ -0,0 +1,15 @@ +#include + +#include "test_static_double.h" + +int main2 ( void ) +{ + A a; + A b; + + std::cout << a._st_double << std::endl; + std::cout << b._st_double << std::endl; + + return 0; +} + diff --git a/test_wfstream/test_wfstream.cpp b/test_wfstream/test_wfstream.cpp new file mode 100644 index 0000000..0a2762d --- /dev/null +++ b/test_wfstream/test_wfstream.cpp @@ -0,0 +1,20 @@ +// test_wfstream.cpp : Defines the entry point for the console application. +// + +#include +#include + +//const wchar_t wsz = Ô¼"Õ¡Õ¢Õ£Õ¤Õ¥Õ¦Õ§Õ¨Õ©ÕªÕ«Õ¬"; + +int main(int argc, const char * argv[]) +{ + std::wstring wstr; + std::wcin >> wstr; + std::wcout << "You typed: " << wstr << std::endl; + std::wstring::iterator it = wstr.begin(); + for ( ; it != wstr.end(); ++it ) + std::wcout << (int)*it << ", "; + std::wcout << std::endl; + return 0; +} + diff --git a/test_wfstream/test_wfstream.sln b/test_wfstream/test_wfstream.sln new file mode 100644 index 0000000..97dff61 --- /dev/null +++ b/test_wfstream/test_wfstream.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_wfstream", "test_wfstream.vcproj", "{202FE136-1957-4735-B223-F62180A41EFF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {202FE136-1957-4735-B223-F62180A41EFF}.Debug|Win32.ActiveCfg = Debug|Win32 + {202FE136-1957-4735-B223-F62180A41EFF}.Debug|Win32.Build.0 = Debug|Win32 + {202FE136-1957-4735-B223-F62180A41EFF}.Release|Win32.ActiveCfg = Release|Win32 + {202FE136-1957-4735-B223-F62180A41EFF}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/test_wfstream/test_wfstream.vcproj b/test_wfstream/test_wfstream.vcproj new file mode 100644 index 0000000..d828c27 --- /dev/null +++ b/test_wfstream/test_wfstream.vcproj @@ -0,0 +1,197 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toIntTest.cpp b/toIntTest.cpp new file mode 100644 index 0000000..0b2e049 --- /dev/null +++ b/toIntTest.cpp @@ -0,0 +1,552 @@ +// toIntTest.cpp : Defines the entry point for the console application. +// + +#include +#include "getCurrentTime.h" + +#include "../fw/2007.12/src/base/point.h" + +#if defined(__AIX) || defined(__sparc) +#define BUSERR_PROTECTION +#else +#define LOW_ENDIAN_ARCH +#endif + +#if defined(__AIX) || defined(__sparc) +#define TEST_AMOUNT 100000000 +#else +#define TEST_AMOUNT 1000000000 +#endif + + +#ifdef _MSC_VER +#define MY_INLINE __forceinline +#else +#define MY_INLINE inline +#endif + +#ifndef _MSC_VER +#define __int64 long +#endif + + + MY_INLINE bool isShortAligned( const unsigned char * p ) + { + return !((int)(p) % 2); + } + + MY_INLINE bool isIntAligned( const unsigned char * p ) + { + return !((int)(p) % 4); + } + + // + /// Convert a gdsII short to a standard short. + // + /*! + * The supplied pointer is to the buffer containing the entire gdsII short. + */ + MY_INLINE short toShort1( const unsigned char * p ) + { + // + // convert the byte stream to a machine short + // + register short val = *p << 8; + val += *(p+1); + // + // check for negative + // + if ( val & 0x8000 ) + { + val &= 0x7ffff; + val ^= 0x7ffff; + val = ++val * -1; + } + return val; + } + + // + /// Convert a gdsII short to a standard short. + // + /*! + * The supplied pointer is to the buffer containing the entire gdsII short. + */ + /* slow on sparc */ + MY_INLINE short toShort2( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isShortAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine short + // + register unsigned short val = *reinterpret_cast(p); + const short mask = 0x00ff; + val = (val & mask) << 8 | (val & ~mask) >> 8; + return (unsigned short)(val); +#else + // + // convert the byte stream to a machine short + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 8 | *(p+1); +#endif + } + + // + /// Convert a gdsII short to a standard short. + // + /*! + * The supplied pointer is to the buffer containing the entire gdsII short. + */ + /* slow on amd64 */ + MY_INLINE short toShort2_( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isShortAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine short + // +// register short val = *p << 8; +// return val | *(p+1); + register unsigned int val = *reinterpret_cast(p); + const int mask = 0x000000ff; + val = (val & mask) << 8 | (val & ~mask) >> 8; + return (unsigned short)(val); +#else + // + // convert the byte stream to a machine short + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 8 | *(p+1); +#endif + } + + // + /// Convert a gdsII short to a standard short. + // + /*! + * The supplied pointer is to the buffer containing the entire gdsII short. + */ + MY_INLINE short toShort3( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isShortAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine short + // + register unsigned short val = *reinterpret_cast(p); + return val >> 8 | val << 8; +#else + // + // convert the byte stream to a machine short + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 8 | *(p+1); +#endif + } + + // + /// Convert a gdsII short to a standard short. + // + /*! + * The supplied pointer is to the buffer containing the entire gdsII short. + */ + MY_INLINE short toShort3_( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isShortAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine short + // + register unsigned int val = 0; + val = *reinterpret_cast(p); + return val >> 8 | val << 8; +#else + // + // convert the byte stream to a machine short + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 8 | *(p+1); +#endif + } + + MY_INLINE int toInt1 ( const unsigned char * p ) + { + // + // convert the byte stream to a machine int + // + register int val = *p++ << 24; + val += *p++ << 16; + val += *p++ << 8; + val += *p; + + // + // check for negative + // + if ( val & 0x80000000 ) + { + val &= 0x7fffffff; + val ^= 0x7fffffff; + val = ++val * -1; + } + return val; + } + + // + // THE BEST + // + MY_INLINE int toInt2 ( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isIntAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine int + // + register unsigned int val = *reinterpret_cast(p); + const int mask = 0x00ff00ff; + val = (val & mask) << 8 | (val & ~mask) >> 8; + return val >> 16 | val << 16; +#else + // + // convert the byte stream to a machine int + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 24 | *(p+1) << 16 | *(p+2) << 8 | *(p+3); +#endif + } + +/* This is SLOW + MY_INLINE int toInt3 ( const unsigned char * p ) + { +#ifdef BUSERR_PROTECTION + if ( isIntAligned(p) ) + { +#endif +#ifdef LOW_ENDIAN_ARCH + // + // convert the byte stream to a machine int + // + union + { + unsigned char val[4]; + int iVal; + } o; + o.val[0] = p[3]; + o.val[1] = p[2]; + o.val[2] = p[1]; + o.val[3] = p[0]; + + return o.iVal; +#else + // + // convert the byte stream to a machine int + // + return *reinterpret_cast(p); +#endif +#ifdef BUSERR_PROTECTION + } + else + return *p << 24 | *(p+1) << 16 | *(p+2) << 8 | *(p+3); +#endif + } +*/ + + +#ifdef __GCC__ +typedef long __int64; +#endif + + typedef pod::point point_int; + + MY_INLINE point_int toIntPoint1 ( const unsigned char * p ) + { + int x = toInt2(p); + int y = toInt2(p+sizeof(int)); + return point_int(x,y); + } + + MY_INLINE point_int toIntPoint2 ( const unsigned char * p ) + { +#if defined(LOW_ENDIAN_ARCH) && defined(_LP64) + +#ifdef BUSERR_PROTECTION + if ( isIntAligned(p) ) + { +#endif + // + // convert the byte stream to a machine int + // + register unsigned __int64 val + = *reinterpret_cast(p); + const unsigned __int64 mask8 = 0x00ff00ff00ff00ffL; + const unsigned __int64 mask16 = 0x0000ffff0000ffffL; + val = (val & mask8) << 8 | (val & ~mask8) >> 8; + val = (val & mask16) << 16 | (val & ~mask16) >> 16; + return point_int( int((val << 32) >> 32), int(val >> 32) ); +#ifdef BUSERR_PROTECTION + } +#endif +#endif + +#if !defined(LOW_ENDIAN_ARCH) || !defined(_LP64) || defined( BUSERR_PROTECTION ) + // + // 32b code + // + int x = toInt2(p); + int y = toInt2(p+sizeof(int)); + return point_int(x,y); +#endif + } + + + +int main(int argc, char* argv[]) +{ +// Init + initGetCurrentTimeLib(); + + unsigned char buffer1[] = { + 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C }; + unsigned char* buffer = buffer1; + int szNum=0x01020344; + int szNum2=0x01020304; + + double dwStart, dwEnd; + + // + // test toShort + // +#if 1 + puts("Calculating speed for toShortX() aligned"); + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort1( buffer ); + dwEnd = getCurrentTime(); + printf( "toShort1 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort2( buffer ); + dwEnd = getCurrentTime(); + printf( "toShort2 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort2_( buffer ); + dwEnd = getCurrentTime(); + printf( "toShort2_ \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort3( buffer ); + dwEnd = getCurrentTime(); + printf( "toShort3 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort3_( buffer ); + dwEnd = getCurrentTime(); + printf( "toShort3_ \t%f\n", dwEnd - dwStart ); +#endif + +#if 1 + puts("Calculating speed for toShortX() not aligned"); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort1( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toShort1 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort2( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toShort2 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort2_( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toShort2_ \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort3( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toShort3 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile short a = toShort3_( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toShort3_ \t%f\n", dwEnd - dwStart ); +#endif + + // + // test toInt + // +#if 1 + puts("Calculating speed for toIntX() aligned"); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile int a = toInt1( buffer ); + dwEnd = getCurrentTime(); + printf( "toInt1 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile int a = toInt2( buffer ); + dwEnd = getCurrentTime(); + printf( "toInt2 \t%f\n", dwEnd - dwStart ); + +// dwStart = getCurrentTime(); +// for ( int i = TEST_AMOUNT; i; --i ) +// volatile int a = toInt3( buffer ); +// dwEnd = getCurrentTime(); +// printf( "toInt3 \t%f\n", dwEnd - dwStart ); + +#endif + +#if 1 + puts("Calculating speed for toIntX() miss aligned"); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile int a = toInt1( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toInt1 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + volatile int a = toInt2( buffer+1 ); + dwEnd = getCurrentTime(); + printf( "toInt2 \t%f\n", dwEnd - dwStart ); + +// dwStart = getCurrentTime(); +// for ( int i = TEST_AMOUNT; i; --i ) +// volatile int a = toInt3( buffer+1 ); +// dwEnd = getCurrentTime(); +// printf( "toInt3 \t%f\n", dwEnd - dwStart ); +#endif + + // + // test toIntPoint + // +#if 1 + puts("Calculating speed for toIntPointX()"); + volatile int nTest[2]; + point_int a; + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + { + nTest[0] = nTest[1] = i; + a += toIntPoint1( (const unsigned char *)&nTest ); + } + dwEnd = getCurrentTime(); + printf( "toIntPoint1 \t%f\n", dwEnd - dwStart ); + + dwStart = getCurrentTime(); + for ( int i = TEST_AMOUNT; i; --i ) + { + nTest[0] = nTest[1] = i; + a += toIntPoint2( (const unsigned char *)&nTest ); + } + dwEnd = getCurrentTime(); + printf( "toIntPoint2 \t%f\n", dwEnd - dwStart ); + + volatile int x = a.getX(); +#endif + +#if 1 + puts("Checking all results for toShort1()==toShort2()"); + for ( unsigned i = 0x10000; i; --i ) + if ( toShort1( (const unsigned char *)&i ) + != toShort3_( (const unsigned char *)&i ) ) + printf( "Error 1-3 %x o:%x m:%x\n", i, + (unsigned int)toShort1( (const unsigned char *)&i ), + (unsigned int)toShort3_( (const unsigned char *)&i ) ); + + puts("Checking all results for toInt1()==toInt2()"); + for ( unsigned i = 0xffffffff; i; --i ) + if ( toInt1( (const unsigned char *)&i ) + != toInt2( (const unsigned char *)&i ) ) + printf( "Error %x o:%x m:%x\n", i, + toInt1( (const unsigned char *)&i ), + toInt2( (const unsigned char *)&i ) ); + + + puts("Checking all results for toIntPoint1()==toIntPoint2()"); + int n8Byte[2]; + n8Byte[1] = 0; + for ( unsigned i = 0xffffffff; i; --i ) + { + n8Byte[0] = i; + if ( toIntPoint1( (const unsigned char *)&n8Byte ) + != toIntPoint2( (const unsigned char *)&n8Byte ) ) + printf( "Error %x,%x o:%x,%x m:%x,%x\n", + n8Byte[0], + n8Byte[1], + toIntPoint1( (const unsigned char *)&n8Byte ).getX(), + toIntPoint1( (const unsigned char *)&n8Byte ).getY(), + toIntPoint2( (const unsigned char *)&n8Byte ).getX(), + toIntPoint2( (const unsigned char *)&n8Byte ).getY() ); + } + + n8Byte[0] = 0; + for ( unsigned i = 0xffffffff; i; --i ) + { + n8Byte[1] = i; + if ( toIntPoint1( (const unsigned char *)&n8Byte ) + != toIntPoint2( (const unsigned char *)&n8Byte ) ) + printf( "Error %x,%x o:%x,%x m:%x,%x\n", + n8Byte[0], + n8Byte[1], + toIntPoint1( (const unsigned char *)&n8Byte ).getX(), + toIntPoint1( (const unsigned char *)&n8Byte ).getY(), + toIntPoint2( (const unsigned char *)&n8Byte ).getX(), + toIntPoint2( (const unsigned char *)&n8Byte ).getY() ); + } +#endif + + return 0; +} diff --git a/typedefed_operators.cpp b/typedefed_operators.cpp new file mode 100644 index 0000000..8a55814 --- /dev/null +++ b/typedefed_operators.cpp @@ -0,0 +1,29 @@ +#include +typedef long mylong; + +class A +{ +public: + + int val; + + operator mylong () + { + return (mylong)val; + } + + operator long () + { + return (long)val; + } +}; + +int main ( void ) +{ + A o; + o.val = 30; + + std::cout << (mylong)o << std::endl; + std::cout << (long)o << std::endl; +} + diff --git a/util/unfreeze.cpp b/util/unfreeze.cpp new file mode 100644 index 0000000..c1322ee --- /dev/null +++ b/util/unfreeze.cpp @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +int main(int argc, char *argv[]) +try +{ + if (argc < 2) + throw string("Usage: ") + argv[0] + " "; + for( int i = 0; i < argc; ++i ) + { + // + // Open the file and determint its size. + // + char *fileName = argv[1]; + int fd = open(fileName, O_RDONLY); + if (fd < 0) + throw strerror(errno); + struct stat st; + if (fstat(fd, &st) < 0) + throw strerror(errno); + off_t fileSize = st.st_size; + // + // Request the system to unload the file from the page cache. + // + if (posix_fadvise(fd, 0, fileSize, POSIX_FADV_DONTNEED)) + throw strerror(errno); + close(fd); + } + return 0; +} +catch (string str) +{ + cout << str << endl; + return 1; +} +catch (const char *str) +{ + cout << str << endl; + return 1; +} + diff --git a/vector_bool_itor.cpp b/vector_bool_itor.cpp new file mode 100644 index 0000000..893f252 --- /dev/null +++ b/vector_bool_itor.cpp @@ -0,0 +1,12 @@ +#include +#include + +int main ( void ) +{ + std::vector a; + a[0] = true; + a[1] = false; + std::sort( a.begin(), a.end() ); + return 0; +} + diff --git a/virtual_inheritence.cpp b/virtual_inheritence.cpp new file mode 100644 index 0000000..9859575 --- /dev/null +++ b/virtual_inheritence.cpp @@ -0,0 +1,48 @@ + +#include + +class A +{ +public: + A() + { + puts( "called A::A()" ); + } + + A( int /*fake*/ ) + { + puts( "called A::A( int )" ); + } +}; + +class B : virtual public A +{ +public: + B() + : A( 6 ) + { + puts( "called B::B()" ); + } +}; + +class C : public B +{ +public: + C() + { + puts( "called C::C()" ); + } +}; + +int main () +{ + puts( "constructing C object" ); + C o; + + puts( "" ); + puts( "constructing B object" ); + B ob; + + return 0; +} + diff --git a/virtual_method_ptr.cpp b/virtual_method_ptr.cpp new file mode 100644 index 0000000..e42ee00 --- /dev/null +++ b/virtual_method_ptr.cpp @@ -0,0 +1,81 @@ + +#include + +class A +{ +public: + typedef void (A::*virt_method_ptr)(); + + virt_method_ptr m_pMethod; + +public: + A() + { + m_pMethod = &A::func1; + } + + void call_method_through_ptr() + { + (this->*m_pMethod)(); + } + + virtual void func1() + { + puts( "called A::func1()" ); + } + + virtual void func2() + { + puts( "called A::func2()" ); + } + + virtual void func3() + { + puts( "called A::func3()" ); + } +}; + +class B : public A +{ +public: + int nTestPrintMe; + +public: + B( int n ) + { + m_pMethod = reinterpret_cast(&B::func4); + nTestPrintMe = n; + } + + virtual void func3() + { + puts( "called B::func3()" ); + } + + virtual void func4() + { + printf( "called B::func4( %d ) \n", nTestPrintMe ); + } +}; + +int main () +{ + A *o = new B( 10 ); + + o->call_method_through_ptr(); + + o->m_pMethod = &A::func1; + o->call_method_through_ptr(); + + o->m_pMethod = &A::func2; + o->call_method_through_ptr(); + + o->m_pMethod = &A::func3; + o->call_method_through_ptr(); + + o->m_pMethod = reinterpret_cast(&B::func4); + o->call_method_through_ptr(); + + return 0; +} + diff --git a/virtual_overriding.cpp b/virtual_overriding.cpp new file mode 100644 index 0000000..66b5308 --- /dev/null +++ b/virtual_overriding.cpp @@ -0,0 +1,42 @@ +#include + +class A +{ +public: + virtual A* fun() + { + puts( "A* fun()" ); + return new A; + } +}; + +class B +{ +public: + virtual B* fun1() + { + puts( "B* fun()" ); + return new B; + } +}; + +class C : public B, public A +{ +public: + virtual C* fun() + { + puts( "C* fun()" ); + return new C; + } +}; + +int main() +{ + A* p = new C; + + A* p_f = p->fun(); + + + return 0; +} + diff --git a/virtual_typo.cpp b/virtual_typo.cpp new file mode 100644 index 0000000..12035e3 --- /dev/null +++ b/virtual_typo.cpp @@ -0,0 +1,69 @@ + +#include + +class base +{ +public: + virtual void virt_func( int ) const + { + puts( "This is base::virt_func." ); + } +}; + +class typo_name : public base +{ +public: + virtual void virt_fanc( int ) const + { + puts( "This is typo_name::virt_fanc." ); + } +}; + +class typo_name2 : public base +{ +public: + void virt_fanc( int ) const + { + puts( "This is typo_name::virt_fanc." ); + } +}; + +class typo_arg : public base +{ +public: + virtual void virt_func( long ) const + { + puts( "This is typo_arg::virt_func." ); + } +}; + +class typo_const : public base +{ +public: + virtual void virt_func( int ) + { + puts( "This is typo_arg::virt_func." ); + } +}; + +void call_virt_func( base* p ) +{ + p->virt_func( 0 ); +} + +int main ( int, char** ) +{ + typo_name o1; + typo_name2 o2; + typo_arg o3; + typo_const o4; + + call_virt_func( &o1 ); + call_virt_func( &o2 ); + call_virt_func( &o3 ); + call_virt_func( &o4 ); + + return 0; +} + +