diff --git a/.gitignore b/.gitignore
index 841da2e..540a573 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-Media/*
-Ignore/*
-Analysis/*
+Media/*
+Ignore/*
+Analysis/*
+UnityBuild
\ No newline at end of file
diff --git a/ARToolKitUWP-Sample.unitypackage b/ARToolKitUWP-Sample.unitypackage
index a373485..552406e 100644
Binary files a/ARToolKitUWP-Sample.unitypackage and b/ARToolKitUWP-Sample.unitypackage differ
diff --git a/ARToolKitUWP.unitypackage b/ARToolKitUWP.unitypackage
index 21b54ec..21e0ac0 100644
Binary files a/ARToolKitUWP.unitypackage and b/ARToolKitUWP.unitypackage differ
diff --git a/ARToolKitUWP/.gitignore b/ARToolKitUWP/.gitignore
index 1d1e837..f42e814 100644
--- a/ARToolKitUWP/.gitignore
+++ b/ARToolKitUWP/.gitignore
@@ -17,8 +17,6 @@
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
-x64/
-x86/
bld/
[Bb]in/
[Oo]bj/
diff --git a/ARToolKitUWP/ARToolKit5/AR.vcxproj b/ARToolKitUWP/ARToolKit5/AR.vcxproj
index ee767c5..004f0d5 100644
--- a/ARToolKitUWP/ARToolKit5/AR.vcxproj
+++ b/ARToolKitUWP/ARToolKit5/AR.vcxproj
@@ -34,39 +34,39 @@
10.0
14.0
true
- 10.0.14393.0
- 10.0.14393.0
+ 10.0.18362.0
+ 10.0.10240.0
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
false
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
false
diff --git a/ARToolKitUWP/ARToolKit5/AR2.vcxproj b/ARToolKitUWP/ARToolKit5/AR2.vcxproj
new file mode 100644
index 0000000..86a23c7
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/AR2.vcxproj
@@ -0,0 +1,241 @@
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {536DC182-90E8-4DC2-B52C-B86FF217E371}
+ Windows Store
+ ARICP
+ Win32Proj
+ 10.0
+ 14.0
+ true
+ 10.0.18362.0
+ 10.0.10240.0
+ true
+
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ false
+
+
+ StaticLibrary
+ v142
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectName)d
+ $(ProjectName)d
+ $(ProjectName)d
+
+
+
+ Disabled
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ Disabled
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ X64
+
+
+ Disabled
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+ X64
+
+
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ _M_ARM64;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/ARICP.vcxproj b/ARToolKitUWP/ARToolKit5/ARICP.vcxproj
index bee00e6..32251b7 100644
--- a/ARToolKitUWP/ARToolKit5/ARICP.vcxproj
+++ b/ARToolKitUWP/ARToolKit5/ARICP.vcxproj
@@ -34,39 +34,39 @@
10.0
14.0
true
- 10.0.14393.0
- 10.0.14393.0
+ 10.0.18362.0
+ 10.0.10240.0
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
false
StaticLibrary
- v141
+ v142
false
diff --git a/ARToolKitUWP/ARToolKit5/ARMulti.vcxproj b/ARToolKitUWP/ARToolKit5/ARMulti.vcxproj
index bf6618f..6ba4993 100644
--- a/ARToolKitUWP/ARToolKit5/ARMulti.vcxproj
+++ b/ARToolKitUWP/ARToolKit5/ARMulti.vcxproj
@@ -34,39 +34,39 @@
10.0
14.0
true
- 10.0.14393.0
- 10.0.14393.0
+ 10.0.18362.0
+ 10.0.10240.0
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
false
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
true
StaticLibrary
- v141
+ v142
false
diff --git a/ARToolKitUWP/ARToolKit5/ARUtil.vcxproj b/ARToolKitUWP/ARToolKit5/ARUtil.vcxproj
new file mode 100644
index 0000000..38ae309
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/ARUtil.vcxproj
@@ -0,0 +1,219 @@
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+ {C25D2BE7-E7D8-457E-97A5-DF49656D2A43}
+ Windows Store
+ ARICP
+ Win32Proj
+ 10.0
+ 14.0
+ true
+ 10.0.18362.0
+ 10.0.10240.0
+ true
+
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ false
+
+
+ StaticLibrary
+ v142
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectName)d
+ $(ProjectName)d
+ $(ProjectName)d
+
+
+
+ Disabled
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ Disabled
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ X64
+
+
+ Disabled
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+ X64
+
+
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ _M_ARM64;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/KPM.vcxproj b/ARToolKitUWP/ARToolKit5/KPM.vcxproj
new file mode 100644
index 0000000..ad2e88c
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/KPM.vcxproj
@@ -0,0 +1,244 @@
+
+
+
+
+ Debug
+ ARM64
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ ARM64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {165C1AEF-EE64-4848-B6B7-B8669A56D156}
+ Windows Store
+ ARICP
+ Win32Proj
+ 10.0
+ 14.0
+ true
+ 10.0.18362.0
+ 10.0.10240.0
+ true
+
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ true
+
+
+ StaticLibrary
+ v142
+ false
+
+
+ StaticLibrary
+ v142
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectDir)..\$(Configuration)\$(Platform)\
+ $(ProjectName)d
+ $(ProjectName)d
+ $(ProjectName)d
+
+
+
+ Disabled
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;$(ProjectDir)src\KPM\FreakMatcher;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ Disabled
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;$(ProjectDir)src\KPM\FreakMatcher;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;$(ProjectDir)src\KPM\FreakMatcher;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ $(ProjectDir)include;$(ProjectDir)include\jpeglib;$(ProjectDir)src\KPM\FreakMatcher;%(AdditionalIncludeDirectories)
+ WIN32;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+ false
+
+
+
+
+
+ X64
+
+
+ Disabled
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+ X64
+
+
+ $(ProjectDir)include;%(AdditionalIncludeDirectories)
+ _M_ARM64;NDEBUG;_LIB;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+
+
+ Level3
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/include/AR/config.h b/ARToolKitUWP/ARToolKit5/include/AR/config.h
index 9f35b42..1789b19 100644
--- a/ARToolKitUWP/ARToolKit5/include/AR/config.h
+++ b/ARToolKitUWP/ARToolKit5/include/AR/config.h
@@ -397,7 +397,7 @@ enum {
#undef AR_DEFAULT_INPUT_WINDOWS_MEDIA_CAPTURE
// Other Windows-only configuration.
-#define HAVE_LIBJPEG 0
+#define HAVE_LIBJPEG 1
#endif // _WIN32
diff --git a/ARToolKitUWP/ARToolKit5/include/KPM/kpm.h b/ARToolKitUWP/ARToolKit5/include/KPM/kpm.h
new file mode 100644
index 0000000..c8686f8
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/KPM/kpm.h
@@ -0,0 +1,405 @@
+/*
+ * kpm.h
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC. All rights reserved.
+ * Copyright 2006-2015 ARToolworks, Inc. All rights reserved.
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+/*!
+ @header kpm
+ @abstract libKPM NFT image recognition and tracking initialisation routines.
+ @discussion
+ This header declares types and API for an NFT tracker,
+ in particular those routines involved in recognising a texture page and
+ initialising the tracking for use by the texture tracker.
+ @copyright 2006-2015 ARToolworks, Inc.
+ */
+
+#ifndef KPM_H
+#define KPM_H
+
+#define BINARY_FEATURE 1
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KpmPose6DOF 1
+#define KpmPoseHomography 2
+
+typedef enum {
+ KpmProcFullSize = 1,
+ KpmProcHalfSize = 2,
+ KpmProcQuatSize = 3,
+ KpmProcOneThirdSize = 4,
+ KpmProcTwoThirdSize = 5
+} KPM_PROC_MODE;
+#define KpmDefaultProcMode KpmProcFullSize
+
+#define KpmCompNull 0
+#define KpmCompX 1
+#define KpmCompY 2
+#define KpmDefaultComp KpmCompNull
+
+#define KpmChangePageNoAllPages (-1)
+
+typedef struct {
+ float x;
+ float y;
+} KpmCoord2D;
+
+typedef struct {
+ int width;
+ int height;
+ int imageNo;
+} KpmImageInfo;
+
+typedef struct {
+ KpmImageInfo *imageInfo;
+ int imageNum;
+ int pageNo;
+} KpmPageInfo;
+
+typedef struct _KpmRefData {
+ KpmCoord2D coord2D;
+ KpmCoord2D coord3D; // millimetres.
+#if BINARY_FEATURE
+ FreakFeature featureVec;
+#else
+ SurfFeature featureVec;
+#endif
+ int pageNo;
+ int refImageNo;
+} KpmRefData;
+
+/*!
+ @typedef KpmRefDataSet
+ @abstract A loaded dataset for KPM tracking.
+ @discussion
+ Key point matching takes as input a reference data set of points. This structure holds a set of points in memory prior to loading into the tracker.
+ @field refPoint Tracking reference points.
+ @field num Number of refPoints in the dataset.
+ @field pageInfo Array of info about each page in the dataset. One entry per page.
+ @field pageNum Number of pages in the dataset (i.e. a count, not an index).
+ */
+typedef struct {
+ KpmRefData *refPoint;
+ int num;
+ KpmPageInfo *pageInfo;
+ int pageNum;
+} KpmRefDataSet;
+
+/*!
+ @typedef KpmInputDataSet
+ @abstract Data describing the number and location of keypoints in an input image to be matched against a loaded data set.
+ @discussion
+ Key point matching occurs between a loaded data set and a set of keypoints extracted from an input image. This structure
+ holds the number and pixel location of keypoints in the input image. The keypoints themselves are an array of 'num'
+ KpmRefData structures.
+ @field coord Array of pixel locations of the keypoints in an input image.
+ @field num Number of coords in the array.
+ */
+typedef struct {
+ KpmCoord2D *coord;
+ int num;
+} KpmInputDataSet;
+
+#if !BINARY_FEATURE
+typedef struct {
+ int refIndex;
+ int inIndex;
+} KpmMatchData;
+
+typedef struct {
+ KpmMatchData *match;
+ int num;
+} KpmMatchResult;
+#endif
+
+typedef struct {
+ float camPose[3][4];
+ int pageNo;
+ float error;
+ int inlierNum;
+ int camPoseF;
+ int skipF;
+} KpmResult;
+
+typedef struct _KpmHandle KpmHandle;
+
+
+/*!
+ @function
+ @abstract Allocate and initialise essential structures for KPM tracking, using full six degree-of-freedom tracking.
+ @discussion
+ @param cparamLT Pointer to an ARParamLT structure holding camera parameters in lookup-table form.
+ The pointer only is copied, and the ARParamLT structure itself is NOT copied, and must remain
+ valid for the lifetime of the KpmHandle.
+ This structure also specifies the size of video frames which will be later supplied to the
+ kpmMatching() function as cparamLT->param.xsize and cparamLT->param.ysize.
+ @param pixFormat Pixel format of video frames which will be later supplied to the kpmMatching() function.
+ @result Pointer to a newly-allocated KpmHandle structure. This structure must be deallocated
+ via a call to kpmDeleteHandle() when no longer needed.
+ @seealso kpmCreateHandleHomography kpmCreateHandleHomography
+ @seealso kpmDeleteHandle kpmDeleteHandle
+ */
+KpmHandle *kpmCreateHandle ( ARParamLT *cparamLT, AR_PIXEL_FORMAT pixFormat );
+#define kpmCreatHandle kpmCreateHandle
+
+KpmHandle *kpmCreateHandle2( int xsize, int ysize, AR_PIXEL_FORMAT pixFormat );
+#define kpmCreatHandle2 kpmCreateHandle2
+
+/*!
+ @function
+ @abstract Allocate and initialise essential structures for KPM tracking, using homography-only tracking.
+ @discussion
+ Homography tracking assumes that the camera has zero lens-distortion, and this does not depend on
+ camera parameters. It is therefore unable to provide correctly calibrated position measurements,
+ but the resulting pose is suitable for visual overlay purposes.
+ @param xsize Width of video frames which will be later supplied to the kpmMatching() function.
+ @param ysize Height of video frames which will be later supplied to the kpmMatching() function.
+ @param pixFormat Pixel format of video frames which will be later supplied to the kpmMatching() function.
+ @result Pointer to a newly-allocated KpmHandle structure. This structure must be deallocated
+ via a call to kpmDeleteHandle() when no longer needed.
+ @seealso kpmCreateHandle kpmCreateHandle
+ @seealso kpmDeleteHandle kpmDeleteHandle
+ */
+KpmHandle *kpmCreateHandleHomography( int xsize, int ysize, AR_PIXEL_FORMAT pixFormat );
+#define kpmCreatHandleHomography kpmCreateHandleHomography
+
+/*!
+ @function
+ @abstract Finalise and dispose of structures for KPM tracking.
+ @discussion
+ Once KPM processing has completed, this routine should be called to
+ dispose of memory allocated.
+ @param kpmHandle Pointer to a location which holds a pointer to a KpmHandle structure.
+ On return, the location pointed to will be set to NULL.
+ @result 0 if successful, or value <0 in case of error.
+ @seealso kpmCreateHandle kpmCreateHandle
+ @seealso kpmCreateHandleHomography kpmCreateHandleHomography
+ */
+int kpmDeleteHandle( KpmHandle **kpmHandle );
+
+int kpmHandleGetXSize(const KpmHandle *kpmHandle);
+int kpmHandleGetYSize(const KpmHandle *kpmHandle);
+AR_PIXEL_FORMAT kpmHandleGetPixelFormat(const KpmHandle *kpmHandle);
+
+int kpmSetProcMode( KpmHandle *kpmHandle, KPM_PROC_MODE procMode );
+int kpmGetProcMode( KpmHandle *kpmHandle, KPM_PROC_MODE *procMode );
+int kpmSetDetectedFeatureMax( KpmHandle *kpmHandle, int detectedMaxFeature );
+int kpmGetDetectedFeatureMax( KpmHandle *kpmHandle, int *detectedMaxFeature );
+int kpmSetSurfThreadNum( KpmHandle *kpmHandle, int surfThreadNum );
+
+/*!
+ @function
+ @abstract Load a reference data set into the key point matcher for tracking.
+ @discussion
+ This function takes a reference data set already in memory and makes it the current
+ dataset for key point matching.
+ @param kpmHandle Handle to the current KPM tracker instance, as generated by kpmCreateHandle or kpmCreateHandleHomography.
+ @param refDataSet The reference data set to load into the KPM handle. The operation takes
+ a copy of the data required from this dataset, thus unless the need for a further load
+ at a later time is required, the dataset can be disposed of by calling kpmDeleteRefDataSet
+ after this operation succeeds.
+ @result 0 if successful, or value <0 in case of error.
+ @seealso kpmCreateHandle kpmCreateHandle
+ @seealso kpmCreateHandleHomography kpmCreateHandleHomography
+ @seealso kpmDeleteRefDataSet kpmDeleteRefDataSet
+ */
+int kpmSetRefDataSet( KpmHandle *kpmHandle, KpmRefDataSet *refDataSet );
+
+/*!
+ @function
+ @abstract
+ Loads a reference data set from a file into the KPM tracker.
+ @discussion
+ This is a convenience method which performs a sequence of kpmLoadRefDataSet, followed
+ by kpmSetRefDataSet and finally kpmDeleteRefDataSet. When tracking from a single
+ reference dataset file, this is the simplest means to start.
+ @param kpmHandle Handle to the current KPM tracker instance, as generated by kpmCreateHandle or kpmCreateHandleHomography.
+ @param filename Path to the dataset. Either full path, or a relative path if supported by
+ the operating system.
+ @param ext If non-NULL, a '.' charater and this string will be appended to 'filename'.
+ Often, this parameter is a pointer to the string "fset3".
+ @result Returns 0 if successful, or value <0 in case of error.
+ @seealso kpmLoadRefDataSet kpmLoadRefDataSet
+ @seealso kpmSetRefDataSet kpmSetRefDataSet
+ @seealso kpmDeleteRefDataSet kpmDeleteRefDataSet
+ */
+int kpmSetRefDataSetFile( KpmHandle *kpmHandle, const char *filename, const char *ext );
+
+int kpmSetRefDataSetFileOld( KpmHandle *kpmHandle, const char *filename, const char *ext );
+
+/*!
+ @function
+ @abstract Perform key-point matching on an image.
+ @discussion
+ @param kpmHandle
+ @param inImage Source image containing the pixels which will be searched for features.
+ Typically, this is one frame from a video stream. The dimensions and pixel format
+ of this image must match the values specified at the time of creation of the KPM handle.
+ @result 0 if successful, or value <0 in case of error.
+ @seealso kpmCreateHandle kpmCreateHandle
+ @seealso kpmCreateHandleHomography kpmCreateHandleHomography
+ */
+int kpmMatching( KpmHandle *kpmHandle, ARUint8 *inImage );
+
+int kpmSetMatchingSkipPage( KpmHandle *kpmHandle, int *skipPages, int num );
+#if !BINARY_FEATURE
+int kpmSetMatchingSkipRegion( KpmHandle *kpmHandle, SurfSubRect *skipRegion, int regionNum);
+#endif
+
+int kpmGetRefDataSet( KpmHandle *kpmHandle, KpmRefDataSet **refDataSet );
+int kpmGetInDataSet( KpmHandle *kpmHandle, KpmInputDataSet **inDataSet );
+#if !BINARY_FEATURE
+int kpmGetMatchingResult( KpmHandle *kpmHandle, KpmMatchResult **preRANSAC, KpmMatchResult **aftRANSAC );
+#endif
+int kpmGetPose( KpmHandle *kpmHandle, float pose[3][4], int *pageNo, float *error );
+int kpmGetResult( KpmHandle *kpmHandle, KpmResult **result, int *resultNum );
+
+
+int kpmGenRefDataSet ( ARUint8 *refImage, AR_PIXEL_FORMAT pixFormat, int xsize, int ysize, float dpi, int procMode, int compMode, int maxFeatureNum,
+ int pageNo, int imageNo, KpmRefDataSet **refDataSet );
+int kpmAddRefDataSet ( ARUint8 *refImage, AR_PIXEL_FORMAT pixFormat, int xsize, int ysize, float dpi, int procMode, int compMode, int maxFeatureNum,
+ int pageNo, int imageNo, KpmRefDataSet **refDataSet );
+
+/*!
+ @function
+ @abstract Merge a second KPM dataset into the first, and dispose of second.
+ @discussion
+ This function merges two KPM datasets by adding the reference points in
+ the second into the first (allocating a new set if the location pointed to
+ by refDataSetPtr1 is NULL) and then deleting the second set.
+ @param refDataSetPtr1 Pointer to a location which points to the first data set, or pointer
+ to NULL if a new dataset is to be created. This will hold the results of the merge.
+ @param refDataSetPtr2 Pointer to a location which points to the second data set. After the
+ merge, the dataset pointed to will be deleted and the location pointed to set to NULL.
+ @result 0 if the merge succeeded, or a value < 0 in case of error.
+ */
+int kpmMergeRefDataSet ( KpmRefDataSet **refDataSetPtr1, KpmRefDataSet **refDataSetPtr2 );
+#define kpmMargeRefDataSet kpmMergeRefDataSet
+
+/*!
+ @function
+ @abstract Dispose of a reference data set and its allocated memory.
+ @discussion
+ Once a data set has been loaded into a KPM handle, or is otherwise no longer required
+ to be held in memory, it should be deleted (i.e. disposed) from memory by calling
+ this function.
+ @param refDataSetPtr Pointer to memory location which points to the dataset. On success,
+ this location will be set to NULL.
+ @result 0 if the delete succeeded, or a value < 0 in case of error.
+ @seealso kpmLoadRefDataSet kpmLoadRefDataSet
+ */
+int kpmDeleteRefDataSet ( KpmRefDataSet **refDataSetPtr );
+
+/*!
+ @function
+ @abstract
+ @discussion
+ @param filename
+ @param ext
+ @param refDataSet
+ @result
+ */
+int kpmSaveRefDataSet ( const char *filename, const char *ext, KpmRefDataSet *refDataSet );
+
+/*!
+ @function
+ @abstract Load a reference data set from the filesystem into memory.
+ @discussion
+ This does not set the reference data as the current tracking set. To do that, call
+ kpmSetRefDataSet after this load completes. Alternately, the loaded set can be
+ merged with another loaded set by calling kpmMergeRefDataSet. To dispose of the
+ loaded dataset, call kpmDeleteRefDataSet.
+ @param filename Path to the dataset. Either full path, or a relative path if supported by
+ the operating system.
+ @param ext If non-NULL, a '.' charater and this string will be appended to 'filename'.
+ Often, this parameter is a pointer to the string "fset3".
+ @result Returns 0 if successful, or value <0 in case of error.
+ @param refDataSetPtr Pointer to a location which after loading will point to the loaded
+ reference data set.
+ @result 0 if the load succeeded, or a value < 0 in case of error.
+ @seealso kpmSetRefDataSet kpmSetRefDataSet
+ @seealso kpmMergeRefDataSet kpmMergeRefDataSet
+ @seealso kpmDeleteRefDataSet kpmDeleteRefDataSet
+ */
+int kpmLoadRefDataSet ( const char *filename, const char *ext, KpmRefDataSet **refDataSetPtr );
+
+int kpmLoadRefDataSetOld( const char *filename, const char *ext, KpmRefDataSet **refDataSetPtr );
+
+/*!
+ @function
+ @abstract
+ @discussion
+ @param refDataSet
+ @param oldPageNo
+ @param newPageNo
+ @result
+ */
+int kpmChangePageNoOfRefDataSet ( KpmRefDataSet *refDataSet, int oldPageNo, int newPageNo );
+
+
+/*!
+ @function
+ @abstract
+ @discussion
+ @param image Source image, as an unpadded pixel buffer beginning with the leftmost pixel of the top row.
+ @param pixFormat Layout of pixel data in 'image'.
+ @param xsize Layout of pixel data in 'image'.
+ @param ysize Layout of pixel data in 'image'.
+ @param procMode
+ @result
+ */
+ARUint8 *kpmUtilGenBWImage( ARUint8 *image, AR_PIXEL_FORMAT pixFormat, int xsize, int ysize, int procMode, int *newXsize, int *newYsize );
+
+#if !BINARY_FEATURE
+int kpmUtilGetPose ( ARParamLT *cparamLT, KpmMatchResult *matchData, KpmRefDataSet *refDataSet, KpmInputDataSet *inputDataSet, float camPose[3][4], float *err );
+
+int kpmUtilGetPose2( ARParamLT *cparamLT, KpmMatchResult *matchData, KpmRefDataSet *refDataSet, int *redDataIndex, KpmInputDataSet *inputDataSet, float camPose[3][4], float *error );
+int kpmUtilGetPoseHomography( KpmMatchResult *matchData, KpmRefDataSet *refDataSet, KpmInputDataSet *inputDataSet, float camPose[3][4], float *err );
+#endif
+int kpmUtilGetCorner( ARUint8 *inImagePtr, AR_PIXEL_FORMAT pixFormat, int xsize, int ysize, int procMode, int maxPointNum, CornerPoints *cornerPoints );
+
+
+double wallclock();
+
+int kpmLoadImageDb(const char *filename);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/include/KPM/kpmType.h b/ARToolKitUWP/ARToolKit5/include/KPM/kpmType.h
new file mode 100644
index 0000000..78ad17a
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/KPM/kpmType.h
@@ -0,0 +1,109 @@
+/*
+ * kpmType.h
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC. All rights reserved.
+ * Copyright 2006-2015 ARToolworks, Inc. All rights reserved.
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#pragma once
+
+#if !BINARY_FEATURE
+#include
+#endif
+
+//-------------------------------------------------------------------------
+// Corner points
+//-------------------------------------------------------------------------
+
+#define MAX_CORNER_POINTS 2000
+
+typedef struct _Point2f {
+ float x;
+ float y;
+} Point2f;
+
+typedef struct _Point2i {
+ int x;
+ int y;
+} Point2i;
+
+typedef struct _CornerPoints {
+ int num;
+ Point2i pt[MAX_CORNER_POINTS];
+} CornerPoints;
+
+//-------------------------------------------------------------------------
+// Correspondence
+//-------------------------------------------------------------------------
+
+typedef struct _MatchPoint {
+ float x1, y1; // Coordinates of corner points in an input image
+ float x2, y2; // Coordinates of corner points in a reference image
+} MatchPoint;
+
+typedef struct _CorspMap {
+ int num; // Same as the number of corner points in the input image
+ MatchPoint *mp;
+} CorspMap;
+
+#if BINARY_FEATURE
+
+#define FREAK_SUB_DIMENSION 96
+
+//FREAK feature vector
+typedef struct _FreakFeature {
+ unsigned char v[FREAK_SUB_DIMENSION];
+ float angle;
+ float scale;
+ int maxima;
+} FreakFeature;
+#else
+//-------------------------------------------------------------------------
+// Surf feature vector
+//-------------------------------------------------------------------------
+
+typedef struct _SurfFeature {
+ float v[SURF_SUB_DIMENSION];
+ int l;
+} SurfFeature;
+#endif
+
+typedef struct _FeatureVector {
+ int num;
+#if BINARY_FEATURE
+ FreakFeature *sf;
+#else
+ SurfFeature *sf;
+#endif
+
+} FeatureVector;
+
diff --git a/ARToolKitUWP/ARToolKit5/include/jpeglib/README.md b/ARToolKitUWP/ARToolKit5/include/jpeglib/README.md
new file mode 100644
index 0000000..7c24439
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/jpeglib/README.md
@@ -0,0 +1,3 @@
+jpeglib.h
+=========
+jpeglib-turbo v2.1.0
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/include/jpeglib/jconfig.h b/ARToolKitUWP/ARToolKit5/include/jpeglib/jconfig.h
new file mode 100644
index 0000000..2311a29
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/jpeglib/jconfig.h
@@ -0,0 +1,33 @@
+#define JPEG_LIB_VERSION 62
+#define LIBJPEG_TURBO_VERSION 2.1.0
+#define LIBJPEG_TURBO_VERSION_NUMBER 2001000
+
+#define C_ARITH_CODING_SUPPORTED
+#define D_ARITH_CODING_SUPPORTED
+#define MEM_SRCDST_SUPPORTED
+/* #undef WITH_SIMD */
+
+#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
+
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_SYS_TYPES_H
+#undef NEED_BSD_STRINGS
+
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+#undef INCOMPLETE_TYPES_BROKEN
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+
+/* Define "INT32" as int, not long, per Windows custom */
+#if !(defined(_BASETSD_H_) || defined(_BASETSD_H)) /* don't conflict if basetsd.h already read */
+typedef short INT16;
+typedef signed int INT32;
+#endif
+#define XMD_H /* prevent jmorecfg.h from redefining it */
diff --git a/ARToolKitUWP/ARToolKit5/include/jpeglib/jmorecfg.h b/ARToolKitUWP/ARToolKit5/include/jpeglib/jmorecfg.h
new file mode 100644
index 0000000..fb3a9cf
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/jpeglib/jmorecfg.h
@@ -0,0 +1,386 @@
+/*
+ * jmorecfg.h
+ *
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * Modified 1997-2009 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2009, 2011, 2014-2015, 2018, 2020, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+ * This file contains additional configuration options that customize the
+ * JPEG software for special applications or support machine-dependent
+ * optimizations. Most users will not need to touch this file.
+ */
+
+
+/*
+ * Maximum number of components (color channels) allowed in JPEG image.
+ * To meet the letter of Rec. ITU-T T.81 | ISO/IEC 10918-1, set this to 255.
+ * However, darn few applications need more than 4 channels (maybe 5 for CMYK +
+ * alpha mask). We recommend 10 as a reasonable compromise; use 4 if you are
+ * really short on memory. (Each allowed component costs a hundred or so
+ * bytes of storage, whether actually used in an image or not.)
+ */
+
+#define MAX_COMPONENTS 10 /* maximum number of image components */
+
+
+/*
+ * Basic data types.
+ * You may need to change these if you have a machine with unusual data
+ * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* Representation of a single sample (pixel element value).
+ * We frequently allocate large arrays of these, so it's important to keep
+ * them small. But if you have memory to burn and access to char or short
+ * arrays is very slow on your hardware, you might want to change these.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ */
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value) ((int)(value))
+
+#define MAXJSAMPLE 255
+#define CENTERJSAMPLE 128
+
+#endif /* BITS_IN_JSAMPLE == 8 */
+
+
+#if BITS_IN_JSAMPLE == 12
+/* JSAMPLE should be the smallest type that will hold the values 0..4095.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value) ((int)(value))
+
+#define MAXJSAMPLE 4095
+#define CENTERJSAMPLE 2048
+
+#endif /* BITS_IN_JSAMPLE == 12 */
+
+
+/* Representation of a DCT frequency coefficient.
+ * This should be a signed value of at least 16 bits; "short" is usually OK.
+ * Again, we allocate large arrays of these, but you can change to int
+ * if you have memory to burn and "short" is really slow.
+ */
+
+typedef short JCOEF;
+
+
+/* Compressed datastreams are represented as arrays of JOCTET.
+ * These must be EXACTLY 8 bits wide, at least once they are written to
+ * external storage. Note that when using the stdio data source/destination
+ * managers, this is also the data type passed to fread/fwrite.
+ */
+
+typedef unsigned char JOCTET;
+#define GETJOCTET(value) (value)
+
+
+/* These typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE. (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+typedef unsigned char UINT8;
+
+/* UINT16 must hold at least the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+typedef unsigned short UINT16;
+#else /* not HAVE_UNSIGNED_SHORT */
+typedef unsigned int UINT16;
+#endif /* HAVE_UNSIGNED_SHORT */
+
+/* INT16 must hold at least the values -32768..32767. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
+typedef short INT16;
+#endif
+
+/* INT32 must hold at least signed 32-bit values.
+ *
+ * NOTE: The INT32 typedef dates back to libjpeg v5 (1994.) Integers were
+ * sometimes 16-bit back then (MS-DOS), which is why INT32 is typedef'd to
+ * long. It also wasn't common (or at least as common) in 1994 for INT32 to be
+ * defined by platform headers. Since then, however, INT32 is defined in
+ * several other common places:
+ *
+ * Xmd.h (X11 header) typedefs INT32 to int on 64-bit platforms and long on
+ * 32-bit platforms (i.e always a 32-bit signed type.)
+ *
+ * basetsd.h (Win32 header) typedefs INT32 to int (always a 32-bit signed type
+ * on modern platforms.)
+ *
+ * qglobal.h (Qt header) typedefs INT32 to int (always a 32-bit signed type on
+ * modern platforms.)
+ *
+ * This is a recipe for conflict, since "long" and "int" aren't always
+ * compatible types. Since the definition of INT32 has technically been part
+ * of the libjpeg API for more than 20 years, we can't remove it, but we do not
+ * use it internally any longer. We instead define a separate type (JLONG)
+ * for internal use, which ensures that internal behavior will always be the
+ * same regardless of any external headers that may be included.
+ */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
+#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
+#ifndef _BASETSD_H /* MinGW is slightly different */
+#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
+typedef long INT32;
+#endif
+#endif
+#endif
+#endif
+
+/* Datatype used for image dimensions. The JPEG standard only supports
+ * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
+ * "unsigned int" is sufficient on all machines. However, if you need to
+ * handle larger images and you don't mind deviating from the spec, you
+ * can change this datatype. (Note that changing this datatype will
+ * potentially require modifying the SIMD code. The x86-64 SIMD extensions,
+ * in particular, assume a 32-bit JDIMENSION.)
+ */
+
+typedef unsigned int JDIMENSION;
+
+#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
+
+
+/* These macros are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions;
+ * in particular, you'll need to do that to make the library a Windows DLL.
+ * Another application is to make all functions global for use with debuggers
+ * or code profilers that require it.
+ */
+
+/* a function called through method pointers: */
+#define METHODDEF(type) static type
+/* a function used only in its module: */
+#define LOCAL(type) static type
+/* a function referenced thru EXTERNs: */
+#define GLOBAL(type) type
+/* a reference to a GLOBAL function: */
+#define EXTERN(type) extern type
+
+
+/* Originally, this macro was used as a way of defining function prototypes
+ * for both modern compilers as well as older compilers that did not support
+ * prototype parameters. libjpeg-turbo has never supported these older,
+ * non-ANSI compilers, but the macro is still included because there is some
+ * software out there that uses it.
+ */
+
+#define JMETHOD(type, methodname, arglist) type (*methodname) arglist
+
+
+/* libjpeg-turbo no longer supports platforms that have far symbols (MS-DOS),
+ * but again, some software relies on this macro.
+ */
+
+#undef FAR
+#define FAR
+
+
+/*
+ * On a few systems, type boolean and/or its values FALSE, TRUE may appear
+ * in standard header files. Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
+ */
+
+#ifndef HAVE_BOOLEAN
+typedef int boolean;
+#endif
+#ifndef FALSE /* in case these macros already exist */
+#define FALSE 0 /* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+/*
+ * The remaining options affect code selection within the JPEG library,
+ * but they don't need to be visible to most applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+#define JPEG_INTERNAL_OPTIONS
+#endif
+
+#ifdef JPEG_INTERNAL_OPTIONS
+
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * library. Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Capability options common to encoder and decoder: */
+
+#define DCT_ISLOW_SUPPORTED /* accurate integer method */
+#define DCT_IFAST_SUPPORTED /* less accurate int method [legacy feature] */
+#define DCT_FLOAT_SUPPORTED /* floating-point method [legacy feature] */
+
+/* Encoder capability options: */
+
+#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
+/* Note: if you selected 12-bit data precision, it is dangerous to turn off
+ * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
+ * precision, so jchuff.c normally uses entropy optimization to compute
+ * usable tables for higher precision. If you don't want to do optimization,
+ * you'll have to supply different default Huffman tables.
+ * The exact same statements apply for progressive JPEG: the default tables
+ * don't work for progressive mode. (This may get fixed, however.)
+ */
+#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
+
+/* Decoder capability options: */
+
+#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
+#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
+#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
+#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
+#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
+#define QUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
+#define QUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * The RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros are a vestigial
+ * feature of libjpeg. The idea was that, if an application developer needed
+ * to compress from/decompress to a BGR/BGRX/RGBX/XBGR/XRGB buffer, they could
+ * change these macros, rebuild libjpeg, and link their application statically
+ * with it. In reality, few people ever did this, because there were some
+ * severe restrictions involved (cjpeg and djpeg no longer worked properly,
+ * compressing/decompressing RGB JPEGs no longer worked properly, and the color
+ * quantizer wouldn't work with pixel sizes other than 3.) Furthermore, since
+ * all of the O/S-supplied versions of libjpeg were built with the default
+ * values of RGB_RED, RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE, many applications
+ * have come to regard these values as immutable.
+ *
+ * The libjpeg-turbo colorspace extensions provide a much cleaner way of
+ * compressing from/decompressing to buffers with arbitrary component orders
+ * and pixel sizes. Thus, we do not support changing the values of RGB_RED,
+ * RGB_GREEN, RGB_BLUE, or RGB_PIXELSIZE. In addition to the restrictions
+ * listed above, changing these values will also break the SIMD extensions and
+ * the regression tests.
+ */
+
+#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
+#define RGB_GREEN 1 /* Offset of Green */
+#define RGB_BLUE 2 /* Offset of Blue */
+#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
+
+#define JPEG_NUMCS 17
+
+#define EXT_RGB_RED 0
+#define EXT_RGB_GREEN 1
+#define EXT_RGB_BLUE 2
+#define EXT_RGB_PIXELSIZE 3
+
+#define EXT_RGBX_RED 0
+#define EXT_RGBX_GREEN 1
+#define EXT_RGBX_BLUE 2
+#define EXT_RGBX_PIXELSIZE 4
+
+#define EXT_BGR_RED 2
+#define EXT_BGR_GREEN 1
+#define EXT_BGR_BLUE 0
+#define EXT_BGR_PIXELSIZE 3
+
+#define EXT_BGRX_RED 2
+#define EXT_BGRX_GREEN 1
+#define EXT_BGRX_BLUE 0
+#define EXT_BGRX_PIXELSIZE 4
+
+#define EXT_XBGR_RED 3
+#define EXT_XBGR_GREEN 2
+#define EXT_XBGR_BLUE 1
+#define EXT_XBGR_PIXELSIZE 4
+
+#define EXT_XRGB_RED 1
+#define EXT_XRGB_GREEN 2
+#define EXT_XRGB_BLUE 3
+#define EXT_XRGB_PIXELSIZE 4
+
+static const int rgb_red[JPEG_NUMCS] = {
+ -1, -1, RGB_RED, -1, -1, -1, EXT_RGB_RED, EXT_RGBX_RED,
+ EXT_BGR_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED,
+ EXT_RGBX_RED, EXT_BGRX_RED, EXT_XBGR_RED, EXT_XRGB_RED,
+ -1
+};
+
+static const int rgb_green[JPEG_NUMCS] = {
+ -1, -1, RGB_GREEN, -1, -1, -1, EXT_RGB_GREEN, EXT_RGBX_GREEN,
+ EXT_BGR_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN,
+ EXT_RGBX_GREEN, EXT_BGRX_GREEN, EXT_XBGR_GREEN, EXT_XRGB_GREEN,
+ -1
+};
+
+static const int rgb_blue[JPEG_NUMCS] = {
+ -1, -1, RGB_BLUE, -1, -1, -1, EXT_RGB_BLUE, EXT_RGBX_BLUE,
+ EXT_BGR_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE,
+ EXT_RGBX_BLUE, EXT_BGRX_BLUE, EXT_XBGR_BLUE, EXT_XRGB_BLUE,
+ -1
+};
+
+static const int rgb_pixelsize[JPEG_NUMCS] = {
+ -1, -1, RGB_PIXELSIZE, -1, -1, -1, EXT_RGB_PIXELSIZE, EXT_RGBX_PIXELSIZE,
+ EXT_BGR_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE,
+ EXT_RGBX_PIXELSIZE, EXT_BGRX_PIXELSIZE, EXT_XBGR_PIXELSIZE, EXT_XRGB_PIXELSIZE,
+ -1
+};
+
+/* Definitions for speed-related optimizations. */
+
+/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
+ * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
+ * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
+ */
+
+#ifndef MULTIPLIER
+#ifndef WITH_SIMD
+#define MULTIPLIER int /* type for fastest integer multiply */
+#else
+#define MULTIPLIER short /* prefer 16-bit with SIMD for parellelism */
+#endif
+#endif
+
+
+/* FAST_FLOAT should be either float or double, whichever is done faster
+ * by your compiler. (Note that this type is only used in the floating point
+ * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
+ */
+
+#ifndef FAST_FLOAT
+#define FAST_FLOAT float
+#endif
+
+#endif /* JPEG_INTERNAL_OPTIONS */
diff --git a/ARToolKitUWP/ARToolKit5/include/jpeglib/jpeglib.h b/ARToolKitUWP/ARToolKit5/include/jpeglib/jpeglib.h
new file mode 100644
index 0000000..d7664f0
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/jpeglib/jpeglib.h
@@ -0,0 +1,1132 @@
+/*
+ * jpeglib.h
+ *
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * Modified 2002-2009 by Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, D. R. Commander.
+ * Copyright (C) 2015, Google, Inc.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+ * This file defines the application interface for the JPEG library.
+ * Most applications using the library need only include this file,
+ * and perhaps jerror.h if they want to know the exact error codes.
+ */
+
+#ifndef JPEGLIB_H
+#define JPEGLIB_H
+
+/*
+ * First we include the configuration files that record how this
+ * installation of the JPEG library is set up. jconfig.h can be
+ * generated automatically for many systems. jmorecfg.h contains
+ * manual configuration options that most people need not worry about.
+ */
+
+#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
+#include "jconfig.h" /* widely used configuration options */
+#endif
+#include "jmorecfg.h" /* seldom changed options */
+
+
+#ifdef __cplusplus
+#ifndef DONT_USE_EXTERN_C
+extern "C" {
+#endif
+#endif
+
+
+/* Various constants determining the sizes of things.
+ * All of these are specified by the JPEG standard, so don't change them
+ * if you want to be compatible.
+ */
+
+#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
+#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
+#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
+/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
+ * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
+ * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
+ * to handle it. We even let you do this from the jconfig.h file. However,
+ * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
+ * sometimes emits noncompliant files doesn't mean you should too.
+ */
+#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
+#ifndef D_MAX_BLOCKS_IN_MCU
+#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
+#endif
+
+
+/* Data structures for images (arrays of samples and of DCT coefficients).
+ */
+
+typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
+
+typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
+typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
+
+typedef JCOEF *JCOEFPTR; /* useful in a couple of places */
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+/* DCT coefficient quantization tables. */
+
+typedef struct {
+ /* This array gives the coefficient quantizers in natural array order
+ * (not the zigzag order in which they are stored in a JPEG DQT marker).
+ * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
+ */
+ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JQUANT_TBL;
+
+
+/* Huffman coding tables. */
+
+typedef struct {
+ /* These two fields directly represent the contents of a JPEG DHT marker */
+ UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
+ /* length k bits; bits[0] is unused */
+ UINT8 huffval[256]; /* The symbols, in order of incr code length */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JHUFF_TBL;
+
+
+/* Basic info about one component (color channel). */
+
+typedef struct {
+ /* These values are fixed over the whole image. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOF marker. */
+ int component_id; /* identifier for this component (0..255) */
+ int component_index; /* its index in SOF or cinfo->comp_info[] */
+ int h_samp_factor; /* horizontal sampling factor (1..4) */
+ int v_samp_factor; /* vertical sampling factor (1..4) */
+ int quant_tbl_no; /* quantization table selector (0..3) */
+ /* These values may vary between scans. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOS marker. */
+ /* The decompressor output side may not use these variables. */
+ int dc_tbl_no; /* DC entropy table selector (0..3) */
+ int ac_tbl_no; /* AC entropy table selector (0..3) */
+
+ /* Remaining fields should be treated as private by applications. */
+
+ /* These values are computed during compression or decompression startup: */
+ /* Component's size in DCT blocks.
+ * Any dummy blocks added to complete an MCU are not counted; therefore
+ * these values do not depend on whether a scan is interleaved or not.
+ */
+ JDIMENSION width_in_blocks;
+ JDIMENSION height_in_blocks;
+ /* Size of a DCT block in samples. Always DCTSIZE for compression.
+ * For decompression this is the size of the output from one DCT block,
+ * reflecting any scaling we choose to apply during the IDCT step.
+ * Values from 1 to 16 are supported.
+ * Note that different components may receive different IDCT scalings.
+ */
+#if JPEG_LIB_VERSION >= 70
+ int DCT_h_scaled_size;
+ int DCT_v_scaled_size;
+#else
+ int DCT_scaled_size;
+#endif
+ /* The downsampled dimensions are the component's actual, unpadded number
+ * of samples at the main buffer (preprocessing/compression interface), thus
+ * downsampled_width = ceil(image_width * Hi/Hmax)
+ * and similarly for height. For decompression, IDCT scaling is included, so
+ * downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE)
+ */
+ JDIMENSION downsampled_width; /* actual width in samples */
+ JDIMENSION downsampled_height; /* actual height in samples */
+ /* This flag is used only for decompression. In cases where some of the
+ * components will be ignored (eg grayscale output from YCbCr image),
+ * we can skip most computations for the unused components.
+ */
+ boolean component_needed; /* do we need the value of this component? */
+
+ /* These values are computed before starting a scan of the component. */
+ /* The decompressor output side may not use these variables. */
+ int MCU_width; /* number of blocks per MCU, horizontally */
+ int MCU_height; /* number of blocks per MCU, vertically */
+ int MCU_blocks; /* MCU_width * MCU_height */
+ int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
+ int last_col_width; /* # of non-dummy blocks across in last MCU */
+ int last_row_height; /* # of non-dummy blocks down in last MCU */
+
+ /* Saved quantization table for component; NULL if none yet saved.
+ * See jdinput.c comments about the need for this information.
+ * This field is currently used only for decompression.
+ */
+ JQUANT_TBL *quant_table;
+
+ /* Private per-component storage for DCT or IDCT subsystem. */
+ void *dct_table;
+} jpeg_component_info;
+
+
+/* The script for encoding a multiple-scan file is an array of these: */
+
+typedef struct {
+ int comps_in_scan; /* number of components encoded in this scan */
+ int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
+ int Ss, Se; /* progressive JPEG spectral selection parms */
+ int Ah, Al; /* progressive JPEG successive approx. parms */
+} jpeg_scan_info;
+
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct *jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+ jpeg_saved_marker_ptr next; /* next in list, or NULL */
+ UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
+ unsigned int original_length; /* # bytes of data in the file */
+ unsigned int data_length; /* # bytes of data saved at data[] */
+ JOCTET *data; /* the data contained in the marker */
+ /* the marker length word is not counted in data_length or original_length */
+};
+
+/* Known color spaces. */
+
+#define JCS_EXTENSIONS 1
+#define JCS_ALPHA_EXTENSIONS 1
+
+typedef enum {
+ JCS_UNKNOWN, /* error/unspecified */
+ JCS_GRAYSCALE, /* monochrome */
+ JCS_RGB, /* red/green/blue as specified by the RGB_RED,
+ RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros */
+ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
+ JCS_CMYK, /* C/M/Y/K */
+ JCS_YCCK, /* Y/Cb/Cr/K */
+ JCS_EXT_RGB, /* red/green/blue */
+ JCS_EXT_RGBX, /* red/green/blue/x */
+ JCS_EXT_BGR, /* blue/green/red */
+ JCS_EXT_BGRX, /* blue/green/red/x */
+ JCS_EXT_XBGR, /* x/blue/green/red */
+ JCS_EXT_XRGB, /* x/red/green/blue */
+ /* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR,
+ or JCS_EXT_XRGB during decompression, the X byte is undefined, and in
+ order to ensure the best performance, libjpeg-turbo can set that byte to
+ whatever value it wishes. Use the following colorspace constants to
+ ensure that the X byte is set to 0xFF, so that it can be interpreted as an
+ opaque alpha channel. */
+ JCS_EXT_RGBA, /* red/green/blue/alpha */
+ JCS_EXT_BGRA, /* blue/green/red/alpha */
+ JCS_EXT_ABGR, /* alpha/blue/green/red */
+ JCS_EXT_ARGB, /* alpha/red/green/blue */
+ JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue */
+} J_COLOR_SPACE;
+
+/* DCT/IDCT algorithm options. */
+
+typedef enum {
+ JDCT_ISLOW, /* accurate integer method */
+ JDCT_IFAST, /* less accurate integer method [legacy feature] */
+ JDCT_FLOAT /* floating-point method [legacy feature] */
+} J_DCT_METHOD;
+
+#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
+#define JDCT_DEFAULT JDCT_ISLOW
+#endif
+#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
+#define JDCT_FASTEST JDCT_IFAST
+#endif
+
+/* Dithering options for decompression. */
+
+typedef enum {
+ JDITHER_NONE, /* no dithering */
+ JDITHER_ORDERED, /* simple ordered dither */
+ JDITHER_FS /* Floyd-Steinberg error diffusion dither */
+} J_DITHER_MODE;
+
+
+/* Common fields between JPEG compression and decompression master structs. */
+
+#define jpeg_common_fields \
+ struct jpeg_error_mgr *err; /* Error handler module */ \
+ struct jpeg_memory_mgr *mem; /* Memory manager module */ \
+ struct jpeg_progress_mgr *progress; /* Progress monitor, or NULL if none */ \
+ void *client_data; /* Available for use by application */ \
+ boolean is_decompressor; /* So common code can tell which is which */ \
+ int global_state /* For checking call sequence validity */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure. There are no actual instances of
+ * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
+ */
+struct jpeg_common_struct {
+ jpeg_common_fields; /* Fields common to both master struct types */
+ /* Additional fields follow in an actual jpeg_compress_struct or
+ * jpeg_decompress_struct. All three structs must agree on these
+ * initial fields! (This would be a lot cleaner in C++.)
+ */
+};
+
+typedef struct jpeg_common_struct *j_common_ptr;
+typedef struct jpeg_compress_struct *j_compress_ptr;
+typedef struct jpeg_decompress_struct *j_decompress_ptr;
+
+
+/* Master record for a compression instance */
+
+struct jpeg_compress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
+
+ /* Destination for compressed data */
+ struct jpeg_destination_mgr *dest;
+
+ /* Description of source image --- these fields must be filled in by
+ * outer application before starting compression. in_color_space must
+ * be correct before you can even call jpeg_set_defaults().
+ */
+
+ JDIMENSION image_width; /* input image width */
+ JDIMENSION image_height; /* input image height */
+ int input_components; /* # of color components in input image */
+ J_COLOR_SPACE in_color_space; /* colorspace of input image */
+
+ double input_gamma; /* image gamma of input image */
+
+ /* Compression parameters --- these fields must be set before calling
+ * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
+ * initialize everything to reasonable defaults, then changing anything
+ * the application specifically wants to change. That way you won't get
+ * burnt when new parameters are added. Also note that there are several
+ * helper routines to simplify changing parameters.
+ */
+
+#if JPEG_LIB_VERSION >= 70
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ JDIMENSION jpeg_width; /* scaled JPEG image width */
+ JDIMENSION jpeg_height; /* scaled JPEG image height */
+ /* Dimensions of actual JPEG image that will be written to file,
+ * derived from input dimensions by scaling factors above.
+ * These fields are computed by jpeg_start_compress().
+ * You can also use jpeg_calc_jpeg_dimensions() to determine these values
+ * in advance of calling jpeg_start_compress().
+ */
+#endif
+
+ int data_precision; /* bits of precision in image data */
+
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ jpeg_component_info *comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ JQUANT_TBL *quant_tbl_ptrs[NUM_QUANT_TBLS];
+#if JPEG_LIB_VERSION >= 70
+ int q_scale_factor[NUM_QUANT_TBLS];
+#endif
+ /* ptrs to coefficient quantization tables, or NULL if not defined,
+ * and corresponding scale factors (percentage, initialized 100).
+ */
+
+ JHUFF_TBL *dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL *ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ int num_scans; /* # of entries in scan_info array */
+ const jpeg_scan_info *scan_info; /* script for multi-scan file, or NULL */
+ /* The default value of scan_info is NULL, which causes a single-scan
+ * sequential JPEG file to be emitted. To create a multi-scan file,
+ * set num_scans and scan_info to point to an array of scan definitions.
+ */
+
+ boolean raw_data_in; /* TRUE=caller supplies downsampled data */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+ boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+#if JPEG_LIB_VERSION >= 70
+ boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
+#endif
+ int smoothing_factor; /* 1..100, or 0 for no input smoothing */
+ J_DCT_METHOD dct_method; /* DCT algorithm selector */
+
+ /* The restart interval can be specified in absolute MCUs by setting
+ * restart_interval, or in MCU rows by setting restart_in_rows
+ * (in which case the correct restart_interval will be figured
+ * for each scan).
+ */
+ unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
+ int restart_in_rows; /* if > 0, MCU rows per restart interval */
+
+ /* Parameters controlling emission of special markers. */
+
+ boolean write_JFIF_header; /* should a JFIF marker be written? */
+ UINT8 JFIF_major_version; /* What to write for the JFIF version number */
+ UINT8 JFIF_minor_version;
+ /* These three values are not used by the JPEG code, merely copied */
+ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
+ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
+ /* ratio is defined by X_density/Y_density even when density_unit=0. */
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean write_Adobe_marker; /* should an Adobe marker be written? */
+
+ /* State variable: index of next scanline to be written to
+ * jpeg_write_scanlines(). Application may use this to control its
+ * processing loop, e.g., "while (next_scanline < image_height)".
+ */
+
+ JDIMENSION next_scanline; /* 0 .. image_height-1 */
+
+ /* Remaining fields are known throughout compressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during compression startup
+ */
+ boolean progressive_mode; /* TRUE if scan script uses progressive mode */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+#if JPEG_LIB_VERSION >= 70
+ int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
+ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
+#endif
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
+ /* The coefficient controller receives data in units of MCU rows as defined
+ * for fully interleaved scans (whether the JPEG file is interleaved or not).
+ * There are v_samp_factor * DCTSIZE sample rows of each component in an
+ * "iMCU" (interleaved MCU) row.
+ */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info *cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[C_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+#if JPEG_LIB_VERSION >= 80
+ int block_size; /* the basic DCT block size: 1..16 */
+ const int *natural_order; /* natural-order position array */
+ int lim_Se; /* min( Se, DCTSIZE2-1 ) */
+#endif
+
+ /*
+ * Links to compression subobjects (methods and private variables of modules)
+ */
+ struct jpeg_comp_master *master;
+ struct jpeg_c_main_controller *main;
+ struct jpeg_c_prep_controller *prep;
+ struct jpeg_c_coef_controller *coef;
+ struct jpeg_marker_writer *marker;
+ struct jpeg_color_converter *cconvert;
+ struct jpeg_downsampler *downsample;
+ struct jpeg_forward_dct *fdct;
+ struct jpeg_entropy_encoder *entropy;
+ jpeg_scan_info *script_space; /* workspace for jpeg_simple_progression */
+ int script_space_size;
+};
+
+
+/* Master record for a decompression instance */
+
+struct jpeg_decompress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
+
+ /* Source of compressed data */
+ struct jpeg_source_mgr *src;
+
+ /* Basic description of image --- filled in by jpeg_read_header(). */
+ /* Application may inspect these values to decide how to process image. */
+
+ JDIMENSION image_width; /* nominal image width (from SOF marker) */
+ JDIMENSION image_height; /* nominal image height */
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ /* Decompression processing parameters --- these fields must be set before
+ * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
+ * them to default values.
+ */
+
+ J_COLOR_SPACE out_color_space; /* colorspace for output */
+
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ double output_gamma; /* image gamma wanted in output */
+
+ boolean buffered_image; /* TRUE=multiple output passes */
+ boolean raw_data_out; /* TRUE=downsampled data wanted */
+
+ J_DCT_METHOD dct_method; /* IDCT algorithm selector */
+ boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
+ boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
+
+ boolean quantize_colors; /* TRUE=colormapped output wanted */
+ /* the following are ignored if not quantize_colors: */
+ J_DITHER_MODE dither_mode; /* type of color dithering to use */
+ boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
+ int desired_number_of_colors; /* max # colors to use in created colormap */
+ /* these are significant only in buffered-image mode: */
+ boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
+ boolean enable_external_quant;/* enable future use of external colormap */
+ boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
+
+ /* Description of actual output image that will be returned to application.
+ * These fields are computed by jpeg_start_decompress().
+ * You can also use jpeg_calc_output_dimensions() to determine these values
+ * in advance of calling jpeg_start_decompress().
+ */
+
+ JDIMENSION output_width; /* scaled image width */
+ JDIMENSION output_height; /* scaled image height */
+ int out_color_components; /* # of color components in out_color_space */
+ int output_components; /* # of color components returned */
+ /* output_components is 1 (a colormap index) when quantizing colors;
+ * otherwise it equals out_color_components.
+ */
+ int rec_outbuf_height; /* min recommended height of scanline buffer */
+ /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
+ * high, space and time will be wasted due to unnecessary data copying.
+ * Usually rec_outbuf_height will be 1 or 2, at most 4.
+ */
+
+ /* When quantizing colors, the output colormap is described by these fields.
+ * The application can supply a colormap by setting colormap non-NULL before
+ * calling jpeg_start_decompress; otherwise a colormap is created during
+ * jpeg_start_decompress or jpeg_start_output.
+ * The map has out_color_components rows and actual_number_of_colors columns.
+ */
+ int actual_number_of_colors; /* number of entries in use */
+ JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
+
+ /* State variables: these variables indicate the progress of decompression.
+ * The application may examine these but must not modify them.
+ */
+
+ /* Row index of next scanline to be read from jpeg_read_scanlines().
+ * Application may use this to control its processing loop, e.g.,
+ * "while (output_scanline < output_height)".
+ */
+ JDIMENSION output_scanline; /* 0 .. output_height-1 */
+
+ /* Current input scan number and number of iMCU rows completed in scan.
+ * These indicate the progress of the decompressor input side.
+ */
+ int input_scan_number; /* Number of SOS markers seen so far */
+ JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
+
+ /* The "output scan number" is the notional scan being displayed by the
+ * output side. The decompressor will not allow output scan/row number
+ * to get ahead of input scan/row, but it can fall arbitrarily far behind.
+ */
+ int output_scan_number; /* Nominal scan number being displayed */
+ JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
+
+ /* Current progression status. coef_bits[c][i] indicates the precision
+ * with which component c's DCT coefficient i (in zigzag order) is known.
+ * It is -1 when no data has yet been received, otherwise it is the point
+ * transform (shift) value for the most recent scan of the coefficient
+ * (thus, 0 at completion of the progression).
+ * This pointer is NULL when reading a non-progressive file.
+ */
+ int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
+
+ /* Internal JPEG parameters --- the application usually need not look at
+ * these fields. Note that the decompressor output side may not use
+ * any parameters that can change between scans.
+ */
+
+ /* Quantization and Huffman tables are carried forward across input
+ * datastreams when processing abbreviated JPEG datastreams.
+ */
+
+ JQUANT_TBL *quant_tbl_ptrs[NUM_QUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL *dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL *ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ /* These parameters are never carried across datastreams, since they
+ * are given in SOF/SOS markers or defined to be reset by SOI.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ jpeg_component_info *comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+#if JPEG_LIB_VERSION >= 80
+ boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
+#endif
+ boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
+
+ /* These fields record data obtained from optional markers recognized by
+ * the JPEG library.
+ */
+ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
+ /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+ UINT8 JFIF_major_version; /* JFIF version number */
+ UINT8 JFIF_minor_version;
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
+ UINT8 Adobe_transform; /* Color transform code from Adobe marker */
+
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+ /* Aside from the specific data retained from APPn markers known to the
+ * library, the uninterpreted contents of any or all APPn and COM markers
+ * can be saved in a list for examination by the application.
+ */
+ jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
+ /* Remaining fields are known throughout decompressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during decompression startup
+ */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+#if JPEG_LIB_VERSION >= 70
+ int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
+ int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
+#else
+ int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
+#endif
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
+ /* The coefficient controller's input and output progress is measured in
+ * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
+ * in fully interleaved JPEG scans, but are used whether the scan is
+ * interleaved or not. We define an iMCU row as v_samp_factor DCT block
+ * rows of each component. Therefore, the IDCT output contains
+ * v_samp_factor*DCT_[v_]scaled_size sample rows of a component per iMCU row.
+ */
+
+ JSAMPLE *sample_range_limit; /* table for fast range-limiting */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ * Note that the decompressor output side must not use these fields.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info *cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+#if JPEG_LIB_VERSION >= 80
+ /* These fields are derived from Se of first SOS marker.
+ */
+ int block_size; /* the basic DCT block size: 1..16 */
+ const int *natural_order; /* natural-order position array for entropy decode */
+ int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
+#endif
+
+ /* This field is shared between entropy decoder and marker parser.
+ * It is either zero or the code of a JPEG marker that has been
+ * read from the data source, but has not yet been processed.
+ */
+ int unread_marker;
+
+ /*
+ * Links to decompression subobjects (methods, private variables of modules)
+ */
+ struct jpeg_decomp_master *master;
+ struct jpeg_d_main_controller *main;
+ struct jpeg_d_coef_controller *coef;
+ struct jpeg_d_post_controller *post;
+ struct jpeg_input_controller *inputctl;
+ struct jpeg_marker_reader *marker;
+ struct jpeg_entropy_decoder *entropy;
+ struct jpeg_inverse_dct *idct;
+ struct jpeg_upsampler *upsample;
+ struct jpeg_color_deconverter *cconvert;
+ struct jpeg_color_quantizer *cquantize;
+};
+
+
+/* "Object" declarations for JPEG modules that may be supplied or called
+ * directly by the surrounding application.
+ * As with all objects in the JPEG library, these structs only define the
+ * publicly visible methods and state variables of a module. Additional
+ * private fields may exist after the public ones.
+ */
+
+
+/* Error handler object */
+
+struct jpeg_error_mgr {
+ /* Error exit handler: does not return to caller */
+ void (*error_exit) (j_common_ptr cinfo);
+ /* Conditionally emit a trace or warning message */
+ void (*emit_message) (j_common_ptr cinfo, int msg_level);
+ /* Routine that actually outputs a trace or error message */
+ void (*output_message) (j_common_ptr cinfo);
+ /* Format a message string for the most recent JPEG error or message */
+ void (*format_message) (j_common_ptr cinfo, char *buffer);
+#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
+ /* Reset error state variables at start of a new image */
+ void (*reset_error_mgr) (j_common_ptr cinfo);
+
+ /* The message ID code and any parameters are saved here.
+ * A message can have one string parameter or up to 8 int parameters.
+ */
+ int msg_code;
+#define JMSG_STR_PARM_MAX 80
+ union {
+ int i[8];
+ char s[JMSG_STR_PARM_MAX];
+ } msg_parm;
+
+ /* Standard state variables for error facility */
+
+ int trace_level; /* max msg_level that will be displayed */
+
+ /* For recoverable corrupt-data errors, we emit a warning message,
+ * but keep going unless emit_message chooses to abort. emit_message
+ * should count warnings in num_warnings. The surrounding application
+ * can check for bad data by seeing if num_warnings is nonzero at the
+ * end of processing.
+ */
+ long num_warnings; /* number of corrupt-data warnings */
+
+ /* These fields point to the table(s) of error message strings.
+ * An application can change the table pointer to switch to a different
+ * message list (typically, to change the language in which errors are
+ * reported). Some applications may wish to add additional error codes
+ * that will be handled by the JPEG library error mechanism; the second
+ * table pointer is used for this purpose.
+ *
+ * First table includes all errors generated by JPEG library itself.
+ * Error code 0 is reserved for a "no such error string" message.
+ */
+ const char * const *jpeg_message_table; /* Library errors */
+ int last_jpeg_message; /* Table contains strings 0..last_jpeg_message */
+ /* Second table can be added by application (see cjpeg/djpeg for example).
+ * It contains strings numbered first_addon_message..last_addon_message.
+ */
+ const char * const *addon_message_table; /* Non-library errors */
+ int first_addon_message; /* code for first string in addon table */
+ int last_addon_message; /* code for last string in addon table */
+};
+
+
+/* Progress monitor object */
+
+struct jpeg_progress_mgr {
+ void (*progress_monitor) (j_common_ptr cinfo);
+
+ long pass_counter; /* work units completed in this pass */
+ long pass_limit; /* total number of work units in this pass */
+ int completed_passes; /* passes completed so far */
+ int total_passes; /* total number of passes expected */
+};
+
+
+/* Data destination object for compression */
+
+struct jpeg_destination_mgr {
+ JOCTET *next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+
+ void (*init_destination) (j_compress_ptr cinfo);
+ boolean (*empty_output_buffer) (j_compress_ptr cinfo);
+ void (*term_destination) (j_compress_ptr cinfo);
+};
+
+
+/* Data source object for decompression */
+
+struct jpeg_source_mgr {
+ const JOCTET *next_input_byte; /* => next byte to read from buffer */
+ size_t bytes_in_buffer; /* # of bytes remaining in buffer */
+
+ void (*init_source) (j_decompress_ptr cinfo);
+ boolean (*fill_input_buffer) (j_decompress_ptr cinfo);
+ void (*skip_input_data) (j_decompress_ptr cinfo, long num_bytes);
+ boolean (*resync_to_restart) (j_decompress_ptr cinfo, int desired);
+ void (*term_source) (j_decompress_ptr cinfo);
+};
+
+
+/* Memory manager object.
+ * Allocates "small" objects (a few K total), "large" objects (tens of K),
+ * and "really big" objects (virtual arrays with backing store if needed).
+ * The memory manager does not allow individual objects to be freed; rather,
+ * each created object is assigned to a pool, and whole pools can be freed
+ * at once. This is faster and more convenient than remembering exactly what
+ * to free, especially where malloc()/free() are not too speedy.
+ * NB: alloc routines never return NULL. They exit to error_exit if not
+ * successful.
+ */
+
+#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
+#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
+#define JPOOL_NUMPOOLS 2
+
+typedef struct jvirt_sarray_control *jvirt_sarray_ptr;
+typedef struct jvirt_barray_control *jvirt_barray_ptr;
+
+
+struct jpeg_memory_mgr {
+ /* Method pointers */
+ void *(*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject);
+ void *(*alloc_large) (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject);
+ JSAMPARRAY (*alloc_sarray) (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow, JDIMENSION numrows);
+ JBLOCKARRAY (*alloc_barray) (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow, JDIMENSION numrows);
+ jvirt_sarray_ptr (*request_virt_sarray) (j_common_ptr cinfo, int pool_id,
+ boolean pre_zero,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess);
+ jvirt_barray_ptr (*request_virt_barray) (j_common_ptr cinfo, int pool_id,
+ boolean pre_zero,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess);
+ void (*realize_virt_arrays) (j_common_ptr cinfo);
+ JSAMPARRAY (*access_virt_sarray) (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable);
+ JBLOCKARRAY (*access_virt_barray) (j_common_ptr cinfo, jvirt_barray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable);
+ void (*free_pool) (j_common_ptr cinfo, int pool_id);
+ void (*self_destruct) (j_common_ptr cinfo);
+
+ /* Limit on memory allocation for this JPEG object. (Note that this is
+ * merely advisory, not a guaranteed maximum; it only affects the space
+ * used for virtual-array buffers.) May be changed by outer application
+ * after creating the JPEG object.
+ */
+ long max_memory_to_use;
+
+ /* Maximum allocation request accepted by alloc_large. */
+ long max_alloc_chunk;
+};
+
+
+/* Routine signature for application-supplied marker processing methods.
+ * Need not pass marker code since it is stored in cinfo->unread_marker.
+ */
+typedef boolean (*jpeg_marker_parser_method) (j_decompress_ptr cinfo);
+
+
+/* Originally, this macro was used as a way of defining function prototypes
+ * for both modern compilers as well as older compilers that did not support
+ * prototype parameters. libjpeg-turbo has never supported these older,
+ * non-ANSI compilers, but the macro is still included because there is some
+ * software out there that uses it.
+ */
+
+#define JPP(arglist) arglist
+
+
+/* Default error-management setup */
+EXTERN(struct jpeg_error_mgr *) jpeg_std_error(struct jpeg_error_mgr *err);
+
+/* Initialization of JPEG compression objects.
+ * jpeg_create_compress() and jpeg_create_decompress() are the exported
+ * names that applications should call. These expand to calls on
+ * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
+ * passed for version mismatch checking.
+ * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
+ */
+#define jpeg_create_compress(cinfo) \
+ jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t)sizeof(struct jpeg_compress_struct))
+#define jpeg_create_decompress(cinfo) \
+ jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t)sizeof(struct jpeg_decompress_struct))
+EXTERN(void) jpeg_CreateCompress(j_compress_ptr cinfo, int version,
+ size_t structsize);
+EXTERN(void) jpeg_CreateDecompress(j_decompress_ptr cinfo, int version,
+ size_t structsize);
+/* Destruction of JPEG compression objects */
+EXTERN(void) jpeg_destroy_compress(j_compress_ptr cinfo);
+EXTERN(void) jpeg_destroy_decompress(j_decompress_ptr cinfo);
+
+/* Standard data source and destination managers: stdio streams. */
+/* Caller is responsible for opening the file before and closing after. */
+EXTERN(void) jpeg_stdio_dest(j_compress_ptr cinfo, FILE *outfile);
+EXTERN(void) jpeg_stdio_src(j_decompress_ptr cinfo, FILE *infile);
+
+#if JPEG_LIB_VERSION >= 80 || defined(MEM_SRCDST_SUPPORTED)
+/* Data source and destination managers: memory buffers. */
+EXTERN(void) jpeg_mem_dest(j_compress_ptr cinfo, unsigned char **outbuffer,
+ unsigned long *outsize);
+EXTERN(void) jpeg_mem_src(j_decompress_ptr cinfo,
+ const unsigned char *inbuffer, unsigned long insize);
+#endif
+
+/* Default parameter setup for compression */
+EXTERN(void) jpeg_set_defaults(j_compress_ptr cinfo);
+/* Compression parameter setup aids */
+EXTERN(void) jpeg_set_colorspace(j_compress_ptr cinfo,
+ J_COLOR_SPACE colorspace);
+EXTERN(void) jpeg_default_colorspace(j_compress_ptr cinfo);
+EXTERN(void) jpeg_set_quality(j_compress_ptr cinfo, int quality,
+ boolean force_baseline);
+EXTERN(void) jpeg_set_linear_quality(j_compress_ptr cinfo, int scale_factor,
+ boolean force_baseline);
+#if JPEG_LIB_VERSION >= 70
+EXTERN(void) jpeg_default_qtables(j_compress_ptr cinfo,
+ boolean force_baseline);
+#endif
+EXTERN(void) jpeg_add_quant_table(j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor, boolean force_baseline);
+EXTERN(int) jpeg_quality_scaling(int quality);
+EXTERN(void) jpeg_simple_progression(j_compress_ptr cinfo);
+EXTERN(void) jpeg_suppress_tables(j_compress_ptr cinfo, boolean suppress);
+EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table(j_common_ptr cinfo);
+EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table(j_common_ptr cinfo);
+
+/* Main entry points for compression */
+EXTERN(void) jpeg_start_compress(j_compress_ptr cinfo,
+ boolean write_all_tables);
+EXTERN(JDIMENSION) jpeg_write_scanlines(j_compress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION num_lines);
+EXTERN(void) jpeg_finish_compress(j_compress_ptr cinfo);
+
+#if JPEG_LIB_VERSION >= 70
+/* Precalculate JPEG dimensions for current compression parameters. */
+EXTERN(void) jpeg_calc_jpeg_dimensions(j_compress_ptr cinfo);
+#endif
+
+/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_write_raw_data(j_compress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION num_lines);
+
+/* Write a special marker. See libjpeg.txt concerning safe usage. */
+EXTERN(void) jpeg_write_marker(j_compress_ptr cinfo, int marker,
+ const JOCTET *dataptr, unsigned int datalen);
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header(j_compress_ptr cinfo, int marker,
+ unsigned int datalen);
+EXTERN(void) jpeg_write_m_byte(j_compress_ptr cinfo, int val);
+
+/* Alternate compression function: just write an abbreviated table file */
+EXTERN(void) jpeg_write_tables(j_compress_ptr cinfo);
+
+/* Write ICC profile. See libjpeg.txt for usage information. */
+EXTERN(void) jpeg_write_icc_profile(j_compress_ptr cinfo,
+ const JOCTET *icc_data_ptr,
+ unsigned int icc_data_len);
+
+
+/* Decompression startup: read start of JPEG datastream to see what's there */
+EXTERN(int) jpeg_read_header(j_decompress_ptr cinfo, boolean require_image);
+/* Return value is one of: */
+#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
+#define JPEG_HEADER_OK 1 /* Found valid image datastream */
+#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
+/* If you pass require_image = TRUE (normal case), you need not check for
+ * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
+ * JPEG_SUSPENDED is only possible if you use a data source module that can
+ * give a suspension return (the stdio source module doesn't).
+ */
+
+/* Main entry points for decompression */
+EXTERN(boolean) jpeg_start_decompress(j_decompress_ptr cinfo);
+EXTERN(JDIMENSION) jpeg_read_scanlines(j_decompress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION max_lines);
+EXTERN(JDIMENSION) jpeg_skip_scanlines(j_decompress_ptr cinfo,
+ JDIMENSION num_lines);
+EXTERN(void) jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
+ JDIMENSION *width);
+EXTERN(boolean) jpeg_finish_decompress(j_decompress_ptr cinfo);
+
+/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_read_raw_data(j_decompress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION max_lines);
+
+/* Additional entry points for buffered-image mode. */
+EXTERN(boolean) jpeg_has_multiple_scans(j_decompress_ptr cinfo);
+EXTERN(boolean) jpeg_start_output(j_decompress_ptr cinfo, int scan_number);
+EXTERN(boolean) jpeg_finish_output(j_decompress_ptr cinfo);
+EXTERN(boolean) jpeg_input_complete(j_decompress_ptr cinfo);
+EXTERN(void) jpeg_new_colormap(j_decompress_ptr cinfo);
+EXTERN(int) jpeg_consume_input(j_decompress_ptr cinfo);
+/* Return value is one of: */
+/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
+#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
+#define JPEG_REACHED_EOI 2 /* Reached end of image */
+#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
+#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
+
+/* Precalculate output dimensions for current decompression parameters. */
+#if JPEG_LIB_VERSION >= 80
+EXTERN(void) jpeg_core_output_dimensions(j_decompress_ptr cinfo);
+#endif
+EXTERN(void) jpeg_calc_output_dimensions(j_decompress_ptr cinfo);
+
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers(j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit);
+
+/* Install a special processing method for COM or APPn markers. */
+EXTERN(void) jpeg_set_marker_processor(j_decompress_ptr cinfo,
+ int marker_code,
+ jpeg_marker_parser_method routine);
+
+/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
+EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients(j_decompress_ptr cinfo);
+EXTERN(void) jpeg_write_coefficients(j_compress_ptr cinfo,
+ jvirt_barray_ptr *coef_arrays);
+EXTERN(void) jpeg_copy_critical_parameters(j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo);
+
+/* If you choose to abort compression or decompression before completing
+ * jpeg_finish_(de)compress, then you need to clean up to release memory,
+ * temporary files, etc. You can just call jpeg_destroy_(de)compress
+ * if you're done with the JPEG object, but if you want to clean it up and
+ * reuse it, call this:
+ */
+EXTERN(void) jpeg_abort_compress(j_compress_ptr cinfo);
+EXTERN(void) jpeg_abort_decompress(j_decompress_ptr cinfo);
+
+/* Generic versions of jpeg_abort and jpeg_destroy that work on either
+ * flavor of JPEG object. These may be more convenient in some places.
+ */
+EXTERN(void) jpeg_abort(j_common_ptr cinfo);
+EXTERN(void) jpeg_destroy(j_common_ptr cinfo);
+
+/* Default restart-marker-resync procedure for use by data source modules */
+EXTERN(boolean) jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired);
+
+/* Read ICC profile. See libjpeg.txt for usage information. */
+EXTERN(boolean) jpeg_read_icc_profile(j_decompress_ptr cinfo,
+ JOCTET **icc_data_ptr,
+ unsigned int *icc_data_len);
+
+
+/* These marker codes are exported since applications and data source modules
+ * are likely to want to use them.
+ */
+
+#define JPEG_RST0 0xD0 /* RST0 marker code */
+#define JPEG_EOI 0xD9 /* EOI marker code */
+#define JPEG_APP0 0xE0 /* APP0 marker code */
+#define JPEG_COM 0xFE /* COM marker code */
+
+
+/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
+ * for structure definitions that are never filled in, keep it quiet by
+ * supplying dummy definitions for the various substructures.
+ */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+struct jpeg_comp_master { long dummy; };
+struct jpeg_c_main_controller { long dummy; };
+struct jpeg_c_prep_controller { long dummy; };
+struct jpeg_c_coef_controller { long dummy; };
+struct jpeg_marker_writer { long dummy; };
+struct jpeg_color_converter { long dummy; };
+struct jpeg_downsampler { long dummy; };
+struct jpeg_forward_dct { long dummy; };
+struct jpeg_entropy_encoder { long dummy; };
+struct jpeg_decomp_master { long dummy; };
+struct jpeg_d_main_controller { long dummy; };
+struct jpeg_d_coef_controller { long dummy; };
+struct jpeg_d_post_controller { long dummy; };
+struct jpeg_input_controller { long dummy; };
+struct jpeg_marker_reader { long dummy; };
+struct jpeg_entropy_decoder { long dummy; };
+struct jpeg_inverse_dct { long dummy; };
+struct jpeg_upsampler { long dummy; };
+struct jpeg_color_deconverter { long dummy; };
+struct jpeg_color_quantizer { long dummy; };
+#endif /* JPEG_INTERNALS */
+#endif /* INCOMPLETE_TYPES_BROKEN */
+
+
+/*
+ * The JPEG library modules define JPEG_INTERNALS before including this file.
+ * The internal structure declarations are read only when that is true.
+ * Applications using the library should not include jpegint.h, but may wish
+ * to include jerror.h.
+ */
+
+#ifdef JPEG_INTERNALS
+#include "jpegint.h" /* fetch private declarations */
+#include "jerror.h" /* fetch error codes too */
+#endif
+
+#ifdef __cplusplus
+#ifndef DONT_USE_EXTERN_C
+}
+#endif
+#endif
+
+#endif /* JPEGLIB_H */
diff --git a/ARToolKitUWP/ARToolKit5/include/jpeglib/jversion.h b/ARToolKitUWP/ARToolKit5/include/jpeglib/jversion.h
new file mode 100644
index 0000000..2ab534a
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/jpeglib/jversion.h
@@ -0,0 +1,54 @@
+/*
+ * jversion.h
+ *
+ * This file was part of the Independent JPEG Group's software:
+ * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding.
+ * libjpeg-turbo Modifications:
+ * Copyright (C) 2010, 2012-2021, D. R. Commander.
+ * For conditions of distribution and use, see the accompanying README.ijg
+ * file.
+ *
+ * This file contains software version identification.
+ */
+
+
+#if JPEG_LIB_VERSION >= 80
+
+#define JVERSION "8d 15-Jan-2012"
+
+#elif JPEG_LIB_VERSION >= 70
+
+#define JVERSION "7 27-Jun-2009"
+
+#else
+
+#define JVERSION "6b 27-Mar-1998"
+
+#endif
+
+/*
+ * NOTE: It is our convention to place the authors in the following order:
+ * - libjpeg-turbo authors (2009-) in descending order of the date of their
+ * most recent contribution to the project, then in ascending order of the
+ * date of their first contribution to the project, then in alphabetical
+ * order
+ * - Upstream authors in descending order of the date of the first inclusion of
+ * their code
+ */
+
+#define JCOPYRIGHT \
+ "Copyright (C) 2009-2021 D. R. Commander\n" \
+ "Copyright (C) 2015, 2020 Google, Inc.\n" \
+ "Copyright (C) 2019-2020 Arm Limited\n" \
+ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \
+ "Copyright (C) 2011-2016 Siarhei Siamashka\n" \
+ "Copyright (C) 2015 Intel Corporation\n" \
+ "Copyright (C) 2013-2014 Linaro Limited\n" \
+ "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \
+ "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \
+ "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \
+ "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \
+ "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding"
+
+#define JCOPYRIGHT_SHORT \
+ "Copyright (C) 1991-2021 The libjpeg-turbo Project and many others"
diff --git a/ARToolKitUWP/ARToolKit5/include/thread_sub.h b/ARToolKitUWP/ARToolKit5/include/thread_sub.h
new file mode 100644
index 0000000..a4ab6ef
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/include/thread_sub.h
@@ -0,0 +1,116 @@
+/*
+ * profile.h
+ * ARToolKit5
+ *
+ * Implements a basic client-worker threading system.
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2007-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+/*
+ thread_sub.c, thread_sub.h
+
+ Written by Hirokazu Kato
+ kato@is.naist.jp Apr.24 2007
+ */
+
+#ifndef THREAD_SUB_H
+#define THREAD_SUB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _THREAD_HANDLE_T THREAD_HANDLE_T;
+
+//
+// Client-side.
+//
+
+// Setup.
+THREAD_HANDLE_T *threadInit( int ID, void *arg, void *(*start_routine)(THREAD_HANDLE_T*) ); // Create a new thread, and launch start_routine() on it. Returns NULL in case of failure.
+int threadFree( THREAD_HANDLE_T **flag ); // Frees structures associated with the thread handle pointed to by the location pointed to by flag. Thread should already have terminated (i.e. threadWaitQuit() has returned). Location pointed to by flag is set to NULL.
+
+// Communication.
+int threadStartSignal( THREAD_HANDLE_T *flag ); // Send the worker thread the "start processing" request.
+int threadGetStatus( THREAD_HANDLE_T *flag ); // Find out (without waiting) whether a worker has ended. 0 = not started or started but not yet ended, 1 = ended.
+int threadGetBusyStatus( THREAD_HANDLE_T *flag ); // Find out if a worker is currently busy. 0 = worker not started or worker ended, 1 = worker started but not yet ended.
+int threadEndWait( THREAD_HANDLE_T *flag ); // Wait for thread to end processing.
+int threadWaitQuit( THREAD_HANDLE_T *flag ); // Tell a thread waiting for the "start processing" request to quit (exit), and wait until this has happened.
+
+// Example client structure:
+//
+// THREAD_HANDLE_T *threadHandle = threadInit(0, NULL, worker);
+// if (!threadHandle) {
+// fprintf(stderr, "Error starting thread.\n");
+// exit(-1);
+// }
+//
+// // Ready to do some work:
+// threadStartSignal(threadHandle);
+//
+// // Wait for the results.
+// threadEndWait(threadHandle);
+//
+// // If all done, quit and cleanup.
+// threadWaitQuit(threadHandle);
+// threadFree(&threadHandle);
+
+//
+// Worker-side.
+//
+
+int threadStartWait( THREAD_HANDLE_T *flag ); // Wait for the "start processing" request. Returns 0 if worker should start, or -1 if worker should quit (exit).
+int threadEndSignal( THREAD_HANDLE_T *flag ); // Notify anyone waiting that the worker has ended.
+int threadGetID( THREAD_HANDLE_T *flag ); // Get the 'ID' value passed to the thread's start routine.
+void *threadGetArg( THREAD_HANDLE_T *flag ); // Get the 'arg' value passed to the thread's start routine.
+
+// Example worker structure:
+//
+// void *worker(THREAD_HANDLE_T *threadHandle)
+// {
+// void *arg = threadHandle->arg; // Get data passed to the worker.
+// while (threadStartWait(threadHandle) == 0) {
+// // Do work, probably on arg.
+// threadEndSignal(threadHandle);
+// }
+// // Do cleanup.
+// return (NULL);
+// }
+
+int threadGetCPU(void); // Returns the number of online CPUs in the system.
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/lib/x86/README.md b/ARToolKitUWP/ARToolKit5/lib/x86/README.md
new file mode 100644
index 0000000..a021157
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/lib/x86/README.md
@@ -0,0 +1,3 @@
+libjpeg.lib
+===========
+libjpeg-turbo v2.1.0 static library (jpeg-static.lib) compiled for x86 (win32) platform
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/lib/x86/libjpeg.lib b/ARToolKitUWP/ARToolKit5/lib/x86/libjpeg.lib
new file mode 100644
index 0000000..78fd96b
Binary files /dev/null and b/ARToolKitUWP/ARToolKit5/lib/x86/libjpeg.lib differ
diff --git a/ARToolKitUWP/ARToolKit5/lib/x86_arm64/README.md b/ARToolKitUWP/ARToolKit5/lib/x86_arm64/README.md
new file mode 100644
index 0000000..17ff855
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/lib/x86_arm64/README.md
@@ -0,0 +1,3 @@
+libjpeg.lib
+===========
+libjpeg-turbo v2.1.0 static library (jpeg-static.lib) compiled for x86_ARM64 platform
\ No newline at end of file
diff --git a/ARToolKitUWP/ARToolKit5/lib/x86_arm64/libjpeg.lib b/ARToolKitUWP/ARToolKit5/lib/x86_arm64/libjpeg.lib
new file mode 100644
index 0000000..944a661
Binary files /dev/null and b/ARToolKitUWP/ARToolKit5/lib/x86_arm64/libjpeg.lib differ
diff --git a/ARToolKitUWP/ARToolKit5/src/AR/arUtil.c b/ARToolKitUWP/ARToolKit5/src/AR/arUtil.c
index 77f9e81..ec18537 100644
--- a/ARToolKitUWP/ARToolKit5/src/AR/arUtil.c
+++ b/ARToolKitUWP/ARToolKit5/src/AR/arUtil.c
@@ -186,7 +186,7 @@ void arLog(const int logLevel, const char *format, ...)
len = _vscprintf(format, ap);
if (len >= 0) {
buf = (char *)malloc((len + 1) * sizeof(char)); // +1 for nul-term.
- vsnprintf(buf, len, format, ap);
+ vsnprintf(buf, len + 1, format, ap);
buf[len] = '\0'; // nul-terminate.
}
#else
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/Makefile.in b/ARToolKitUWP/ARToolKit5/src/AR2/Makefile.in
new file mode 100644
index 0000000..e5b4c75
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/Makefile.in
@@ -0,0 +1,113 @@
+#
+# Makefile
+# ARToolKit5
+#
+# This file is part of ARToolKit.
+#
+# ARToolKit is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# ARToolKit is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with ARToolKit. If not, see .
+#
+# As a special exception, the copyright holders of this library give you
+# permission to link this library with independent modules to produce an
+# executable, regardless of the license terms of these independent modules, and to
+# copy and distribute the resulting executable under terms of your choice,
+# provided that you also meet, for each linked independent module, the terms and
+# conditions of the license of that module. An independent module is a module
+# which is neither derived from nor based on this library. If you modify this
+# library, you may extend this exception to your version of the library, but you
+# are not obligated to do so. If you do not wish to do so, delete this exception
+# statement from your version.
+#
+# Copyright 2015 Daqri, LLC.
+# Copyright 2006-2015 ARToolworks, Inc.
+#
+# Author(s): Hirokazu Kato, Philip Lamb
+#
+
+#
+# For instalation. Change this to your settings.
+#
+INC_DIR= ../../../include
+LIB_DIR= ../..
+#
+# compiler
+#
+CC=@CC@
+CFLAGS=@CFLAG@ -I$(INC_DIR)/@SYSTEM@ -I$(INC_DIR)
+#
+# For making the library
+#
+AR=@AR@
+ARFLAGS=@ARFLAGS@
+
+#
+# products
+#
+LIB= ${LIB_DIR}/libAR2.a
+
+INCLUDE= \
+ ${INC_DIR}/AR2/config.h \
+ ${INC_DIR}/AR2/coord.h \
+ ${INC_DIR}/AR2/featureSet.h \
+ ${INC_DIR}/AR2/imageFormat.h \
+ ${INC_DIR}/AR2/imageSet.h \
+ ${INC_DIR}/AR2/marker.h \
+ ${INC_DIR}/AR2/searchPoint.h \
+ ${INC_DIR}/AR2/template.h \
+ ${INC_DIR}/AR2/tracking.h \
+ ${INC_DIR}/AR2/util.h
+
+#
+# compilation control
+#
+LIBOBJS= \
+ ${LIB}(handle.o) \
+ ${LIB}(imageSet.o) \
+ ${LIB}(jpeg.o) \
+ ${LIB}(marker.o) \
+ ${LIB}(featureMap.o) \
+ ${LIB}(featureSet.o) \
+ ${LIB}(selectTemplate.o) \
+ ${LIB}(surface.o) \
+ ${LIB}(tracking.o) \
+ ${LIB}(tracking2d.o) \
+ ${LIB}(matching.o) \
+ ${LIB}(matching2.o) \
+ ${LIB}(template.o) \
+ ${LIB}(searchPoint.o) \
+ ${LIB}(coord.o) \
+ ${LIB}(util.o)
+
+
+all: ${LIBOBJS}
+
+${LIBOBJS}: ${INCLUDE}
+
+.c.a:
+ ${CC} -c ${CFLAGS} $<
+ ${AR} ${ARFLAGS} $@ $*.o
+ rm -f $*.o
+
+clean:
+ rm -f *.o
+ rm -f ${LIB}
+
+allclean:
+ rm -f *.o
+ rm -f ${LIB}
+ rm -f Makefile
+
+distclean:
+ rm -f *.o
+ rm -f Makefile
+
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/coord.c b/ARToolKitUWP/ARToolKit5/src/AR2/coord.c
new file mode 100644
index 0000000..763a112
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/coord.c
@@ -0,0 +1,240 @@
+/*
+ * AR2/coord.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+int ar2MarkerCoord2ScreenCoord2( const ARParamLT *cparamLT, const float trans[3][4], const float mx, const float my, float *sx, float *sy )
+{
+ float wtrans[3][4];
+ float hx, hy, h;
+ float ix, iy;
+ float ix1, iy1;
+
+ if( cparamLT != NULL ) {
+ arUtilMatMuldff( cparamLT->param.mat, trans, wtrans );
+ hx = wtrans[0][0] * mx
+ + wtrans[0][1] * my
+ + wtrans[0][3];
+ hy = wtrans[1][0] * mx
+ + wtrans[1][1] * my
+ + wtrans[1][3];
+ h = wtrans[2][0] * mx
+ + wtrans[2][1] * my
+ + wtrans[2][3];
+ ix = hx / h;
+ iy = hy / h;
+ }
+ else {
+ hx = trans[0][0] * mx
+ + trans[0][1] * my
+ + trans[0][3];
+ hy = trans[1][0] * mx
+ + trans[1][1] * my
+ + trans[1][3];
+ h = trans[2][0] * mx
+ + trans[2][1] * my
+ + trans[2][3];
+ *sx = hx / h;
+ *sy = hy / h;
+ return 0;
+ }
+
+ if( arParamIdeal2ObservLTf( &cparamLT->paramLTf, ix, iy, sx, sy ) < 0 ) return -1;
+ if( arParamObserv2IdealLTf( &cparamLT->paramLTf, *sx, *sy, &ix1, &iy1) < 0 ) return -1;
+ if( (ix-ix1)*(ix-ix1) + (iy-iy1)*(iy-iy1) > 1.0F ) return -1;
+
+ return 0;
+}
+
+int ar2MarkerCoord2ScreenCoord( const ARParamLT *cparamLT, const float trans[3][4], const float mx, const float my, float *sx, float *sy )
+{
+ float wtrans[3][4];
+ float hx, hy, h;
+ float ix, iy;
+
+ if( cparamLT != NULL ) {
+ arUtilMatMuldff( cparamLT->param.mat, trans, wtrans );
+ hx = wtrans[0][0] * mx
+ + wtrans[0][1] * my
+ + wtrans[0][3];
+ hy = wtrans[1][0] * mx
+ + wtrans[1][1] * my
+ + wtrans[1][3];
+ h = wtrans[2][0] * mx
+ + wtrans[2][1] * my
+ + wtrans[2][3];
+ ix = hx / h;
+ iy = hy / h;
+ }
+ else {
+ hx = trans[0][0] * mx
+ + trans[0][1] * my
+ + trans[0][3];
+ hy = trans[1][0] * mx
+ + trans[1][1] * my
+ + trans[1][3];
+ h = trans[2][0] * mx
+ + trans[2][1] * my
+ + trans[2][3];
+ *sx = hx / h;
+ *sy = hy / h;
+ return 0;
+ }
+
+ if( arParamIdeal2ObservLTf( &cparamLT->paramLTf, ix, iy, sx, sy ) < 0 ) return -1;
+
+ return 0;
+}
+
+int ar2ScreenCoord2MarkerCoord( const ARParamLT *cparamLT, const float trans[3][4], const float sx, const float sy, float *mx, float *my )
+{
+ float ix, iy;
+ float wtrans[3][4];
+ float c11, c12, c21, c22, b1, b2;
+ float m;
+
+ if( cparamLT == NULL ) {
+ c11 = trans[2][0] * sx - trans[0][0];
+ c12 = trans[2][1] * sx - trans[0][1];
+ c21 = trans[2][0] * sy - trans[1][0];
+ c22 = trans[2][1] * sy - trans[1][1];
+ b1 = trans[0][3] - trans[2][3] * sx;
+ b2 = trans[1][3] - trans[2][3] * sy;
+ }
+ else {
+ if( arParamObserv2IdealLTf( &cparamLT->paramLTf, sx, sy, &ix, &iy) < 0 ) return -1;
+ arUtilMatMuldff( cparamLT->param.mat, trans, wtrans );
+ c11 = wtrans[2][0] * ix - wtrans[0][0];
+ c12 = wtrans[2][1] * ix - wtrans[0][1];
+ c21 = wtrans[2][0] * iy - wtrans[1][0];
+ c22 = wtrans[2][1] * iy - wtrans[1][1];
+ b1 = wtrans[0][3] - wtrans[2][3] * ix;
+ b2 = wtrans[1][3] - wtrans[2][3] * iy;
+ }
+
+ m = c11 * c22 - c12 * c21;
+ if( m == 0.0F ) return -1;
+ *mx = (c22 * b1 - c12 * b2) / m;
+ *my = (c11 * b2 - c21 * b1) / m;
+
+ return 0;
+}
+
+int ar2MarkerCoord2ImageCoord( const int xsize, const int ysize, const float dpi, const float mx, const float my, float *ix, float *iy )
+{
+ *ix = mx * dpi / 25.4f;
+ *iy = ysize - my * dpi / 25.4f;
+
+ return 0;
+}
+
+int ar2ImageCoord2MarkerCoord2( const int xsize, const int ysize, const float dpi, const float ix, const float iy, float *mx, float *my )
+{
+ *mx = ix * 25.4f / dpi;
+ *my = (ysize - iy) * 25.4f / dpi;
+
+ return 0;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2GetImageValue( const ARParamLT *cparamLT, const float trans[3][4], const AR2ImageT *image,
+ const float sx, const float sy, const int blurLevel, ARUint8 *pBW )
+{
+ float mx, my;
+ float iix, iiy;
+ int ix, iy;
+
+ if( ar2ScreenCoord2MarkerCoord( cparamLT, trans, sx, sy, &mx, &my ) < 0 ) return -1;
+ ar2MarkerCoord2ImageCoord( image->xsize, image->ysize, image->dpi, mx, my, &iix, &iiy );
+ ix = (int)(iix + 0.5F);
+ iy = (int)(iiy + 0.5F);
+
+ if( ix < 0 || ix >= image->xsize
+ || iy < 0 || iy >= image->ysize ) return -1;
+
+ *pBW = image->imgBWBlur[blurLevel][iy*image->xsize+ix];
+
+ return 0;
+}
+
+int ar2GetImageValue2( const ARParamLT *cparamLT, const float trans[3][4], const AR2ImageT *image,
+ const float sx, const float sy, const int blurLevel, ARUint8 *pBW1, ARUint8 *pBW2, ARUint8 *pBW3 )
+{
+ float mx, my;
+ float iix, iiy;
+ int ix, iy;
+
+ if( ar2ScreenCoord2MarkerCoord( cparamLT, trans, sx, sy, &mx, &my ) < 0 ) return -1;
+ ar2MarkerCoord2ImageCoord( image->xsize, image->ysize, image->dpi, mx, my, &iix, &iiy );
+ ix = (int)(iix + 0.5);
+ iy = (int)(iiy + 0.5);
+
+ if( ix < 0 || ix >= image->xsize
+ || iy < 0 || iy >= image->ysize ) return -1;
+
+ if( blurLevel < 1 ) blurLevel = 1;
+ if( blurLevel >= AR2_BLUR_IMAGE_MAX-1 ) blurLevel = AR2_BLUR_IMAGE_MAX-2;
+ *pBW1 = image->imgBWBlur[blurLevel-1][iy*image->xsize+ix];
+ *pBW2 = image->imgBWBlur[blurLevel ][iy*image->xsize+ix];
+ *pBW3 = image->imgBWBlur[blurLevel+1][iy*image->xsize+ix];
+
+ return 0;
+}
+#else
+int ar2GetImageValue( const ARParamLT *cparamLT, const float trans[3][4], const AR2ImageT *image,
+ const float sx, const float sy, ARUint8 *pBW )
+{
+ float mx, my;
+ int ix, iy;
+
+ if( ar2ScreenCoord2MarkerCoord( cparamLT, trans, sx, sy, &mx, &my ) < 0 ) return -1;
+
+ ix = (int)(mx * image->dpi / 25.4F + 0.5F);
+ if( ix < 0 || ix >= image->xsize ) return -1;
+
+ iy = (int)(image->ysize - my * image->dpi / 25.4F + 0.5F);
+ if( iy < 0 || iy >= image->ysize ) return -1;
+
+ *pBW = image->imgBW[iy*image->xsize+ix];
+
+ return 0;
+}
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/featureMap.c b/ARToolKitUWP/ARToolKit5/src/AR2/featureMap.c
new file mode 100644
index 0000000..0db7b93
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/featureMap.c
@@ -0,0 +1,686 @@
+/*
+ * AR2/featureMap.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+static int make_template( ARUint8 *imageBW, int xsize, int ysize,
+ int cx, int cy, int ts1, int ts2, float sd_thresh,
+ float *template, float *vlen );
+
+static int get_similarity( ARUint8 *imageBW, int xsize, int ysize,
+ float *template, float vlen, int ts1, int ts2,
+ int cx, int cy, float *sim);
+
+int ar2FreeFeatureMap( AR2FeatureMapT *featureMap )
+{
+ free( featureMap->map );
+ free( featureMap);
+
+ return 0;
+}
+
+int ar2SaveFeatureMap( char *filename, char *ext, AR2FeatureMapT *featureMap )
+{
+ FILE *fp;
+
+ char buf[512];
+ sprintf(buf, "%s.%s", filename, ext);
+ if( (fp=fopen(buf, "wb")) == NULL ) return -1;
+
+ if( fwrite(&(featureMap->xsize), sizeof(featureMap->xsize), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureMap->ysize), sizeof(featureMap->ysize), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(featureMap->map, sizeof(float), (featureMap->xsize)*(featureMap->ysize), fp) != (featureMap->xsize)*(featureMap->ysize) ) goto bailBadWrite;
+
+ fclose(fp);
+ return 0;
+
+bailBadWrite:
+ ARLOGe("Error saving feature map: error writing data.\n");
+ fclose(fp);
+ return (-1);
+}
+
+AR2FeatureMapT *ar2ReadFeatureMap( char *filename, char *ext )
+{
+ AR2FeatureMapT *featureMap;
+ FILE *fp;
+
+ char buf[512];
+ sprintf(buf, "%s.%s", filename, ext);
+ if( (fp=fopen(buf, "rb")) == NULL ) return NULL;
+
+ arMalloc( featureMap, AR2FeatureMapT, 1 );
+
+ if( fread(&(featureMap->xsize), sizeof(featureMap->xsize), 1, fp) != 1 ) {
+ fclose(fp);
+ free(featureMap);
+ return NULL;
+ }
+
+ if( fread(&(featureMap->ysize), sizeof(featureMap->ysize), 1, fp) != 1 ) {
+ fclose(fp);
+ free(featureMap);
+ return NULL;
+ }
+
+ arMalloc( featureMap->map, float, (featureMap->xsize)*(featureMap->ysize) );
+
+ if( fread(featureMap->map, sizeof(float), (featureMap->xsize)*(featureMap->ysize), fp) != (featureMap->xsize)*(featureMap->ysize) ) {
+ free(featureMap->map);
+ free(featureMap);
+ fclose(fp);
+ return NULL;
+ }
+
+ fclose(fp);
+
+ return featureMap;
+}
+
+AR2FeatureMapT *ar2GenFeatureMap( AR2ImageT *image,
+ int ts1, int ts2,
+ int search_size1, int search_size2,
+ float max_sim_thresh, float sd_thresh )
+{
+ AR2FeatureMapT *featureMap;
+ float *fimage, *fp;
+ float *fimage2, *fp2;
+ float *template;
+ ARUint8 *p;
+ float dx, dy;
+ int xsize, ysize;
+ int hist[1000], sum;
+ int i, j, k;
+ float vlen;
+ float max, sim;
+ int ii, jj;
+
+ xsize = image->xsize;
+ ysize = image->ysize;
+ arMalloc(fimage, float, xsize*ysize);
+ arMalloc(fimage2, float, xsize*ysize);
+ arMalloc(template, float , (ts1+ts2+1)*(ts1+ts2+1));
+
+
+ fp2 = fimage2;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ p = image->imgBWBlur[1];
+#else
+ p = image->imgBW;
+#endif
+ for( i = 0; i < xsize; i++ ) {*(fp2++) = -1.0f; p++;}
+ for( j = 1; j < ysize-1; j++ ) {
+ *(fp2++) = -1.0f; p++;
+ for( i = 1; i < xsize-1; i++ ) {
+ dx = ((int)(*(p-xsize+1)) - (int)(*(p-xsize-1))
+ + (int)(*(p +1)) - (int)(*(p -1))
+ + (int)(*(p+xsize+1)) - (int)(*(p+xsize-1))) / (float )(3.0f*256);
+ dy = ((int)(*(p+xsize+1)) - (int)(*(p-xsize+1))
+ + (int)(*(p+xsize )) - (int)(*(p-xsize ))
+ + (int)(*(p+xsize-1)) - (int)(*(p-xsize-1))) / (float )(3.0f*256);
+ *(fp2++) = (float)sqrtf( (dx*dx+dy*dy) / (float )2.0f );
+ p++;
+ }
+ *(fp2++) = -1.0f; p++;
+ }
+ for( i = 0; i < xsize; i++ ) {*(fp2++) = -1.0f; p++;}
+
+
+ sum = 0;
+ for( i = 0; i < 1000; i++ ) hist[i] = 0;
+ fp2 = fimage2 + xsize + 1;
+ for( j = 1; j < ysize-1; j++ ) {
+ for( i = 1; i < xsize-1; i++ ) {
+ if( *fp2 > *(fp2-1) && *fp2 > *(fp2+1) && *fp2 > *(fp2-xsize) && *fp2 > *(fp2+xsize) ) {
+ k = (int)(*fp2 * 1000.0f);
+ if( k > 999 ) k = 999;
+ if( k < 0 ) k = 0;
+ hist[k]++;
+ sum++;
+ }
+ fp2++;
+ }
+ fp2 += 2;
+ }
+ j = 0;
+ for( i = 999; i >= 0; i-- ) {
+ j += hist[i];
+ if( (float )j / (float )(xsize*ysize) >= 0.02f ) break;
+ //if( (float )j / (float )(xsize*ysize) >= 0.2f ) break;
+ }
+ k = i;
+ ARLOGi(" ImageSize = %7d[pixel]\n", xsize*ysize);
+ ARLOGi("Extracted features = %7d[pixel]\n", sum);
+ ARLOGi(" Filtered features = %7d[pixel]\n", j);
+
+
+ fp = fimage;
+ fp2 = fimage2;
+ for( i = 0; i < xsize; i++ ) {
+ *(fp++) = 1.0f;
+ fp2++;
+ }
+ for( j = 1; j < ysize-1; j++ ) {
+ ARLOGi("\r%4d/%4d.", j+1, ysize); fflush(stdout);
+ *(fp++) = 1.0f;
+ fp2++;
+ for( i = 1; i < xsize-1; i++ ) {
+ if( *fp2 <= *(fp2-1) || *fp2 <= *(fp2+1) || *fp2 <= *(fp2-xsize) || *fp2 <= *(fp2+xsize) ) {
+ *(fp++) = 1.0f;
+ fp2++;
+ continue;
+ }
+ if( (int)(*fp2 * 1000) < k ) {
+ *(fp++) = 1.0f;
+ fp2++;
+ continue;
+ }
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( make_template(image->imgBWBlur[1], xsize, ysize, i, j, ts1, ts2, sd_thresh, template, &vlen) < 0 ) {
+#else
+ if( make_template(image->imgBW, xsize, ysize, i, j, ts1, ts2, sd_thresh, template, &vlen) < 0 ) {
+#endif
+ *(fp++) = 1.0f;
+ fp2++;
+ continue;
+ }
+
+ max = -1.0f;
+ for( jj = -search_size1; jj <= search_size1; jj++ ) {
+ for( ii = -search_size1; ii <= search_size1; ii++ ) {
+
+ if( ii*ii + jj*jj <= search_size2*search_size2 ) continue;
+ //if( jj >= -search_size2 && jj <= search_size2 && ii >= -search_size2 && ii <= search_size2 ) continue;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( get_similarity(image->imgBWBlur[1], xsize, ysize, template, vlen, ts1, ts2, i+ii, j+jj, &sim) < 0 ) continue;
+#else
+ if( get_similarity(image->imgBW, xsize, ysize, template, vlen, ts1, ts2, i+ii, j+jj, &sim) < 0 ) continue;
+#endif
+
+ if( sim > max ) {
+ max = sim;
+ if( max > max_sim_thresh ) break;
+ }
+ }
+ if( max > max_sim_thresh ) break;
+ }
+ *(fp++) = (float)max;
+ fp2++;
+ }
+ *(fp++) = 1.0f;
+ fp2++;
+ }
+ ARLOGi("\n");
+ free(fimage2);
+ free(template);
+
+ arMalloc( featureMap, AR2FeatureMapT, 1 );
+ featureMap->map = fimage;
+ featureMap->xsize = xsize;
+ featureMap->ysize = ysize;
+
+ return featureMap;
+}
+
+
+AR2FeatureCoordT *ar2SelectFeature( AR2ImageT *image, AR2FeatureMapT *featureMap,
+ int ts1, int ts2, int search_size2, int occ_size,
+ float max_sim_thresh, float min_sim_thresh, float sd_thresh, int *num )
+{
+ AR2FeatureCoordT *coord;
+ float *template, vlen;
+ float *fimage2, *fp1, *fp2;
+ float min_sim;
+ float sim, min, max;
+ float dpi;
+ int xsize, ysize;
+ int max_feature_num;
+ int cx, cy;
+ int i, j;
+
+ if( image->xsize != featureMap->xsize || image->ysize != featureMap->ysize ) return NULL;
+
+ xsize = image->xsize;
+ ysize = image->ysize;
+ dpi = image->dpi;
+ arMalloc(template, float , (ts1+ts2+1)*(ts1+ts2+1));
+ arMalloc(fimage2, float, xsize*ysize);
+ fp1 = featureMap->map;
+ fp2 = fimage2;
+ for( i = 0; i < xsize*ysize; i++ ) {
+ *(fp2++) = *(fp1++);
+ }
+
+ max_feature_num = (xsize/occ_size)*(ysize/occ_size);
+ if( max_feature_num < 10 ) max_feature_num = 10;
+ ARLOGi("Max feature = %d\n", max_feature_num);
+ arMalloc( coord, AR2FeatureCoordT, max_feature_num );
+ *num = 0;
+
+ while( *num < max_feature_num ) {
+
+ min_sim = max_sim_thresh;
+ fp2 = fimage2;
+ cx = cy = -1;
+ for( j = 0; j < ysize; j++ ) {
+ for( i = 0; i < xsize; i++ ) {
+ if( *fp2 < min_sim ) {
+ min_sim = *fp2;
+ cx = i;
+ cy = j;
+ }
+ fp2++;
+ }
+ }
+ if( cx == -1 ) break;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( make_template( image->imgBWBlur[1], xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#else
+ if( make_template( image->imgBW, xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#endif
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+ if( vlen/(ts1+ts2+1) < sd_thresh ) {
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+
+ min = 1.0f;
+ max = -1.0f;
+ for( j = -search_size2; j <= search_size2; j++ ) {
+ for( i = -search_size2; i <= search_size2; i++ ) {
+ if( i*i + j*j > search_size2*search_size2 ) continue;
+ if( i == 0 && j == 0 ) continue;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( get_similarity(image->imgBWBlur[1], xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#else
+ if( get_similarity(image->imgBW, xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#endif
+
+ if( sim < min ) {
+ min = sim;
+ if( min < min_sim_thresh && min < min_sim ) break;
+ }
+ if( sim > max ) {
+ max = sim;
+ if( max > 0.99f ) break;
+ }
+ }
+ if( (min < min_sim_thresh && min < min_sim) || max > 0.99f ) break;
+ }
+
+ if( (min < min_sim_thresh && min < min_sim) || max > 0.99f ) {
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+
+ coord[*num].x = cx;
+ coord[*num].y = cy;
+ coord[*num].mx = (float) cx / dpi * 25.4f; // millimetres.
+ coord[*num].my = (float)(ysize - cy) / dpi * 25.4f; // millimetres.
+ coord[*num].maxSim = (float)min_sim;
+ (*num)++;
+
+ ARLOGi("%3d: (%3d,%3d) : %f min=%f max=%f, sd=%f\n", *num, cx, cy, min_sim, min, max, vlen/(ts1+ts2+1));
+ for( j = -occ_size; j <= occ_size; j++ ) {
+ for( i = -occ_size; i <= occ_size; i++ ) {
+ if( cy+j < 0 || cy+j >= ysize || cx+i < 0 || cx+i >= xsize ) continue;
+
+ fimage2[(cy+j)*xsize+(cx+i)] = 1.0f;
+ }
+ }
+ }
+
+ free( template );
+ free( fimage2 );
+
+ return coord;
+}
+
+
+AR2FeatureCoordT *ar2SelectFeature2( AR2ImageT *image, AR2FeatureMapT *featureMap,
+ int ts1, int ts2, int search_size2, int occ_size,
+ float max_sim_thresh, float min_sim_thresh, float sd_thresh, int *num )
+{
+ AR2FeatureCoordT *coord;
+ float *template, vlen;
+ float min_sim;
+ float sim, min, max;
+ float *fimage2, *fp1, *fp2;
+ float dpi;
+ int xdiv, ydiv, div_size;
+ int xsize, ysize;
+ int max_feature_num;
+ int cx, cy;
+ int i, j;
+ int ii;
+
+ if( image->xsize != featureMap->xsize || image->ysize != featureMap->ysize ) return NULL;
+
+ occ_size *= 2;
+
+ xsize = image->xsize;
+ ysize = image->ysize;
+ dpi = image->dpi;
+ arMalloc(template, float , (ts1+ts2+1)*(ts1+ts2+1));
+ arMalloc(fimage2, float, xsize*ysize);
+ fp1 = featureMap->map;
+ fp2 = fimage2;
+ for( i = 0; i < xsize*ysize; i++ ) {
+ *(fp2++) = *(fp1++);
+ }
+
+ div_size = (ts1+ts2+1)*3;
+ xdiv = xsize/div_size;
+ ydiv = ysize/div_size;
+
+ max_feature_num = (xsize/occ_size)*(ysize/occ_size) + xdiv*ydiv;
+ ARLOGi("Max feature = %d\n", max_feature_num);
+ arMalloc( coord, AR2FeatureCoordT, max_feature_num );
+ *num = 0;
+
+ while( *num < max_feature_num ) {
+
+ min_sim = max_sim_thresh;
+ fp2 = fimage2;
+ cx = cy = -1;
+ for( j = 0; j < ysize; j++ ) {
+ for( i = 0; i < xsize; i++ ) {
+ if( *fp2 < min_sim ) {
+ min_sim = *fp2;
+ cx = i;
+ cy = j;
+ }
+ fp2++;
+ }
+ }
+ if( cx == -1 ) break;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( make_template( image->imgBWBlur[1], xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#else
+ if( make_template( image->imgBW, xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#endif
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+ if( vlen/(ts1+ts2+1) < sd_thresh ) {
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+
+ min = 1.0f;
+ max = -1.0f;
+ for( j = -search_size2; j <= search_size2; j++ ) {
+ for( i = -search_size2; i <= search_size2; i++ ) {
+ if( i*i + j*j > search_size2*search_size2 ) continue;
+ if( i == 0 && j == 0 ) continue;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( get_similarity(image->imgBWBlur[1], xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#else
+ if( get_similarity(image->imgBW, xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#endif
+
+ if( sim < min ) {
+ min = sim;
+ if( min < min_sim_thresh && min < min_sim ) break;
+ }
+ if( sim > max ) {
+ max = sim;
+ if( max > 0.99f ) break;
+ }
+ }
+ if( (min < min_sim_thresh && min < min_sim) || max > 0.99f ) break;
+ }
+
+ if( (min < min_sim_thresh && min < min_sim) || max > 0.99f ) {
+ fimage2[cy*xsize+cx] = 1.0f;
+ continue;
+ }
+
+ coord[*num].x = cx;
+ coord[*num].y = cy;
+ coord[*num].mx = (float) cx / dpi * 25.4f;
+ coord[*num].my = (float)(ysize - cy) / dpi * 25.4f;
+ coord[*num].maxSim = (float)min_sim;
+ (*num)++;
+
+ ARLOGi("%3d: (%3d,%3d) : %f min=%f max=%f, sd=%f\n", *num, cx, cy, min_sim, min, max, vlen/(ts1+ts2+1));
+ for( j = -occ_size; j <= occ_size; j++ ) {
+ for( i = -occ_size; i <= occ_size; i++ ) {
+ if( cy+j < 0 || cy+j >= ysize || cx+i < 0 || cx+i >= xsize ) continue;
+
+ fimage2[(cy+j)*xsize+(cx+i)] = 1.0f;
+ }
+ }
+ }
+
+
+ fp1 = featureMap->map;
+ fp2 = fimage2;
+ for( i = 0; i < xsize*ysize; i++ ) {
+ *(fp2++) = *(fp1++);
+ }
+ for( ii = 0; ii < *num; ii++ ) {
+ cx = coord[ii].x;
+ cy = coord[ii].y;
+ for( j = -occ_size; j <= occ_size; j++ ) {
+ for( i = -occ_size; i <= occ_size; i++ ) {
+ if( cy+j < 0 || cy+j >= ysize || cx+i < 0 || cx+i >= xsize ) continue;
+ fimage2[(cy+j)*xsize+(cx+i)] = 1.0f;
+ }
+ }
+ }
+
+ ARLOGi("---------------------------------------------------------------\n");
+
+ free( template );
+ free( fimage2 );
+
+ return coord;
+}
+
+
+int ar2PrintFeatureInfo( AR2ImageT *image, AR2FeatureMapT *featureMap, int ts1, int ts2, int search_size2, int cx, int cy )
+{
+ float *template, vlen;
+ float max, min, sim;
+ int xsize, ysize;
+ int i, j;
+
+ if( image->xsize != featureMap->xsize || image->ysize != featureMap->ysize ) return -1;
+
+ arMalloc(template, float, (ts1+ts2+1)*(ts1+ts2+1));
+ xsize = image->xsize;
+ ysize = image->ysize;
+ if( cx < 0 || cy < 0 || cx >= xsize || cy >= ysize ) {
+ free(template);
+ return -1;
+ }
+
+ if( featureMap->map[cy*xsize+cx] == 1.0 ) {
+ ARLOG("%3d, %3d: max_sim = %f\n", cx, cy, featureMap->map[cy*xsize+cx]);
+ free( template );
+ return 0;
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( make_template( image->imgBWBlur[1], xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#else
+ if( make_template( image->imgBW, xsize, ysize, cx, cy, ts1, ts2, 0.0, template, &vlen ) < 0 ) {
+#endif
+ free( template );
+ return -1;
+ }
+
+ min = 1.0f;
+ max = -1.0f;
+ARLOG("\n");
+ for( j = -search_size2; j <= search_size2; j++ ) {
+ for( i = -search_size2; i <= search_size2; i++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( get_similarity(image->imgBWBlur[1], xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#else
+ if( get_similarity(image->imgBW, xsize, ysize, template, vlen, ts1, ts2, cx+i, cy+j, &sim) < 0 ) continue;
+#endif
+
+ if( (i*i + j*j <= search_size2*search_size2)
+ && (i != 0 || j != 0) ) {
+ if( sim < min ) min = sim;
+ if( sim > max ) max = sim;
+ }
+ARLOG("%7.4f ", sim);
+ }
+ARLOG("\n");
+ }
+ARLOG("\n");
+
+ ARLOG("%3d, %3d: max_sim = %f, (max,min) = %f, %f, sd = %f\n", cx, cy, featureMap->map[cy*xsize+cx], max, min, vlen/(ts1+ts2+1));
+ free( template );
+ return 0;
+}
+
+
+static int make_template( ARUint8 *imageBW, int xsize, int ysize,
+ int cx, int cy, int ts1, int ts2, float sd_thresh,
+ float *template, float *vlen )
+{
+ ARUint8 *ip;
+ float *tp;
+ float vlen1, ave;
+ int i, j;
+
+ if( cy - ts1 < 0 || cy + ts2 >= ysize || cx - ts1 < 0 || cx + ts2 >= xsize ) return -1;
+
+ ave = 0.0f;
+ for( j = -ts1; j <= ts2; j++ ) {
+ ip = &imageBW[(cy+j)*xsize+(cx-ts1)];
+ for( i = -ts1; i <= ts2 ; i++ ) ave += *(ip++);
+ }
+ ave /= (ts1+ts2+1)*(ts1+ts2+1);
+
+ tp = template;
+ vlen1 = 0.0f;
+ for( j = -ts1; j <= ts2; j++ ) {
+ ip = &imageBW[(cy+j)*xsize+(cx-ts1)];
+ for( i = -ts1; i <= ts2 ; i++ ) {
+ *tp = (float )(*(ip++)) - ave;
+ vlen1 += *tp * *tp;
+ tp++;
+ }
+ }
+
+ if( vlen1 == 0.0f ) return -1;
+ if( vlen1/((ts1+ts2+1)*(ts1+ts2+1)) < sd_thresh*sd_thresh ) return -1;
+
+ *vlen = sqrtf(vlen1);
+
+ return 0;
+}
+
+static int get_similarity( ARUint8 *imageBW, int xsize, int ysize,
+ float *template, float vlen, int ts1, int ts2,
+ int cx, int cy, float *sim)
+{
+#if 0
+ ARUint8 *ip;
+ float *tp;
+ float ave2, w1, w2, vlen2;
+ int i, j;
+
+ if( cy - ts1 < 0 || cy + ts2 >= ysize || cx - ts1 < 0 || cx + ts2 >= xsize ) return -1;
+
+ ave2 = 0.0f;
+ for( j = -ts1; j <= ts2; j++ ) {
+ ip = &imageBW[(cy+j)*xsize+(cx-ts1)];
+ for( i = -ts1; i <= ts2 ; i++ ) ave2 += *(ip++);
+ }
+ ave2 /= (ts1+ts2+1)*(ts1+ts2+1);
+
+ tp = template;
+ w1 = 0.0f;
+ vlen2 = 0.0f;
+ for( j = -ts1; j <= ts2; j++ ) {
+ ip = &imageBW[(cy+j)*xsize+(cx-ts1)];
+ for( i = -ts1; i <= ts2 ; i++ ) {
+ w2 = (float )(*(ip++)) - ave2;
+ vlen2 += w2 * w2;
+ w1 += *(tp++) * w2;
+ }
+ }
+ if( vlen2 == 0.0f ) return -1;
+
+ vlen2 = sqrtf(vlen2);
+ *sim = w1 / (vlen * vlen2);
+#else
+ ARUint8 *ip;
+ float *tp;
+ float sx, sxx, sxy;
+ float vlen2;
+ int i, j;
+
+ if( cy - ts1 < 0 || cy + ts2 >= ysize || cx - ts1 < 0 || cx + ts2 >= xsize ) return -1;
+
+ tp = template;
+ sx = sxx = sxy = 0.0f;
+ for( j = -ts1; j <= ts2; j++ ) {
+ ip = &imageBW[(cy+j)*xsize+(cx-ts1)];
+ for( i = -ts1; i <= ts2 ; i++ ) {
+ sx += *ip;
+ sxx += *ip * *ip;
+ sxy += *(ip++) * *(tp++);
+ }
+ }
+ vlen2 = sxx - sx*sx/((ts1+ts2+1)*(ts1+ts2+1));
+ if( vlen2 == 0.0f ) return -1;
+ vlen2 = sqrtf(vlen2);
+
+ *sim = sxy / (vlen * vlen2);
+#endif
+
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/featureSet.c b/ARToolKitUWP/ARToolKit5/src/AR2/featureSet.c
new file mode 100644
index 0000000..0a20f77
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/featureSet.c
@@ -0,0 +1,176 @@
+/*
+ * AR2/featureSet.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+
+AR2FeatureSetT *ar2ReadFeatureSet( char *filename, char *ext )
+{
+ AR2FeatureSetT *featureSet = NULL;
+ FILE *fp = NULL;
+ int i, j, l3;
+
+ char buf[512];
+ sprintf(buf, "%s.%s", filename, ext);
+ if( (fp=fopen(buf, "rb")) == NULL ) {
+ ARLOGe("File open error. %s\n", filename);
+ return NULL;
+ }
+
+ arMalloc( featureSet, AR2FeatureSetT, 1 );
+
+ //COVHI10403
+ if( fread(&(featureSet->num), sizeof(featureSet->num), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail0;
+ }
+
+ arMalloc( featureSet->list, AR2FeaturePointsT, featureSet->num );
+ for( i = 0; i < featureSet->num; i++ ) {
+ if( fread(&(featureSet->list[i].scale), sizeof(featureSet->list[i].scale), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].maxdpi), sizeof(featureSet->list[i].maxdpi), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].mindpi), sizeof(featureSet->list[i].mindpi), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].num), sizeof(featureSet->list[i].num), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+
+ arMalloc( featureSet->list[i].coord, AR2FeatureCoordT, featureSet->list[i].num );
+ for( j = 0; j < featureSet->list[i].num; j++ ) {
+ if( fread(&(featureSet->list[i].coord[j].x), sizeof(featureSet->list[i].coord[j].x), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].coord[j].y), sizeof(featureSet->list[i].coord[j].y), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].coord[j].mx), sizeof(featureSet->list[i].coord[j].mx), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].coord[j].my), sizeof(featureSet->list[i].coord[j].my), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ if( fread(&(featureSet->list[i].coord[j].maxSim), sizeof(featureSet->list[i].coord[j].maxSim), 1, fp) != 1 ) {
+ ARLOGe("Read error!!\n");
+ goto bail1;
+ }
+ }
+ }
+
+ goto done;
+
+bail1:
+ for(l3=0;l3list[l3].coord );
+ }
+ free( featureSet->list );
+bail0:
+ free( featureSet );
+ featureSet = NULL;
+
+done:
+ fclose(fp);
+ return featureSet;
+}
+
+int ar2SaveFeatureSet( char *filename, char *ext, AR2FeatureSetT *featureSet )
+{
+ FILE *fp;
+ int i, j;
+
+ char buf[512];
+ sprintf(buf, "%s.%s", filename, ext);
+ if( (fp=fopen(buf, "wb")) == NULL ) {
+ ARLOGe("File open error. %s\n", filename);
+ return -1;
+ }
+
+ if( fwrite(&(featureSet->num), sizeof(featureSet->num), 1, fp) != 1 ) goto bailBadWrite;
+
+ for( i = 0; i < featureSet->num; i++ ) {
+ if( fwrite(&(featureSet->list[i].scale), sizeof(featureSet->list[i].scale), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].maxdpi), sizeof(featureSet->list[i].maxdpi), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].mindpi), sizeof(featureSet->list[i].mindpi), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].num), sizeof(featureSet->list[i].num), 1, fp) != 1 ) goto bailBadWrite;
+
+ for( j = 0; j < featureSet->list[i].num; j++ ) {
+ if( fwrite(&(featureSet->list[i].coord[j].x), sizeof(featureSet->list[i].coord[j].x), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].coord[j].y), sizeof(featureSet->list[i].coord[j].y), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].coord[j].mx), sizeof(featureSet->list[i].coord[j].mx), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].coord[j].my), sizeof(featureSet->list[i].coord[j].my), 1, fp) != 1 ) goto bailBadWrite;
+ if( fwrite(&(featureSet->list[i].coord[j].maxSim), sizeof(featureSet->list[i].coord[j].maxSim), 1, fp) != 1 ) goto bailBadWrite;
+ }
+ }
+
+ fclose(fp);
+ return 0;
+
+bailBadWrite:
+ ARLOGe("Error saving feature set: error writing data.\n");
+ fclose(fp);
+ return (-1);
+}
+
+int ar2FreeFeatureSet( AR2FeatureSetT **featureSet )
+{
+ int i;
+
+ if( *featureSet == NULL ) return -1;
+
+ for( i = 0; i < (*featureSet)->num; i++ ) {
+ free( (*featureSet)->list[i].coord );
+ }
+ free( (*featureSet)->list );
+ free( *featureSet );
+ *featureSet = NULL;
+
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/handle.c b/ARToolKitUWP/ARToolKit5/src/AR2/handle.c
new file mode 100644
index 0000000..6b3563d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/handle.c
@@ -0,0 +1,281 @@
+/*
+ * AR2/handle.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static AR2HandleT *ar2CreateHandleSub( AR_PIXEL_FORMAT pixFormat, int xsize, int ysize, int threadNum );
+
+
+AR2HandleT *ar2CreateHandle( ARParamLT *cparamLT, AR_PIXEL_FORMAT pixFormat, int threadNum )
+{
+ AR2HandleT *ar2Handle;
+
+ ar2Handle = ar2CreateHandleSub( pixFormat, cparamLT->param.xsize, cparamLT->param.ysize, threadNum );
+
+ ar2Handle->trackingMode = AR2_TRACKING_6DOF;
+ ar2Handle->cparamLT = cparamLT;
+ ar2Handle->icpHandle = icpCreateHandle( cparamLT->param.mat );
+ icpSetInlierProbability( ar2Handle->icpHandle, 0.0 );
+
+ return ar2Handle;
+}
+
+AR2HandleT *ar2CreateHandleHomography( int xsize, int ysize, AR_PIXEL_FORMAT pixFormat, int threadNum )
+{
+ AR2HandleT *ar2Handle;
+
+ ar2Handle = ar2CreateHandleSub( pixFormat, xsize, ysize, threadNum );
+
+ ar2Handle->trackingMode = AR2_TRACKING_HOMOGRAPHY;
+ ar2Handle->cparamLT = NULL;
+ ar2Handle->icpHandle = NULL;
+
+ return ar2Handle;
+}
+
+static AR2HandleT *ar2CreateHandleSub( int pixFormat, int xsize, int ysize, int threadNum )
+{
+ AR2HandleT *ar2Handle;
+ int i;
+
+ arMalloc(ar2Handle, AR2HandleT, 1);
+ ar2Handle->pixFormat = pixFormat;
+ ar2Handle->xsize = xsize;
+ ar2Handle->ysize = ysize;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ ar2Handle->blurMethod = AR2_DEFAULT_BLUR_METHOD;
+ ar2Handle->blurLevel = AR2_DEFAULT_BLUR_LEVEL;
+#endif
+ ar2Handle->searchSize = AR2_DEFAULT_SEARCH_SIZE;
+ ar2Handle->templateSize1 = AR2_DEFAULT_TS1;
+ ar2Handle->templateSize2 = AR2_DEFAULT_TS2;
+ ar2Handle->searchFeatureNum = AR2_DEFAULT_SEARCH_FEATURE_NUM;
+ if( ar2Handle->searchFeatureNum > AR2_SEARCH_FEATURE_MAX ) {
+ ar2Handle->searchFeatureNum = AR2_SEARCH_FEATURE_MAX;
+ }
+ ar2Handle->simThresh = AR2_DEFAULT_SIM_THRESH;
+ ar2Handle->trackingThresh = AR2_DEFAULT_TRACKING_THRESH;
+
+
+
+ if( threadNum == AR2_TRACKING_DEFAULT_THREAD_NUM ) {
+ threadNum = threadGetCPU();
+ }
+ if( threadNum < 1 ) {
+ threadNum = 1;
+ }
+ if( threadNum > AR2_THREAD_MAX ) {
+ threadNum = AR2_THREAD_MAX;
+ }
+ ar2Handle->threadNum = threadNum;
+ ARLOGi("Tracking thread = %d\n", threadNum);
+ for( i = 0; i < ar2Handle->threadNum; i++ ) {
+ arMalloc( ar2Handle->arg[i].mfImage, ARUint8, xsize*ysize );
+ ar2Handle->arg[i].templ = NULL;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ ar2Handle->arg[i].templ2 = NULL;
+#endif
+ ar2Handle->threadHandle[i] = threadInit(i, &(ar2Handle->arg[i]), ar2Tracking2d);
+ }
+
+ return ar2Handle;
+}
+
+int ar2DeleteHandle( AR2HandleT **ar2Handle )
+{
+ int i;
+
+ if( *ar2Handle == NULL ) return -1;
+
+ for( i = 0; i < (*ar2Handle)->threadNum; i++ ) {
+ threadWaitQuit( (*ar2Handle)->threadHandle[i] );
+ threadFree( &((*ar2Handle)->threadHandle[i]) );
+ if( (*ar2Handle)->arg[i].mfImage != NULL ) free( (*ar2Handle)->arg[i].mfImage );
+ if( (*ar2Handle)->arg[i].templ != NULL ) ar2FreeTemplate( (*ar2Handle)->arg[i].templ );
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( (*ar2Handle)->arg[i].templ2 != NULL ) ar2FreeTemplate ( (*ar2Handle)->arg[i].templ2 );
+#endif
+ }
+
+ if( (*ar2Handle)->icpHandle != NULL ) icpDeleteHandle( &((*ar2Handle)->icpHandle) );
+ //if( (*ar2Handle)->cparamLT != NULL ) arParamLTFree( (*ar2Handle)->cparamLT );
+ free( *ar2Handle );
+ *ar2Handle = NULL;
+
+ return 0;
+}
+
+int ar2SetTrackingMode( AR2HandleT *ar2Handle, int trackingMode )
+{
+ if( ar2Handle == NULL ) return -1;
+ if( trackingMode == AR2_TRACKING_6DOF && ar2Handle->icpHandle == NULL ) return -1;
+ ar2Handle->trackingMode = trackingMode;
+ return 0;
+}
+
+int ar2GetTrackingMode( AR2HandleT *ar2Handle, int *trackingMode )
+{
+ if( ar2Handle == NULL ) return -1;
+ *trackingMode = ar2Handle->trackingMode;
+ return 0;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2SetBlurLevel( AR2HandleT *ar2Handle, int blurLevel )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->blurLevel = blurLevel;
+ return 0;
+}
+
+int ar2GetBlurLevel( AR2HandleT *ar2Handle, int *blurLevel )
+{
+ if( ar2Handle == NULL ) return -1;
+ *blurLevel = ar2Handle->blurLevel;
+ return 0;
+}
+
+int ar2SetBlurMethod( AR2HandleT *ar2Handle, int blurMethod )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->blurMethod = blurMethod;
+ return 0;
+}
+
+int ar2GetBlurMethod( AR2HandleT *ar2Handle, int *blurMethod )
+{
+ if( ar2Handle == NULL ) return -1;
+ *blurMethod = ar2Handle->blurMethod;
+ return 0;
+}
+#endif
+
+int ar2SetSimThresh( AR2HandleT *ar2Handle, float simThresh )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->simThresh = simThresh;
+ return 0;
+}
+
+int ar2GetSimThresh( AR2HandleT *ar2Handle, float *simThresh )
+{
+ if( ar2Handle == NULL ) return -1;
+ *simThresh = ar2Handle->simThresh;
+ return 0;
+}
+
+int ar2SetTrackingThresh( AR2HandleT *ar2Handle, float trackingThresh )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->trackingThresh = trackingThresh;
+ return 0;
+}
+
+int ar2GetTrackingThresh( AR2HandleT *ar2Handle, float *trackingThresh )
+{
+ if( ar2Handle == NULL ) return -1;
+ *trackingThresh = ar2Handle->trackingThresh;
+ return 0;
+}
+
+int ar2SetSearchSize( AR2HandleT *ar2Handle, int searchSize )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->searchSize = searchSize;
+ return 0;
+}
+
+int ar2GetSearchSize( AR2HandleT *ar2Handle, int *searchSize )
+{
+ if( ar2Handle == NULL ) return -1;
+ *searchSize = ar2Handle->searchSize;
+ return 0;
+}
+
+int ar2SetSearchFeatureNum( AR2HandleT *ar2Handle, int searchFeatureNum )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->searchFeatureNum = searchFeatureNum;
+ if( ar2Handle->searchFeatureNum > AR2_SEARCH_FEATURE_MAX ) {
+ ar2Handle->searchFeatureNum = AR2_SEARCH_FEATURE_MAX;
+ }
+ if( ar2Handle->searchFeatureNum < 3 ) {
+ ar2Handle->searchFeatureNum = 3;
+ }
+ return 0;
+}
+
+int ar2GetSearchFeatureNum( AR2HandleT *ar2Handle, int *searchFeatureNum )
+{
+ if( ar2Handle == NULL ) return -1;
+ *searchFeatureNum = ar2Handle->searchFeatureNum;
+ return 0;
+}
+
+int ar2SetTemplateSize1( AR2HandleT *ar2Handle, int templateSize1 )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->templateSize1 = templateSize1;
+ return 0;
+}
+
+int ar2GetTemplateSize1( AR2HandleT *ar2Handle, int *templateSize1 )
+{
+ if( ar2Handle == NULL ) return -1;
+ *templateSize1 = ar2Handle->templateSize1;
+ return 0;
+}
+
+int ar2SetTemplateSize2( AR2HandleT *ar2Handle, int templateSize2 )
+{
+ if( ar2Handle == NULL ) return -1;
+ ar2Handle->templateSize2 = templateSize2;
+ return 0;
+}
+
+int ar2GetTemplateSize2( AR2HandleT *ar2Handle, int *templateSize2 )
+{
+ if( ar2Handle == NULL ) return -1;
+ *templateSize2 = ar2Handle->templateSize2;
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/imageSet.c b/ARToolKitUWP/ARToolKit5/src/AR2/imageSet.c
new file mode 100644
index 0000000..548232d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/imageSet.c
@@ -0,0 +1,547 @@
+/*
+ * AR2/imageSet.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#ifdef _WIN32
+# define lroundf(x) ((x)>=0.0f?(long)((x)+0.5f):(long)((x)-0.5f))
+#endif
+#include
+#include
+
+static AR2ImageT *ar2GenImageLayer1 ( ARUint8 *image, int xsize, int ysize, int nc, float srcdpi, float dstdpi );
+static AR2ImageT *ar2GenImageLayer2 ( AR2ImageT *src, float dstdpi );
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static void defocus_image ( ARUint8 *img, int xsize, int ysize, int n );
+#endif
+static AR2ImageSetT *ar2ReadImageSetOld( FILE *fp );
+
+AR2ImageSetT *ar2GenImageSet( ARUint8 *image, int xsize, int ysize, int nc, float dpi, float dpi_list[], int dpi_num )
+{
+ AR2ImageSetT *imageSet;
+ int i;
+
+ if( nc != 1 && nc != 3 ) return NULL;
+ if( dpi_num <= 0 ) return NULL;
+ if( dpi_list[0] > dpi ) return NULL;
+ for( i = 1; i < dpi_num; i++ ) {
+ if( dpi_list[i] > dpi_list[0] ) return NULL;
+ }
+
+ arMalloc( imageSet, AR2ImageSetT, 1 );
+ imageSet->num = dpi_num;
+ arMalloc( imageSet->scale, AR2ImageT*, imageSet->num );
+
+ imageSet->scale[0] = ar2GenImageLayer1( image, xsize, ysize, nc, dpi, dpi_list[0] );
+ for( i = 1; i < dpi_num; i++ ) {
+ imageSet->scale[i] = ar2GenImageLayer2( imageSet->scale[0], dpi_list[i] );
+ }
+
+ return imageSet;
+}
+
+AR2ImageSetT *ar2ReadImageSet( char *filename )
+{
+ FILE *fp;
+ AR2JpegImageT *jpgImage;
+ AR2ImageSetT *imageSet;
+ float dpi;
+ int i, k1;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ int j, k2;
+ ARUint *p1, *p2;
+#endif
+ size_t len;
+ const char ext[] = ".iset";
+ char *buf;
+
+ len = strlen(filename) + strlen(ext) + 1; // +1 for nul terminator.
+ arMalloc(buf, char, len);
+ sprintf(buf, "%s%s", filename, ext);
+ fp = fopen(buf, "rb");
+ free(buf);
+ if (!fp) {
+ ARLOGe("Error: unable to open file '%s%s' for reading.\n", filename, ext);
+ return (NULL);
+ }
+
+ arMalloc( imageSet, AR2ImageSetT, 1 );
+
+ if( fread(&(imageSet->num), sizeof(imageSet->num), 1, fp) != 1 || imageSet->num <= 0) {
+ ARLOGe("Error reading imageSet.\n");
+ goto bail;
+ }
+ ARLOGi("Imageset contains %d images.\n", imageSet->num);
+ arMalloc( imageSet->scale, AR2ImageT*, imageSet->num );
+
+ arMalloc( imageSet->scale[0], AR2ImageT, 1 );
+ jpgImage = ar2ReadJpegImage2(fp); // Caller must free result.
+ if( jpgImage == NULL || jpgImage->nc != 1 ) {
+ ARLOGw("Falling back to reading '%s%s' in ARToolKit v4.x format.\n", filename, ext);
+ free(imageSet->scale[0]);
+ free(imageSet->scale);
+ free(imageSet);
+
+ if( jpgImage == NULL ) {
+ rewind(fp);
+ return ar2ReadImageSetOld(fp);
+ }
+ free(jpgImage); //COVHI10396
+ fclose(fp);
+ return NULL;
+ }
+ imageSet->scale[0]->xsize = jpgImage->xsize;
+ imageSet->scale[0]->ysize = jpgImage->ysize;
+ imageSet->scale[0]->dpi = jpgImage->dpi; // The dpi value is not read correctly by jpeglib embedded in OpenCV 2.2.x.
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ imageSet->scale[0]->imgBWBlur[0] = jpgImage->image;
+ // Create the blurred images.
+ for( j = 1; j < AR2_BLUR_IMAGE_MAX; j++ ) {
+ arMalloc( imageSet->scale[0]->imgBWBlur[j], ARUint8, imageSet->scale[0]->xsize * imageSet->scale[0]->ysize);
+ p1 = dst->imgBWBlur[0];
+ p2 = dst->imgBWBlur[i];
+ for( k1 = 0; k1 < imageSet->scale[0]->xsize * imageSet->scale[0]->ysize; k1++ ) *(p2++) = *(p1++);
+ defocus_image( imageSet->scale[0]->imgBWBlur[j], imageSet->scale[0]->xsize, imageSet->scale[0]->ysize, 3 );
+ }
+#else
+ imageSet->scale[0]->imgBW = jpgImage->image;
+#endif
+ free(jpgImage);
+
+ // Minify for the other scales.
+ // First, find the list of scales we wrote into the file.
+ fseek(fp, (long)(-(int)sizeof(dpi)*(imageSet->num - 1)), SEEK_END);
+ for( i = 1; i < imageSet->num; i++ ) {
+
+ if( fread(&dpi, sizeof(dpi), 1, fp) != 1 ) {
+ for( k1 = 0; k1 < i; k1++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( k2 = 0; k2 < AR2_BLUR_IMAGE_MAX; k2++ ) free(imageSet->scale[k1]->imgBWBlur[k2]);
+#else
+ free(imageSet->scale[k1]->imgBW);
+#endif
+ free(imageSet->scale[k1]);
+ }
+ goto bail1;
+ }
+
+ imageSet->scale[i] = ar2GenImageLayer2( imageSet->scale[0], dpi );
+ if( imageSet->scale[i] == NULL ) {
+ for( k1 = 0; k1 < i; k1++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( k2 = 0; k2 < AR2_BLUR_IMAGE_MAX; k2++ ) free(imageSet->scale[k1]->imgBWBlur[k2]);
+#else
+ free(imageSet->scale[k1]->imgBW);
+#endif
+ free(imageSet->scale[k1]);
+ }
+ goto bail1;
+ }
+ }
+
+ fclose(fp);
+
+ return imageSet;
+
+
+bail1:
+ free(imageSet->scale);
+bail:
+ free(imageSet);
+ fclose(fp);
+ return NULL;
+}
+
+int ar2WriteImageSet( char *filename, AR2ImageSetT *imageSet )
+{
+ FILE *fp;
+ AR2JpegImageT jpegImage;
+ int i;
+ size_t len;
+ const char ext[] = ".iset";
+ char *buf;
+
+ len = strlen(filename) + strlen(ext) + 1; // +1 for nul terminator.
+ arMalloc(buf, char, len);
+ sprintf(buf, "%s%s", filename, ext);
+ if( (fp=fopen(buf, "wb")) == NULL ) {
+ ARLOGe("Error: unable to open file '%s' for writing.\n", buf);
+ free(buf);
+ return (-1);
+ }
+ free(buf);
+
+ if( fwrite(&(imageSet->num), sizeof(imageSet->num), 1, fp) != 1 ) goto bailBadWrite;
+
+ jpegImage.xsize = imageSet->scale[0]->xsize;
+ jpegImage.ysize = imageSet->scale[0]->ysize;
+ jpegImage.dpi = imageSet->scale[0]->dpi;
+ jpegImage.nc = 1;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ jpegImage.image = imageSet->scale[0]->imgBWBlur[0];
+#else
+ jpegImage.image = imageSet->scale[0]->imgBW;
+#endif
+
+ if( ar2WriteJpegImage2(fp, &jpegImage, AR2_DEFAULT_JPEG_IMAGE_QUALITY) < 0 ) goto bailBadWrite;
+
+ for( i = 1; i < imageSet->num; i++ ) {
+ if( fwrite(&(imageSet->scale[i]->dpi), sizeof(imageSet->scale[i]->dpi), 1, fp) != 1 ) goto bailBadWrite;
+ }
+
+ fclose(fp);
+ return 0;
+
+bailBadWrite:
+ ARLOGe("Error saving image set: error writing data.\n");
+ fclose(fp);
+ return (-1);
+}
+
+int ar2FreeImageSet( AR2ImageSetT **imageSet )
+{
+ int i;
+
+ if( imageSet == NULL ) return -1;
+ if( *imageSet == NULL ) return -1;
+
+ for( i = 0; i < (*imageSet)->num; i++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( int j = 0; j < AR2_BLUR_IMAGE_MAX; j++ ) {
+ free( (*imageSet)->scale[i]->imgBWBlur[j] );
+ }
+#else
+ free( (*imageSet)->scale[i]->imgBW );
+#endif
+ free( (*imageSet)->scale[i] );
+ }
+ free( (*imageSet)->scale );
+ free( *imageSet );
+ *imageSet = NULL;
+
+ return 0;
+}
+
+static AR2ImageT *ar2GenImageLayer1( ARUint8 *image, int xsize, int ysize, int nc, float srcdpi, float dstdpi )
+{
+ AR2ImageT *dst;
+ ARUint8 *p1, *p2;
+ int wx, wy;
+ int sx, sy, ex, ey;
+ int ii, jj, iii, jjj;
+ int co, value;
+
+ wx = (int)lroundf(xsize * dstdpi / srcdpi);
+ wy = (int)lroundf(ysize * dstdpi / srcdpi);
+
+ arMalloc( dst, AR2ImageT, 1 );
+ dst->xsize = wx;
+ dst->ysize = wy;
+ dst->dpi = dstdpi;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( int i = 0; i < AR2_BLUR_IMAGE_MAX; i++ ) {
+ arMalloc( dst->imgWBlur[i], ARUint8, wx*wy );
+ }
+ p2 = dst->imgBWBlur[0];
+#else
+ arMalloc( dst->imgBW, ARUint8, wx*wy );
+ p2 = dst->imgBW;
+#endif
+
+ // Scale down, nearest neighbour.
+ for( jj = 0; jj < wy; jj++ ) {
+ sy = (int)lroundf( jj * srcdpi / dstdpi);
+ ey = (int)lroundf((jj+1) * srcdpi / dstdpi) - 1;
+ if( ey >= ysize ) ey = ysize - 1;
+ for( ii = 0; ii < wx; ii++ ) {
+ sx = (int)lroundf( ii * srcdpi / dstdpi);
+ ex = (int)lroundf((ii+1) * srcdpi / dstdpi) - 1;
+ if( ex >= xsize ) ex = xsize - 1;
+
+ co = value = 0;
+ if( nc == 1 ) {
+ for( jjj = sy; jjj <= ey; jjj++ ) {
+ p1 = &(image[(jjj*xsize+sx)*nc]);
+ for( iii = sx; iii <= ex; iii++ ) {
+ value += *(p1++);
+ co++;
+ }
+ }
+ }
+ else {
+ for( jjj = sy; jjj <= ey; jjj++ ) {
+ p1 = &(image[(jjj*xsize+sx)*nc]);
+ for( iii = sx; iii <= ex; iii++ ) {
+ value += *(p1++);
+ value += *(p1++);
+ value += *(p1++);
+ co+=3;
+ }
+ }
+ }
+ *(p2++) = value / co;
+ }
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( int i = 1; i < AR2_BLUR_IMAGE_MAX; i++ ) {
+ p1 = dst->imgBWBlue[0];
+ p2 = dst->imgBWBlue[i];
+ for( int j = 0; j < wx*wy; j++ ) *(p2++) = *(p1++);
+ defocus_image( dst->imgBWBlur[i], wx, wy, 2 );
+ }
+#else
+ //defocus_image( dst->imgBW, wx, wy, 3 );
+#endif
+
+ return dst;
+}
+
+static AR2ImageT *ar2GenImageLayer2( AR2ImageT *src, float dpi )
+{
+ AR2ImageT *dst;
+ ARUint8 *p1, *p2;
+ int wx, wy;
+ int sx, sy, ex, ey;
+ int ii, jj, iii, jjj;
+ int co, value;
+
+ wx = (int)lroundf(src->xsize * dpi / src->dpi);
+ wy = (int)lroundf(src->ysize * dpi / src->dpi);
+
+ arMalloc( dst, AR2ImageT, 1 );
+ dst->xsize = wx;
+ dst->ysize = wy;
+ dst->dpi = dpi;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( int i = 0; i < AR2_BLUR_IMAGE_MAX; i++ ) {
+ arMalloc( dst->imgBWBlur[i], ARUint8, wx*wy );
+ }
+ p2 = dst->imgBWBlue[0];
+#else
+ arMalloc( dst->imgBW, ARUint8, wx*wy );
+ p2 = dst->imgBW;
+#endif
+
+ for( jj = 0; jj < wy; jj++ ) {
+ sy = (int)lroundf( jj * src->dpi / dpi);
+ ey = (int)lroundf((jj+1) * src->dpi / dpi) - 1;
+ if( ey >= src->ysize ) ey = src->ysize - 1;
+ for( ii = 0; ii < wx; ii++ ) {
+ sx = (int)lroundf( ii * src->dpi / dpi);
+ ex = (int)lroundf((ii+1) * src->dpi / dpi) - 1;
+ if( ex >= src->xsize ) ex = src->xsize - 1;
+
+ co = value = 0;
+ for( jjj = sy; jjj <= ey; jjj++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ p1 = &(src->imgBWBlur[0][jjj*src->xsize+sx]);
+#else
+ p1 = &(src->imgBW[jjj*src->xsize+sx]);
+#endif
+ for( iii = sx; iii <= ex; iii++ ) {
+ value += *(p1++);
+ co++;
+ }
+ }
+ *(p2++) = value / co;
+ }
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ defocus_image( dst->imageBWBlur[0], wx, wy, 3 );
+ for( int i = 1; i < AR2_BLUR_IMAGE_MAX; i++ ) {
+ p1 = dst->imgBWBlue[0];
+ p2 = dst->imgBWBlue[i];
+ for( int j = 0; j < wx*wy; j++ ) *(p2++) = *(p1++);
+ defocus_image( dst->imgBWBlur[i], wx, wy, 2 );
+ }
+#else
+ //defocus_image( dst->imgBW, wx, wy, 3 );
+#endif
+
+ return dst;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static void defocus_image( ARUint8 *img, int xsize, int ysize, int n )
+{
+ ARUint8 *wimg;
+ int isize;
+ ARUint8 *p1, *p2;
+ int i, j, k, w;
+
+ isize = xsize * ysize;
+ arMalloc( wimg, ARUint8, xsize*ysize );
+
+ for( k = 0; k < n; k++ ) {
+ if( k%2 == 0 ) {
+ p1 = img;
+ p2 = wimg;
+ }
+ else {
+ p1 = wimg;
+ p2 = img;
+ }
+ for( j = 0; j < ysize; j++ ) {
+ for( i = 0; i < xsize; i++ ) {
+ if( i == 0 || j == 0 || i == xsize-1 || j == ysize-1 ) {
+ *(p2++) = *(p1++);
+ continue;
+ }
+
+ w = *(p1-xsize-1) + *(p1-xsize) + *(p1-xsize+1)
+ + *(p1-1) + *(p1) + *(p1+1)
+ + *(p1+xsize-1) + *(p1+xsize) + *(p1+xsize+1);
+ *(p2++) = w / 9;
+ p1++;
+ }
+ }
+ }
+
+ if( n%2 == 1 ) {
+ p1 = wimg;
+ p2 = img;
+ for( i = 0; i < xsize*ysize; i++ ) *(p2++) = *(p1++);
+ }
+
+ free(wimg);
+
+ return;
+}
+#endif
+
+static AR2ImageSetT *ar2ReadImageSetOld( FILE *fp )
+{
+ AR2ImageSetT *imageSet;
+ int i, k;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ int j, l;
+#endif
+
+ arMalloc( imageSet, AR2ImageSetT, 1 );
+
+ if( fread(&(imageSet->num), sizeof(imageSet->num), 1, fp) != 1 || imageSet->num <= 0) {
+ ARLOGe("Error reading imageSet.\n");
+ goto bail;
+ }
+
+ arMalloc( imageSet->scale, AR2ImageT*, imageSet->num );
+ for( i = 0; i < imageSet->num; i++ ) {
+ arMalloc( imageSet->scale[i], AR2ImageT, 1 );
+ }
+
+ for( i = 0; i < imageSet->num; i++ ) {
+ if( fread(&(imageSet->scale[i]->xsize), sizeof(imageSet->scale[i]->xsize), 1, fp) != 1 ) {
+ for( k = 0; k < i; k++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( l = 0; l < AR2_BLUR_IMAGE_MAX; l++) free(imageSet->scale[k]->imgBWBlur[l]);
+#else
+ free(imageSet->scale[k]->imgBW);
+#endif
+ }
+ for( k = 0; k < imageSet->num; k++ ) free(imageSet->scale[k]);
+ goto bail1;
+ }
+ if( fread(&(imageSet->scale[i]->ysize), sizeof(imageSet->scale[i]->ysize), 1, fp) != 1 ) {
+ for( k = 0; k < i; k++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( l = 0; l < AR2_BLUR_IMAGE_MAX; l++) free(imageSet->scale[k]->imgBWBlur[l]);
+#else
+ free(imageSet->scale[k]->imgBW);
+#endif
+ }
+ for( k = 0; k < imageSet->num; k++ ) free(imageSet->scale[k]);
+ goto bail1;
+ }
+ if( fread(&(imageSet->scale[i]->dpi), sizeof(imageSet->scale[i]->dpi), 1, fp) != 1 ) {
+ for( k = 0; k < i; k++ ) {
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( l = 0; l < AR2_BLUR_IMAGE_MAX; l++) free(imageSet->scale[k]->imgBWBlur[l]);
+#else
+ free(imageSet->scale[k]->imgBW);
+#endif
+ }
+ for( k = 0; k < imageSet->num; k++ ) free(imageSet->scale[k]);
+ goto bail1;
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( j = 0; j < AR2_BLUR_IMAGE_MAX; j++ ) {
+ arMalloc( imageSet->scale[i]->imgBWBlur[j], ARUint8, imageSet->scale[i]->xsize * imageSet->scale[i]->ysize);
+ }
+#else
+ arMalloc( imageSet->scale[i]->imgBW, ARUint8, imageSet->scale[i]->xsize * imageSet->scale[i]->ysize);
+#endif
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ for( j = 0; j < AR2_BLUR_IMAGE_MAX; j++ ) {
+ if( fread(imageSet->scale[i]->imgBWBlur[j], sizeof(ARUint8), imageSet->scale[i]->xsize * imageSet->scale[i]->ysize, fp)
+ != imageSet->scale[i]->xsize * imageSet->scale[i]->ysize ) {
+ for( k = 0; k <= i; k++ ) {
+ for( l = 0; l < AR2_BLUR_IMAGE_MAX; l++) free(imageSet->scale[k]->imgBWBlur[l]);
+ }
+ for( k = 0; k < imageSet->num; k++ ) free(imageSet->scale[k]);
+ goto bail1;
+ }
+ }
+#else
+ if( fread(imageSet->scale[i]->imgBW, sizeof(ARUint8), imageSet->scale[i]->xsize * imageSet->scale[i]->ysize, fp)
+ != imageSet->scale[i]->xsize * imageSet->scale[i]->ysize ) {
+ for( k = 0; k <= i; k++ ) {
+ free(imageSet->scale[k]->imgBW);
+ }
+ for( k = 0; k < imageSet->num; k++ ) free(imageSet->scale[k]);
+ goto bail1;
+ }
+#endif
+ }
+
+ fclose(fp);
+ return imageSet;
+
+bail1:
+ free(imageSet->scale);
+bail:
+ free(imageSet);
+ fclose(fp);
+ return NULL;
+}
+
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/jpeg.c b/ARToolKitUWP/ARToolKit5/src/AR2/jpeg.c
new file mode 100644
index 0000000..ad55698
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/jpeg.c
@@ -0,0 +1,301 @@
+/*
+ * AR2/jpeg.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include "jpeglib.h"
+#include
+#include
+
+struct my_error_mgr {
+ struct jpeg_error_mgr pub; /* "public" fields */
+ jmp_buf setjmp_buffer; /* for return to caller */
+};
+typedef struct my_error_mgr * my_error_ptr;
+
+static unsigned char *jpgread (FILE *fp, int *w, int *h, int *nc, float *dpi);
+static int jpgwrite (FILE *fp, unsigned char *image, int w, int h, int nc, float dpi, int quality);
+
+int ar2WriteJpegImage( const char *filename, const char *ext, AR2JpegImageT *jpegImage, int quality )
+{
+ FILE *fp;
+ int ret;
+ size_t len;
+ char *buf1;
+
+ len = strlen(filename) + strlen(ext) + 1;
+ arMalloc(buf1, char, len + 1); // +1 for nul terminator.
+ sprintf(buf1, "%s.%s", filename, ext);
+ fp = fopen(buf1, "wb");
+ if( fp == NULL ) {
+ ARLOGe("Error: Unable to open file '%s' for writing.\n", buf1);
+ free(buf1);
+ return -1;
+ }
+ free(buf1);
+
+ ret = ar2WriteJpegImage2( fp, jpegImage, quality );
+
+ fclose(fp);
+ return ret;
+}
+
+int ar2WriteJpegImage2( FILE *fp, AR2JpegImageT *jpegImage, int quality )
+{
+ return jpgwrite(fp, jpegImage->image, jpegImage->xsize, jpegImage->ysize, jpegImage->nc, jpegImage->dpi, quality);
+}
+
+AR2JpegImageT *ar2ReadJpegImage( const char *filename, const char *ext )
+{
+ FILE *fp;
+ AR2JpegImageT *jpegImage;
+ size_t len;
+ char *buf1;
+
+
+ len = strlen(filename) + strlen(ext) + 1;
+ arMalloc(buf1, char, len + 1); // +1 for nul terminator.
+ sprintf(buf1, "%s.%s", filename, ext);
+ fp = fopen(buf1, "rb");
+ if( fp == NULL ) {
+ ARLOGe("Error: Unable to open file '%s' for reading.\n", buf1);
+ free(buf1);
+ return (NULL);
+ }
+ free(buf1);
+
+ jpegImage = ar2ReadJpegImage2(fp);
+
+ fclose(fp);
+ return jpegImage;
+}
+
+AR2JpegImageT *ar2ReadJpegImage2( FILE *fp )
+{
+ AR2JpegImageT *jpegImage;
+
+ arMalloc( jpegImage, AR2JpegImageT, 1 );
+ jpegImage->image = jpgread(fp, &(jpegImage->xsize), &(jpegImage->ysize), &(jpegImage->nc), &(jpegImage->dpi));
+
+ if( jpegImage->image == NULL ) {
+ free( jpegImage );
+ return NULL;
+ }
+
+ return jpegImage;
+}
+
+int ar2FreeJpegImage( AR2JpegImageT **jpegImage )
+{
+ if( jpegImage == NULL ) return -1;
+ if( *jpegImage == NULL ) return -1;
+
+ free( (*jpegImage)->image );
+ free( (*jpegImage) );
+
+ *jpegImage = NULL;
+
+ return 0;
+}
+
+#define BUFFER_HEIGHT 5
+
+static void my_error_exit (j_common_ptr cinfo)
+{
+ /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
+ my_error_ptr myerr = (my_error_ptr) cinfo->err;
+
+ /* Always display the message. */
+ /* We could postpone this until after returning, if we chose. */
+ //(*cinfo->err->output_message) (cinfo);
+
+ /* Return control to the setjmp point */
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+static unsigned char *jpgread (FILE *fp, int *w, int *h, int *nc, float *dpi)
+{
+ struct jpeg_decompress_struct cinfo;
+ struct my_error_mgr jerr;
+ unsigned char *pixels;
+ unsigned char *buffer[BUFFER_HEIGHT];
+ int bytes_per_line;
+ int row;
+ int i;
+ int ret;
+
+ /* Initialize the JPEG decompression object with default error handling. */
+ memset(&cinfo, 0, sizeof(cinfo));
+
+ /* We set up the normal JPEG error routines, then override error_exit. */
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = my_error_exit;
+ /* Establish the setjmp return context for my_error_exit to use. */
+ if (setjmp(jerr.setjmp_buffer)) {
+ /* If we get here, the JPEG code has signaled an error.
+ * We need to clean up the JPEG object, close the input file, and return.
+ */
+ jpeg_destroy_decompress(&cinfo);
+ ARLOGe("Error reading JPEG file.\n");
+ return NULL;
+ }
+
+ jpeg_create_decompress(&cinfo);
+
+ /* Specify data source for decompression */
+ jpeg_stdio_src(&cinfo, fp);
+
+ /* Read file header, set default decompression parameters */
+ ret = jpeg_read_header(&cinfo, TRUE);
+ if( ret != 1 ) {
+ ARLOGe("Error reading JPEG file header.\n");
+ jpeg_destroy_decompress(&cinfo);
+ return NULL;
+ }
+
+ /* Start decompressor */
+ (void) jpeg_start_decompress(&cinfo);
+
+ /* Allocate image buffer */
+ bytes_per_line = cinfo.num_components * cinfo.image_width;
+ pixels = (unsigned char *)malloc(bytes_per_line * cinfo.image_height);
+ if (!pixels) {
+ ARLOGe("Out of memory!!\n");
+ jpeg_destroy_decompress(&cinfo);
+ return NULL;
+ }
+
+ row = 0;
+
+ /* Process data */
+ while (cinfo.output_scanline < cinfo.output_height) {
+ for (i=0; i 2 && cinfo.X_density == 0 && cinfo.Y_density == 0) { // Handle the case with some libjpeg versions where density in DPI is returned in the density_unit field.
+ *dpi = (float)(cinfo.density_unit);
+ } else {
+ *dpi = 0.0f;
+ }
+ }
+
+ return pixels;
+}
+
+static int jpgwrite (FILE *fp, unsigned char *image, int w, int h, int nc, float dpi, int quality)
+{
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ unsigned char *p;
+ int i, j;
+ JSAMPARRAY img;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+ jpeg_stdio_dest(&cinfo, fp);
+ cinfo.image_width = w;
+ cinfo.image_height = h;
+ if( nc == 1 ) {
+ cinfo.input_components = 1;
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ }
+ else if( nc == 3 ) {
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ }
+ else return -1;
+ jpeg_set_defaults(&cinfo);
+ cinfo.density_unit = 1;
+ cinfo.X_density = (UINT16)dpi;
+ cinfo.Y_density = (UINT16)dpi;
+ cinfo.write_JFIF_header = 1;
+
+ if( quality < 0 ) quality = 0;
+ if( quality > 100 ) quality = 100;
+ jpeg_set_quality(&cinfo, quality, TRUE);
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+ p = image;
+ img = (JSAMPARRAY) malloc(sizeof(JSAMPROW) * h);
+ for (i = 0; i < h; i++) {
+ img[i] = (JSAMPROW) malloc(sizeof(JSAMPLE) * nc * w);
+ if( nc == 1 ) {
+ for (j = 0; j < w; j++) {
+ img[i][j] = *(p++);
+ }
+ }
+ else if( nc == 3 ) {
+ for (j = 0; j < w; j++) {
+ img[i][j*3+0] = *(p++);
+ img[i][j*3+1] = *(p++);
+ img[i][j*3+2] = *(p++);
+ }
+ }
+ }
+ jpeg_write_scanlines(&cinfo, img, h);
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ for (i = 0; i < h; i++) free(img[i]);
+ free(img);
+
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/marker.c b/ARToolKitUWP/ARToolKit5/src/AR2/marker.c
new file mode 100644
index 0000000..a03a81b
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/marker.c
@@ -0,0 +1,158 @@
+/*
+ * AR2/marker.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+static char *get_buff( char *buf, int n, FILE *fp );
+
+int ar2FreeMarkerSet( AR2MarkerSetT **markerSet )
+{
+ if( *markerSet == NULL ) return -1;
+
+ free( (*markerSet)->marker );
+ free( *markerSet );
+ *markerSet = NULL;
+
+ return 0;
+}
+
+AR2MarkerSetT *ar2ReadMarkerSet( char *filename, char *ext, ARPattHandle *pattHandle )
+{
+ //COVHI10394
+ FILE *fp = NULL;
+ AR2MarkerSetT *markerSet = NULL;
+ char buf[256], buf1[256]/*, buf2[256]*/;
+ int i, j;
+
+ char namebuf[512];
+ sprintf(namebuf, "%s.%s", filename, ext);
+ if( (fp=fopen(namebuf, "r")) == NULL ) return NULL;
+
+ arMalloc( markerSet, AR2MarkerSetT, 1 );
+
+ if( get_buff(buf, 256, fp) == NULL ) {
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ if( sscanf(buf, "%d", &(markerSet->num)) != 1 ) {
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ if( markerSet->num <= 0 ) {
+ free(markerSet);
+ markerSet = NULL;
+ goto done;
+ }
+
+ arMalloc( markerSet->marker, AR2MarkerT, markerSet->num );
+
+ for( i = 0; i < markerSet->num; i++ ) {
+ if( get_buff(buf, 256, fp) == NULL ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ if( sscanf(buf, "%s", buf1) != 1 ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ //ar2UtilDivideExt(buf1, buf, buf2);
+ if( (markerSet->marker[i].pattId = arPattLoad(pattHandle, buf1)) < 0 ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+
+ if( get_buff(buf, 256, fp) == NULL ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ if( sscanf(buf, "%f", &(markerSet->marker[i].width)) != 1 ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+
+ for( j = 0; j < 3; j++ ) {
+ if( get_buff(buf, 256, fp) == NULL ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ if( sscanf(buf, "%f %f %f %f",
+ &(markerSet->marker[i].transI2M[j][0]),
+ &(markerSet->marker[i].transI2M[j][1]),
+ &(markerSet->marker[i].transI2M[j][2]),
+ &(markerSet->marker[i].transI2M[j][3])) != 4 ) {
+ free( markerSet->marker );
+ free( markerSet );
+ markerSet = NULL;
+ goto done;
+ }
+ }
+ }
+
+done:
+ fclose(fp);
+ return markerSet;
+}
+
+static char *get_buff( char *buf, int n, FILE *fp )
+{
+ char *ret;
+
+ for(;;) {
+ ret = fgets( buf, n, fp );
+ if( ret == NULL ) return(NULL);
+ if( buf[0] != '\n' && buf[0] != '#' ) return(ret);
+ }
+}
+
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/matching.c b/ARToolKitUWP/ARToolKit5/src/AR2/matching.c
new file mode 100644
index 0000000..f9b9e32
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/matching.c
@@ -0,0 +1,498 @@
+/*
+ * AR2/matching.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define USE_SEARCH1 1
+#define USE_SEARCH2 1
+#define USE_SEARCH3 1
+
+#define SKIP_INTERVAL 3
+#define KEEP_NUM 3
+
+
+static int ar2GetBestMatchingSubFine ( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2TemplateT *mtemp, int sx, int sy, int *val);
+static void updateCandidate ( int x, int y, int wval,
+ int *keep_num, int cx[KEEP_NUM], int cy[KEEP_NUM], int cval[KEEP_NUM] );
+#if 1
+static int ar2GetBestMatchingSubFineOpt( ARUint8 *img, int xsize, int ysize, int sx1, int sy1, AR2TemplateT *mtemp,
+ ARUint32 *subImage1, ARUint32 *subImage2, int sx2, int sy2, int *val);
+#endif
+
+/*!
+ @function
+ @abstract Get best match for a candidate feature template.
+ @discussion
+ @param img Incoming image to match against.
+ @param mfImage Buffer same size as img, to provide working memory for status of matched features.
+ @param xsize Horizontal size of img and mfImage.
+ @param ysize Vertical size of img and mfImage.
+ @param pixFormat Pixel format of img.
+ @param mtemp Template undergoing matching.
+ @param rx search radius in x dimension.
+ @param ry search radius in y dimension.
+ @param search screen coordinates (second dimension is x and y) for up to three previous positions of this feature.
+ @param bx On return, x position of best candidate.
+ @param by On return, y position of best candidate.
+ @param val On return, the quality of the match of the best candidate.
+ @result -1 in case of error or no match, or 0 otherwise.
+ */
+
+int ar2GetBestMatching( ARUint8 *img, ARUint8 *mfImage, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2TemplateT *mtemp, int rx, int ry,
+ int search[3][2], int *bx, int *by, float *val)
+{
+ int search_flag[] = {USE_SEARCH1, USE_SEARCH2, USE_SEARCH3};
+ int px, py, sx, sy, ex, ey;
+ int yts1, yts2;
+ int keep_num;
+ int cx[KEEP_NUM], cy[KEEP_NUM];
+ int cval[KEEP_NUM];
+ int wval, wval2;
+ int i, j, l;
+ int ii;
+ int ret;
+ ARUint8 *pmf;
+#if 0
+#else
+ ARUint32 *subImage1, *p11, *p12, w1;
+ ARUint32 *subImage2, *p21, *p22, w2;
+ ARUint32 subImage11[AR2_TEMP_SCALE];
+ ARUint32 subImage21[AR2_TEMP_SCALE];
+ ARUint8 *p3, *p4;
+#endif
+
+ // First pass: initialise.
+ yts1 = mtemp->yts1;
+ yts2 = mtemp->yts2;
+ for( ii = 0; ii < 3; ii++ ) {
+ if( search_flag[ii] == 0 ) continue;
+ if( search[ii][0] < 0 ) break;
+
+ // "Snap" position to centre of grid square.
+ px = (search[ii][0]/(SKIP_INTERVAL + 1))*(SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1)/2;
+ py = (search[ii][1]/(SKIP_INTERVAL + 1))*(SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1)/2;
+
+ sx = px - rx; // Start position in x.
+ if( sx < 0 ) sx = 0;
+ ex = px + rx; // End position in x.
+ if( ex >= xsize ) ex = xsize - 1;
+
+ sy = py - ry; // Start position in y.
+ if( sy < 0 ) sy = 0;
+ ey = py + ry; // End position in y.
+ if( ey >= ysize ) ey = ysize - 1;
+
+ // Initialise mfImage by writing 0s into the potential search space.
+ for( j = sy; j <= ey; j++ ) {
+ pmf = &mfImage[j*xsize + sx];
+ for( i = sx; i <= ex; i++ ) {
+ *(pmf++) = 0;
+ }
+ }
+ }
+
+ // Second pass: get candidates.
+ keep_num = 0;
+ ret = 1;
+ for( ii = 0; ii < 3; ii++ ) {
+ if( search_flag[ii] == 0 ) continue;
+ if( search[ii][0] < 0 ) {
+ if( ret ) return -1; // If we haven't got at least one starting point for a search, bail out.
+ else break;
+ }
+
+ px = (search[ii][0]/(SKIP_INTERVAL + 1))*(SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1)/2;
+ py = (search[ii][1]/(SKIP_INTERVAL + 1))*(SKIP_INTERVAL + 1) + (SKIP_INTERVAL + 1)/2;
+
+ for( j = py - ry; j <= py + ry; j += SKIP_INTERVAL + 1 ) {
+ if( j - yts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( j + yts2*AR2_TEMP_SCALE >= ysize ) break;
+ for( i = px - rx; i <= px + rx; i += SKIP_INTERVAL + 1 ) {
+ if( i - mtemp->xts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( i + mtemp->xts2*AR2_TEMP_SCALE >= xsize ) break;
+ if( mfImage[j*xsize + i] ) continue; // Skip pixels already matched.
+ mfImage[j*xsize + i] = 1; // Mark this pixel as matched.
+ if( ar2GetBestMatchingSubFine(img, xsize, ysize, pixFormat, mtemp, i, j, &wval) < 0 ) {
+ continue;
+ }
+ ret = 0;
+ updateCandidate(i, j, wval, &keep_num, cx, cy, cval);
+ }
+ }
+ }
+
+ // Third pass. Determine best candidate.
+ wval2 = 0;
+ ret = -1;
+#if 0
+ for(l = 0; l < keep_num; l++) {
+ for( j = cy[l] - SKIP_INTERVAL; j <= cy[l] + SKIP_INTERVAL; j++ ) {
+ if( j - mtemp->yts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( j + mtemp->yts2*AR2_TEMP_SCALE >= ysize ) break;
+ for( i = cx[l] - SKIP_INTERVAL; i <= cx[l] + SKIP_INTERVAL; i++ ) {
+ if( i - mtemp->xts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( i + mtemp->xts2*AR2_TEMP_SCALE >= xsize ) break;
+ if( ar2GetBestMatchingSubFine(img, xsize, ysize, pixFormat, mtemp, i, j, &wval) < 0 ) {
+ continue;
+ }
+ if( wval > wval2 ) {
+ *bx = i;
+ *by = j;
+ wval2 = wval;
+ *val = (float)wval / 10000.0f;
+ ret = 0;
+ }
+ }
+ }
+ }
+#else
+ arMalloc( subImage1, ARUint32, ( (mtemp->xsize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2)) * ((mtemp->ysize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2) ) );
+ arMalloc( subImage2, ARUint32, ( (mtemp->xsize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2)) * ((mtemp->ysize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2) ) );
+
+ for(l = 0; l < keep_num; l++) {
+ if( mtemp->validNum != mtemp->xsize*mtemp->ysize
+ || (pixFormat != AR_PIXEL_FORMAT_MONO && pixFormat != AR_PIXEL_FORMAT_420v && pixFormat != AR_PIXEL_FORMAT_420f && pixFormat != AR_PIXEL_FORMAT_NV21)
+ || cy[l] - SKIP_INTERVAL - mtemp->yts1*AR2_TEMP_SCALE < 0
+ || cy[l] + SKIP_INTERVAL + mtemp->yts2*AR2_TEMP_SCALE >= ysize
+ || cx[l] - SKIP_INTERVAL - mtemp->xts1*AR2_TEMP_SCALE < 0
+ || cx[l] + SKIP_INTERVAL + mtemp->xts2*AR2_TEMP_SCALE >= xsize ) {
+ for( j = cy[l] - SKIP_INTERVAL; j <= cy[l] + SKIP_INTERVAL; j++ ) {
+ if( j - mtemp->yts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( j + mtemp->yts2*AR2_TEMP_SCALE >= ysize ) break;
+ for( i = cx[l] - SKIP_INTERVAL; i <= cx[l] + SKIP_INTERVAL; i++ ) {
+ if( i - mtemp->xts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( i + mtemp->xts2*AR2_TEMP_SCALE >= xsize ) break;
+ if( ar2GetBestMatchingSubFine(img, xsize, ysize, pixFormat, mtemp, i, j, &wval) < 0 ) {
+ continue;
+ }
+ if( wval > wval2 ) {
+ *bx = i;
+ *by = j;
+ wval2 = wval;
+ *val = (float)wval / 10000.0f;
+ ret = 0;
+ }
+ }
+ }
+ }
+ else {
+ // Optimised case for mono incoming image.
+ int px1 = (mtemp->xsize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2);
+ int py1 = mtemp->ysize*AR2_TEMP_SCALE + (SKIP_INTERVAL*2);
+ int px2 = cx[l] - SKIP_INTERVAL - mtemp->xts1*AR2_TEMP_SCALE;
+ int py2 = cy[l] - SKIP_INTERVAL - mtemp->yts1*AR2_TEMP_SCALE;
+ int px3 = px1 - AR2_TEMP_SCALE;
+ p11 = p12 = subImage1;
+ p21 = p22 = subImage2;
+ for( j = 0; j < AR2_TEMP_SCALE*px1; j++ ) {
+ *(p11++) = 0;
+ *(p21++) = 0;
+ }
+ p3 = p4 = &img[py2*xsize + px2];
+ for( j = 0; j < py1; j++ ) {
+ for( i = 0; i < AR2_TEMP_SCALE; i++ ) {
+ *(p11++) = 0;
+ *(p21++) = 0;
+ subImage11[i] = 0;
+ subImage21[i] = 0;
+ }
+ p12 += AR2_TEMP_SCALE;
+ p22 += AR2_TEMP_SCALE;
+ for( i = 0; i < px3; i++) {
+ w1 = subImage11[i%AR2_TEMP_SCALE] += (*p3);
+ w2 = subImage21[i%AR2_TEMP_SCALE] += (*p3)*(*p3);
+ p3++;
+ *(p11++) = w1 + *(p12++);
+ *(p21++) = w2 + *(p22++);
+ }
+ p3 = p4 += xsize;
+ }
+ for( j = 0; j < SKIP_INTERVAL*2 + 1; j++ ) {
+ for( i = 0; i < SKIP_INTERVAL*2 + 1; i++) {
+ if( ar2GetBestMatchingSubFineOpt(img, xsize, ysize, px2 + i, py2 + j,
+ mtemp, subImage1, subImage2, i + AR2_TEMP_SCALE, j + AR2_TEMP_SCALE, &wval) < 0 ) {
+ continue;
+ }
+ if( wval > wval2 ) {
+ *bx = cx[l] - SKIP_INTERVAL + i;
+ *by = cy[l] - SKIP_INTERVAL + j;
+ wval2 = wval;
+ *val = (float)wval / 10000;
+ ret = 0;
+ }
+ }
+ }
+ }
+ }
+ free(subImage1);
+ free(subImage2);
+#endif
+
+ return ret;
+}
+
+static int ar2GetBestMatchingSubFine( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2TemplateT *mtemp, int sx, int sy, int *val)
+{
+ ARUint16 *p1;
+ ARUint8 *p2;
+ int w;
+ int sum1, sum2, sum3;
+ int vlen;
+ int i, j;
+
+ p1 = mtemp->img1;
+ sum1 = sum2 = sum3 = 0;
+ if( pixFormat == AR_PIXEL_FORMAT_MONO || pixFormat == AR_PIXEL_FORMAT_420v || pixFormat == AR_PIXEL_FORMAT_420f || pixFormat == AR_PIXEL_FORMAT_NV21 ) {
+#if 0
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ sum1 += (*p2);
+ sum2 += (*p2) * (*p2);
+ sum3 += (*p2) * (*p1);
+ }
+ p2 += AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+#else
+ int ssx, eex, ssy, eey;
+ ARUint8 *p3;
+ ssx = -(mtemp->xts1);
+ eex = mtemp->xts2;
+ ssy = -(mtemp->yts1);
+ eey = mtemp->yts2;
+ p2 = p3 = &img[((sy + ssy*AR2_TEMP_SCALE)*xsize + sx + ssx*AR2_TEMP_SCALE)];
+ for( j = ssy; j <= eey; j++ ) {
+ for( i = ssx; i <= eex; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ sum1 += (*p2);
+ sum2 += (*p2) * (*p2);
+ sum3 += (*p2) * (*p1);
+ }
+ p2 += AR2_TEMP_SCALE;
+ p1++;
+ }
+ p2 = p3 += AR2_TEMP_SCALE*xsize; // i.e. p3 += AR2_TEMP_SCALE*xsize; p2 = p3;
+ }
+#endif
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGB || pixFormat == AR_PIXEL_FORMAT_BGR) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*3];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2 + 0) + *(p2 + 1) + *(p2 + 2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2 += 3*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGBA || pixFormat == AR_PIXEL_FORMAT_BGRA ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2 + 0) + *(p2 + 1) + *(p2 + 2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2 += 4*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_ARGB || pixFormat == AR_PIXEL_FORMAT_ABGR ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2 + 1) + *(p2 + 2) + *(p2 + 3))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2 += 4*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_2vuy ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *(p2 + 1);
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2 += 2*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_yuvs ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy + j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *p2;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2 += 2*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ }
+
+ sum3 -= sum1 * mtemp->sum / mtemp->validNum;
+ vlen = sum2 - sum1*sum1/mtemp->validNum;
+ if( vlen == 0 ) *val = 0;
+ else *val = sum3 * 100 / mtemp->vlen * 100 / (int)sqrtf((float)vlen);
+
+ return 0;
+}
+
+#if 1
+static int ar2GetBestMatchingSubFineOpt( ARUint8 *img, int xsize, int ysize, int sx1, int sy1, AR2TemplateT *mtemp,
+ ARUint32 *subImage1, ARUint32 *subImage2, int sx2, int sy2, int *val)
+{
+ ARUint16 *p1;
+ ARUint8 *p2, *p3;
+ int sum1, sum2, sum3;
+ int vlen;
+ int subImageXsize, px1, px2, py1, py2;
+ int i, j;
+
+ p1 = mtemp->img1;
+ sum3 = 0;
+ p2 = p3 = &img[sy1*xsize + sx1];
+ for( j = 0; j < mtemp->ysize; j++ ) {
+ for( i = 0; i < mtemp->xsize; i++ ) {
+ sum3 += (*p2) * *(p1++);
+ p2 += AR2_TEMP_SCALE;
+ }
+ p2 = p3 += AR2_TEMP_SCALE*xsize;
+ }
+
+ subImageXsize = (mtemp->xsize + 1)*AR2_TEMP_SCALE + (SKIP_INTERVAL*2);
+ px1 = sx2 + (mtemp->xsize - 1)*AR2_TEMP_SCALE;
+ px2 = sx2 - AR2_TEMP_SCALE;
+ py1 = (sy2 + (mtemp->ysize - 1)*AR2_TEMP_SCALE)*subImageXsize;
+ py2 = (sy2 - AR2_TEMP_SCALE)*subImageXsize;
+ sum1 = subImage1[py1 + px1]
+ + subImage1[py2 + px2]
+ - subImage1[py1 + px2]
+ - subImage1[py2 + px1];
+
+ sum2 = subImage2[py1 + px1]
+ + subImage2[py2 + px2]
+ - subImage2[py1 + px2]
+ - subImage2[py2 + px1];
+
+ sum3 -= sum1 * mtemp->sum / mtemp->validNum;
+ vlen = sum2 - sum1*sum1/mtemp->validNum;
+ if( vlen == 0 ) *val = 0;
+ else *val = sum3 * 100 / mtemp->vlen * 100 / (int)sqrtf((float)vlen);
+
+ return 0;
+}
+#endif
+
+static void updateCandidate( int x, int y, int wval,
+ int *keep_num, int cx[KEEP_NUM], int cy[KEEP_NUM], int cval[KEEP_NUM] )
+{
+ int l, m, n;
+
+ if( *keep_num == 0 ) {
+ cx[0] = x;
+ cy[0] = y;
+ cval[0] = wval;
+ *keep_num = 1;
+ return;
+ }
+
+ for(l = 0; l < *keep_num; l++) {
+ if( cval[l] < wval ) break;
+ }
+ if( l == *keep_num ) {
+ if( l < KEEP_NUM ) {
+ cx[l] = x;
+ cy[l] = y;
+ cval[l] = wval;
+ (*keep_num)++;
+ }
+ return;
+ }
+
+ if( *keep_num == KEEP_NUM ) {
+ m = KEEP_NUM - 1;
+ }
+ else {
+ m = *keep_num;
+ (*keep_num)++;
+ }
+
+ for( n = m; n > l; n-- ) {
+ cx[n] = cx[n - 1];
+ cy[n] = cy[n - 1];
+ cval[n] = cval[n - 1];
+ }
+ cx[n] = x;
+ cy[n] = y;
+ cval[n] = wval;
+
+ return;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/matching2.c b/ARToolKitUWP/ARToolKit5/src/AR2/matching2.c
new file mode 100644
index 0000000..afd9113
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/matching2.c
@@ -0,0 +1,498 @@
+/*
+ * AR2/matching2.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define USE_SEARCH1 1
+#define USE_SEARCH2 1
+#define USE_SEARCH3 1
+
+#define SKIP_INTERVAL 3
+#define KEEP_NUM 3
+
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static int ar2GetBestMatchingSubFine ( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2Template2T *mtemp, int sx, int sy, int *val);
+static int ar2GetBestMatchingSubFine2 ( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2Template2T *mtemp, int sx, int sy, int *val, int *blurLevel);
+static void updateCandidate ( int x, int y, int wval,
+ int *keep_num, int cx[KEEP_NUM], int cy[KEEP_NUM], int cval[KEEP_NUM] );
+#endif
+
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2GetBestMatching2( ARUint8 *img, ARUint8 *mfImage, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2Template2T *mtemp, int rx, int ry,
+ int search[3][2], int *bx, int *by, float *val, int *blurLevel)
+{
+ int search_flag[] = {USE_SEARCH1, USE_SEARCH2, USE_SEARCH3};
+ int px, py, sx, sy, ex, ey;
+ int yts1, yts2;
+ int keep_num;
+ int cx[KEEP_NUM], cy[KEEP_NUM];
+ int cval[KEEP_NUM];
+ int wval, wval2;
+ int wlevel;
+ int i, j, l;
+ int ii;
+ int ret;
+ ARUint8 *pmf;
+
+ keep_num = 0;
+
+ yts1 = mtemp->yts1;
+ yts2 = mtemp->yts2;
+
+ for( ii = 0; ii < 3; ii++ ) {
+ if( search_flag[ii] == 0 ) continue;
+ if( search[ii][0] < 0 ) break;
+
+ px = (search[ii][0]/(SKIP_INTERVAL+1))*(SKIP_INTERVAL+1) + (SKIP_INTERVAL+1)/2;
+ py = (search[ii][1]/(SKIP_INTERVAL+1))*(SKIP_INTERVAL+1) + (SKIP_INTERVAL+1)/2;
+
+ sx = px - rx;
+ if( sx < 0 ) sx = 0;
+ ex = px + rx;
+ if( ex >= xsize ) ex = xsize-1;
+
+ sy = py - ry;
+ if( sy < 0 ) sy = 0;
+ ey = py + ry;
+ if( ey >= ysize ) ey = ysize-1;
+
+ for( j = sy; j <= ey; j++ ) {
+ pmf = &mfImage[j*xsize+sx];
+ for( i = sx; i <= ex; i++ ) {
+ *(pmf++) = 0;
+ }
+ }
+ }
+
+ ret = 1;
+ for( ii = 0; ii < 3; ii++ ) {
+ if( search_flag[ii] == 0 ) continue;
+ if( search[ii][0] < 0 ) {
+ if( ret ) return -1;
+ else break;
+ }
+
+ px = (search[ii][0]/(SKIP_INTERVAL+1))*(SKIP_INTERVAL+1) + (SKIP_INTERVAL+1)/2;
+ py = (search[ii][1]/(SKIP_INTERVAL+1))*(SKIP_INTERVAL+1) + (SKIP_INTERVAL+1)/2;
+
+ for( j = py - ry; j <= py + ry; j += SKIP_INTERVAL+1 ) {
+ if( j - yts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( j + yts2*AR2_TEMP_SCALE >= ysize ) break;
+ for( i = px - rx; i <= px + rx; i += SKIP_INTERVAL+1 ) {
+ if( i - mtemp->xts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( i + mtemp->xts2*AR2_TEMP_SCALE >= xsize ) break;
+ if( mfImage[j*xsize+i] ) continue;
+ mfImage[j*xsize+i] = 1;
+ if( ar2GetBestMatchingSubFine(img,xsize,ysize,pixFormat,mtemp,i,j,&wval) < 0 ) {
+ continue;
+ }
+ ret = 0;
+ updateCandidate(i, j, wval, &keep_num, cx, cy, cval);
+ }
+ }
+ }
+
+ wval2 = 0;
+ ret = -1;
+ for(l = 0; l < keep_num; l++) {
+ for( j = cy[l]-SKIP_INTERVAL; j <= cy[l]+SKIP_INTERVAL; j++ ) {
+ if( j-mtemp->yts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( j+mtemp->yts2*AR2_TEMP_SCALE >= ysize ) break;
+ for( i = cx[l]-SKIP_INTERVAL; i <= cx[l]+SKIP_INTERVAL; i++ ) {
+ if( i-mtemp->xts1*AR2_TEMP_SCALE < 0 ) continue;
+ if( i+mtemp->xts2*AR2_TEMP_SCALE >= xsize ) break;
+ if( ar2GetBestMatchingSubFine2(img,xsize,ysize,pixFormat,mtemp,i,j,&wval, &wlevel) < 0 ) {
+ continue;
+ }
+ if( wval > wval2 ) {
+ *bx = i;
+ *by = j;
+ wval2 = wval;
+ *val = (float)wval / 10000;
+ *blurLevel = wlevel;
+ ret = 0;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+#else
+int ar2GetBestMatching2(void)
+{
+ return 0;
+}
+#endif
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static int ar2GetBestMatchingSubFine( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2Template2T *mtemp, int sx, int sy, int *val)
+{
+ ARUint16 *p1;
+ ARUint8 *p2;
+ int sum1, sum2, sum3;
+ int w, vlen;
+ int i, j;
+
+ p1 = mtemp->img1[1];
+ sum1 = sum2 = sum3 = 0;
+ if( pixFormat == AR_PIXEL_FORMAT_MONO || pixFormat == AR_PIXEL_FORMAT_420v || pixFormat == AR_PIXEL_FORMAT_420f || pixFormat == AR_PIXEL_FORMAT_NV21 ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ sum1 += (*p2);
+ sum2 += (*p2) * (*p2);
+ sum3 += (*p2) * (*p1);
+ }
+ p2+=AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGB || pixFormat == AR_PIXEL_FORMAT_BGR) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*3];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+0) + *(p2+1) + *(p2+2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2+=3*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGBA || pixFormat == AR_PIXEL_FORMAT_BGRA ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+0) + *(p2+1) + *(p2+2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2+=4*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ else if( pixFormat == AR_PIXEL_FORMAT_ARGB || pixFormat == AR_PIXEL_FORMAT_ABGR ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+1) + *(p2+2) + *(p2+3))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2+=4*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_2vuy ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *(p2+1);
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2+=2*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_yuvs ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p1 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *p2;
+ sum1 += w;
+ sum2 += w*w;
+ sum3 += w * (*p1);
+ }
+ p2+=2*AR2_TEMP_SCALE;
+ p1++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+
+ sum3 -= sum1 * mtemp->sum / mtemp->validNum;
+ vlen = sum2 - sum1*sum1/mtemp->validNum;
+ if( vlen == 0 ) *val = 0;
+ else *val = sum3 * 100 / mtemp->vlen[1] * 100 / (int)sqrtf((float)vlen);
+
+ return 0;
+}
+
+static int ar2GetBestMatchingSubFine2( ARUint8 *img, int xsize, int ysize, AR_PIXEL_FORMAT pixFormat,
+ AR2Template2T *mtemp, int sx, int sy, int *val, int *blurLevel)
+{
+ ARUint16 *p11, *p12, *p13;
+ ARUint8 *p2;
+ int sum1, sum2, sum31, sum32, sum33;
+ int w, vlen;
+ int val1, val2, val3;
+ int i, j, k;
+
+ p11 = mtemp->img1[0];
+ p12 = mtemp->img1[1];
+ p13 = mtemp->img1[2];
+ k = sum1 = sum2 = sum31 = sum32 = sum33 = 0;
+ if( pixFormat == AR_PIXEL_FORMAT_MONO || pixFormat == AR_PIXEL_FORMAT_420v || pixFormat == AR_PIXEL_FORMAT_420f || pixFormat == AR_PIXEL_FORMAT_NV21 ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ sum1 += (*p2);
+ sum2 += (*p2) * (*p2);
+ sum31 += (*p2) * (*p11);
+ sum32 += (*p2) * (*p12);
+ sum33 += (*p2) * (*p13);
+ k++;
+ }
+ p2+=AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGB || pixFormat == AR_PIXEL_FORMAT_BGR ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*3];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+0) + *(p2+1) + *(p2+2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum31 += w * (*p11);
+ sum32 += w * (*p12);
+ sum33 += w * (*p13);
+ k++;
+ }
+ p2+=3*AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_RGBA || pixFormat == AR_PIXEL_FORMAT_BGRA ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+0) + *(p2+1) + *(p2+2))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum31 += w * (*p11);
+ sum32 += w * (*p12);
+ sum33 += w * (*p13);
+ k++;
+ }
+ p2+=4*AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ else if( pixFormat == AR_PIXEL_FORMAT_ARGB || pixFormat == AR_PIXEL_FORMAT_ABGR ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*4];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = (*(p2+1) + *(p2+2) + *(p2+3))/3;
+ sum1 += w;
+ sum2 += w*w;
+ sum31 += w * (*p11);
+ sum32 += w * (*p12);
+ sum33 += w * (*p13);
+ k++;
+ }
+ p2+=4*AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_2vuy ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *(p2+1);
+ sum1 += w;
+ sum2 += w*w;
+ sum31 += w * (*p11);
+ sum32 += w * (*p12);
+ sum33 += w * (*p13);
+ k++;
+ }
+ p2+=2*AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+ else if( pixFormat == AR_PIXEL_FORMAT_yuvs ) {
+ for( j = -(mtemp->yts1); j <= mtemp->yts2; j++ ) {
+ p2 = &img[((sy+j*AR2_TEMP_SCALE)*xsize + sx - mtemp->xts1*AR2_TEMP_SCALE)*2];
+ for( i = -(mtemp->xts1); i <= mtemp->xts2; i++ ) {
+ if( *p11 != AR2_TEMPLATE_NULL_PIXEL ) {
+ w = *p2;
+ sum1 += w;
+ sum2 += w*w;
+ sum31 += w * (*p11);
+ sum32 += w * (*p12);
+ sum33 += w * (*p13);
+ k++;
+ }
+ p2+=2*AR2_TEMP_SCALE;
+ p11++;
+ p12++;
+ p13++;
+ }
+ }
+ if( k == 0 ) return -1;
+ }
+
+ vlen = sum2 - sum1*sum1/k;
+ if( vlen == 0 ) {
+ *val = 0;
+ return 0;
+ }
+
+ sum31 -= sum1 * mtemp->sum[0] / k;
+ sum32 -= sum1 * mtemp->sum[1] / k;
+ sum33 -= sum1 * mtemp->sum[2] / k;
+
+ vlen = (int)sqrtf((float)vlen);
+ val1 = sum31 * 100 / mtemp->vlen[0] * 100 / vlen;
+ val2 = sum32 * 100 / mtemp->vlen[1] * 100 / vlen;
+ val3 = sum33 * 100 / mtemp->vlen[2] * 100 / vlen;
+ if( val1 > val2 ) {
+ if( val1 > val3 ) { *val = val1; *blurLevel = 0;}
+ else { *val = val3; *blurLevel = 2;}
+ }
+ else {
+ if( val2 > val3 ) { *val = val2; *blurLevel = 1;}
+ else { *val = val3; *blurLevel = 2;}
+ }
+
+ return 0;
+}
+
+static void updateCandidate( int x, int y, int wval,
+ int *keep_num, int cx[KEEP_NUM], int cy[KEEP_NUM], int cval[KEEP_NUM] )
+{
+ int l, m, n;
+
+ if( *keep_num == 0 ) {
+ cx[0] = x;
+ cy[0] = y;
+ cval[0] = wval;
+ *keep_num = 1;
+ return;
+ }
+
+ for(l = 0; l < *keep_num; l++) {
+ if( cval[l] < wval ) break;
+ }
+ if( l == *keep_num ) {
+ if( l < KEEP_NUM ) {
+ cx[l] = x;
+ cy[l] = y;
+ cval[l] = wval;
+ (*keep_num)++;
+ }
+ return;
+ }
+
+ if( *keep_num == KEEP_NUM ) {
+ m = KEEP_NUM - 1;
+ }
+ else {
+ m = *keep_num;
+ (*keep_num)++;
+ }
+
+ for( n = m; n > l; n-- ) {
+ cx[n] = cx[n-1];
+ cy[n] = cy[n-1];
+ cval[n] = cval[n-1];
+ }
+ cx[n] = x;
+ cy[n] = y;
+ cval[n] = wval;
+
+ return;
+}
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/searchPoint.c b/ARToolKitUWP/ARToolKit5/src/AR2/searchPoint.c
new file mode 100644
index 0000000..375de2a
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/searchPoint.c
@@ -0,0 +1,91 @@
+/*
+ * AR2/searchPoint.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+void ar2GetSearchPoint( const ARParamLT *cparamLT,
+ const float trans1[3][4], const float trans2[3][4], const float trans3[3][4],
+ AR2FeatureCoordT *feature,
+ int search[3][2] )
+{
+ float mx, my;
+ float ox1, ox2, ox3;
+ float oy1, oy2, oy3;
+
+ mx = feature->mx;
+ my = feature->my;
+
+ if( trans1 == NULL
+ || ar2MarkerCoord2ScreenCoord( cparamLT, trans1, mx, my, &ox1, &oy1 ) < 0 ) {
+ goto nosearch1;
+ }
+ search[0][0] = (int)ox1;
+ search[0][1] = (int)oy1;
+
+ if( trans2 == NULL
+ || ar2MarkerCoord2ScreenCoord( cparamLT, trans2, mx, my, &ox2, &oy2 ) < 0 ) {
+ goto nosearch2;
+ }
+ search[1][0] = (int)(2*ox1 - ox2);
+ search[1][1] = (int)(2*oy1 - oy2);
+
+ if( trans3 == NULL
+ || ar2MarkerCoord2ScreenCoord( cparamLT, trans3, mx, my, &ox3, &oy3 ) < 0 ) {
+ goto nosearch3;
+ }
+ search[2][0] = (int)(3*ox1 - 3*ox2 + ox3);
+ search[2][1] = (int)(3*oy1 - 3*oy2 + oy3);
+
+ return;
+
+nosearch1:
+ search[0][0] = -1;
+ search[0][1] = -1;
+nosearch2:
+ search[1][0] = -1;
+ search[1][1] = -1;
+nosearch3:
+ search[2][0] = -1;
+ search[2][1] = -1;
+ return;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/selectTemplate.c b/ARToolKitUWP/ARToolKit5/src/AR2/selectTemplate.c
new file mode 100644
index 0000000..661a052
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/selectTemplate.c
@@ -0,0 +1,328 @@
+/*
+ * AR2/selectTemplate.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+static int ar2GetVectorAngle( float p1[2], float p2[2], float *psinf, float *pcosf );
+static float ar2GetTriangleArea( float p1[2], float p2[2], float p3[2] );
+static float ar2GetRegionArea( float pos[4][2], int q1, int r1, int r2 );
+
+
+int ar2GetResolution( const ARParamLT *cparamLT, const float trans[3][4], const float pos[2], float dpi[2] )
+{
+ if( cparamLT != NULL ) {
+ return ar2GetResolution2( &(cparamLT->param), trans, pos, dpi );
+ }
+ else {
+ return ar2GetResolution2( NULL, trans, pos, dpi );
+ }
+}
+
+int ar2GetResolution2( const ARParam *cparam, const float trans[3][4], const float pos[2], float dpi[2] )
+{
+ float mat[3][4];
+ float mx, my, hx, hy, h;
+ float x0, y0, x1, y1, x2, y2, d1, d2;
+
+ if( cparam != NULL ) {
+ arUtilMatMuldff( cparam->mat, trans, mat );
+
+ mx = pos[0];
+ my = pos[1];
+ hx = mat[0][0] * mx + mat[0][1] * my + mat[0][3];
+ hy = mat[1][0] * mx + mat[1][1] * my + mat[1][3];
+ h = mat[2][0] * mx + mat[2][1] * my + mat[2][3];
+ x0 = hx / h;
+ y0 = hy / h;
+
+ mx = pos[0] + 10.0F;
+ my = pos[1];
+ hx = mat[0][0] * mx + mat[0][1] * my + mat[0][3];
+ hy = mat[1][0] * mx + mat[1][1] * my + mat[1][3];
+ h = mat[2][0] * mx + mat[2][1] * my + mat[2][3];
+ x1 = hx / h;
+ y1 = hy / h;
+
+ mx = pos[0];
+ my = pos[1] + 10.0F;
+ hx = mat[0][0] * mx + mat[0][1] * my + mat[0][3];
+ hy = mat[1][0] * mx + mat[1][1] * my + mat[1][3];
+ h = mat[2][0] * mx + mat[2][1] * my + mat[2][3];
+ x2 = hx / h;
+ y2 = hy / h;
+ }
+ else {
+ mx = pos[0];
+ my = pos[1];
+ hx = trans[0][0] * mx + trans[0][1] * my + trans[0][3];
+ hy = trans[1][0] * mx + trans[1][1] * my + trans[1][3];
+ h = trans[2][0] * mx + trans[2][1] * my + trans[2][3];
+ x0 = hx / h;
+ y0 = hy / h;
+
+ mx = pos[0] + 10.0F;
+ my = pos[1];
+ hx = trans[0][0] * mx + trans[0][1] * my + trans[0][3];
+ hy = trans[1][0] * mx + trans[1][1] * my + trans[1][3];
+ h = trans[2][0] * mx + trans[2][1] * my + trans[2][3];
+ x1 = hx / h;
+ y1 = hy / h;
+
+ mx = pos[0];
+ my = pos[1] + 10.0F;
+ hx = trans[0][0] * mx + trans[0][1] * my + trans[0][3];
+ hy = trans[1][0] * mx + trans[1][1] * my + trans[1][3];
+ h = trans[2][0] * mx + trans[2][1] * my + trans[2][3];
+ x2 = hx / h;
+ y2 = hy / h;
+ }
+
+ d1 = (x1-x0)*(x1-x0) + (y1-y0)*(y1-y0);
+ d2 = (x2-x0)*(x2-x0) + (y2-y0)*(y2-y0);
+ if( d1 < d2 ) {
+ dpi[0] = sqrtf(d2) * 2.54F;
+ dpi[1] = sqrtf(d1) * 2.54F;
+ }
+ else {
+ dpi[0] = sqrtf(d1) * 2.54F;
+ dpi[1] = sqrtf(d2) * 2.54F;
+ }
+
+ return 0;
+}
+
+int ar2SelectTemplate( AR2TemplateCandidateT *candidate, AR2TemplateCandidateT *prevFeature, int num,
+ float pos[4][2], int xsize, int ysize )
+{
+ if( num < 0 ) return -1;
+
+ if( num == 0 ) {
+ float d, dmax;
+ int i, j;
+
+ dmax = 0.0f; j = -1;
+ for( i = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag != 0 ) continue;
+ if( candidate[i].sx < xsize/8 || candidate[i].sx > xsize*7/8
+ || candidate[i].sy < ysize/8 || candidate[i].sy > ysize*7/8 ) continue;
+
+ d = (candidate[i].sx - xsize/2)*(candidate[i].sx - xsize/2)
+ + (candidate[i].sy - ysize/2)*(candidate[i].sy - ysize/2);
+ if( d > dmax ) { dmax = d; j = i; }
+ }
+
+ if( j != -1 ) candidate[j].flag = 1;
+ return j;
+ }
+
+ else if( num == 1 ) {
+ float d, dmax;
+ int i, j;
+
+ dmax = 0.0f; j = -1;
+ for( i = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag != 0 ) continue;
+ if( candidate[i].sx < xsize/8 || candidate[i].sx > xsize*7/8
+ || candidate[i].sy < ysize/8 || candidate[i].sy > ysize*7/8 ) continue;
+
+ d = (candidate[i].sx - pos[0][0])*(candidate[i].sx - pos[0][0])
+ + (candidate[i].sy - pos[0][1])*(candidate[i].sy - pos[0][1]);
+ if( d > dmax ) { dmax = d; j = i; }
+ }
+
+ if( j != -1 ) candidate[j].flag = 1;
+ return j;
+ }
+
+ else if( num == 2 ) {
+ float d, dmax;
+ int i, j;
+
+ dmax = 0.0f; j = -1;
+ for( i = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag != 0 ) continue;
+ if( candidate[i].sx < xsize/8 || candidate[i].sx > xsize*7/8
+ || candidate[i].sy < ysize/8 || candidate[i].sy > ysize*7/8 ) continue;
+
+ d = ((candidate[i].sx - pos[0][0])*(pos[1][1] - pos[0][1])
+ - (candidate[i].sy - pos[0][1])*(pos[1][0] - pos[0][0]));
+ d = d * d;
+ if( d > dmax ) { dmax = d; j = i; }
+ }
+
+ if( j != -1 ) candidate[j].flag = 1;
+ return j;
+ }
+
+ else if( num == 3 ) {
+ float p2sinf, p2cosf, p3sinf, p3cosf, p4sinf, p4cosf;
+ float smax, s;
+ int q1, r1, r2;
+ int i, j;
+
+ ar2GetVectorAngle(pos[0], pos[1], &p2sinf, &p2cosf);
+ ar2GetVectorAngle(pos[0], pos[2], &p3sinf, &p3cosf);
+
+ j = -1;
+ smax = 0.0f;
+ for( i = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag != 0 ) continue;
+ if( candidate[i].sx < xsize/8 || candidate[i].sx > xsize*7/8
+ || candidate[i].sy < ysize/8 || candidate[i].sy > ysize*7/8 ) continue;
+
+ pos[3][0] = candidate[i].sx;
+ pos[3][1] = candidate[i].sy;
+ ar2GetVectorAngle(pos[0], pos[3], &p4sinf, &p4cosf);
+
+ if( ((p3sinf*p2cosf - p3cosf*p2sinf) >= 0.0F) && ((p4sinf*p2cosf - p4cosf*p2sinf) >= 0.0F) ) {
+ if( p4sinf*p3cosf - p4cosf*p3sinf >= 0.0F ) {
+ q1 = 1; r1 = 2; r2 = 3;
+ }
+ else {
+ q1 = 1; r1 = 3; r2 = 2;
+ }
+ }
+ else if( ((p4sinf*p3cosf - p4cosf*p3sinf) >= 0.0F) && ((p2sinf*p3cosf - p2cosf*p3sinf) >= 0.0F) ) {
+ if( p4sinf*p2cosf - p4cosf*p2sinf >= 0.0F ) {
+ q1 = 2; r1 = 1; r2 = 3;
+ }
+ else {
+ q1 = 2; r1 = 3; r2 = 1;
+ }
+ }
+ else if( ((p2sinf*p4cosf - p2cosf*p4sinf) >= 0.0F) && ((p3sinf*p4cosf - p3cosf*p4sinf) >= 0.0F) ) {
+ if( p3sinf*p2cosf - p3cosf*p2sinf >= 0.0F ) {
+ q1 = 3; r1 = 1; r2 = 2;
+ }
+ else {
+ q1 = 3; r1 = 2; r2 = 1;
+ }
+ }
+ else continue;
+
+ s = ar2GetRegionArea( pos, q1, r1, r2 );
+ if( s > smax ) { smax = s; j = i; }
+ }
+
+ if( j != -1 ) candidate[j].flag = 1;
+ return j;
+ }
+
+ else {
+ int i, j, k;
+ static int s = 0;
+
+ for( i = 0; prevFeature[i].flag != -1; i++ ) {
+ if( prevFeature[i].flag != 0 ) continue;
+ prevFeature[i].flag = 1;
+ for( j = 0; candidate[j].flag != -1; j++ ) {
+ if( candidate[j].flag == 0
+ && prevFeature[i].snum == candidate[j].snum
+ && prevFeature[i].level == candidate[j].level
+ && prevFeature[i].num == candidate[j].num ) break;
+ }
+ if( candidate[j].flag != -1 ) {
+ candidate[j].flag = 1;
+ return j;
+ }
+ }
+ prevFeature[0].flag = -1;
+
+ if( s == 0 ) srand((unsigned int)time(NULL));
+ s++;
+ if( s == 128 ) s = 0;
+
+ for( i = j = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag == 0 ) j++;
+ }
+ if( j == 0 ) return -1;
+
+ k = (int)((float )j * rand() / (RAND_MAX + 1.0F));
+ for( i = j = 0; candidate[i].flag != -1; i++ ) {
+ if( candidate[i].flag != 0 ) continue;
+ if( j == k ) {
+ candidate[i].flag = 1;
+ return i;
+ }
+ j++;
+ }
+ return -1;
+ }
+}
+
+static int ar2GetVectorAngle( float p1[2], float p2[2], float *psinf, float *pcosf )
+{
+ float l;
+
+ l = sqrtf( (p2[0]-p1[0])*(p2[0]-p1[0]) + (p2[1]-p1[1])*(p2[1]-p1[1]) );
+ if( l == 0.0F ) return -1;
+
+ *psinf = (p2[1] - p1[1]) / l;
+ *pcosf = (p2[0] - p1[0]) / l;
+ return 0;
+}
+
+static float ar2GetRegionArea( float pos[4][2], int q1, int r1, int r2 )
+{
+ float s;
+
+ s = ar2GetTriangleArea( pos[0], pos[q1], pos[r1] );
+ s += ar2GetTriangleArea( pos[0], pos[r1], pos[r2] );
+
+ return s;
+}
+
+static float ar2GetTriangleArea( float p1[2], float p2[2], float p3[2] )
+{
+ float x1, y1, x2, y2;
+ float s;
+
+ x1 = p2[0] - p1[0];
+ y1 = p2[1] - p1[1];
+ x2 = p3[0] - p1[0];
+ y2 = p3[1] - p1[1];
+
+ s = (x1 * y2 - x2 * y1) / 2.0f;
+ if( s < 0.0f ) s = -s;
+
+ return s;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/surface.c b/ARToolKitUWP/ARToolKit5/src/AR2/surface.c
new file mode 100644
index 0000000..bdc96ac
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/surface.c
@@ -0,0 +1,245 @@
+/*
+ * AR2/surface.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static char *get_buff( char *buf, int n, FILE *fp );
+
+AR2SurfaceSetT *ar2ReadSurfaceSet( const char *filename, const char *ext, ARPattHandle *pattHandle )
+{
+ AR2SurfaceSetT *surfaceSet;
+ FILE *fp = NULL;
+ int readMode;
+ char buf[256], name[256];
+ int i, j, k;
+
+ if( ext == NULL || *ext == '\0' || strcmp(ext,"fset") == 0 ) {
+ strncpy(name, filename, sizeof(name) - 1);
+ name[sizeof(name) - 1] = '\0';
+ readMode = 0;
+ }
+ else {
+ char namebuf[512];
+ sprintf(namebuf, "%s.%s", filename, ext);
+ if ((fp = fopen(namebuf,"r")) == NULL) {
+ ARLOGe("Error opening file '%s': ", filename);
+ ARLOGperror(NULL);
+ return (NULL);
+ }
+ readMode = 1;
+ }
+ arMalloc(surfaceSet, AR2SurfaceSetT, 1);
+
+ if( readMode ) {
+ if( get_buff(buf, 256, fp) == NULL ) {
+ fclose(fp);
+ free(surfaceSet);
+ return (NULL);
+ }
+ if( sscanf(buf, "%d", &i) != 1 ) {
+ fclose(fp);
+ free(surfaceSet);
+ return (NULL);
+ }
+ if( i < 1 ) {
+ fclose(fp);
+ free(surfaceSet);
+ return (NULL);
+ }
+ surfaceSet->num = i;
+ surfaceSet->contNum = 0;
+ }
+ else {
+ surfaceSet->num = 1;
+ surfaceSet->contNum = 0;
+ }
+ arMalloc(surfaceSet->surface, AR2SurfaceT, surfaceSet->num);
+
+ for( i = 0; i < surfaceSet->num; i++ ) {
+ ARLOGi("\n### Surface No.%d ###\n", i+1);
+ if( readMode ) {
+ if( get_buff(buf, 256, fp) == NULL ) break;
+ if( sscanf(buf, "%s", name) != 1 ) break;
+ ar2UtilRemoveExt( name );
+ }
+ ARLOGi(" Read ImageSet.\n");
+ surfaceSet->surface[i].imageSet = ar2ReadImageSet( name );
+ if( surfaceSet->surface[i].imageSet == NULL ) {
+ ARLOGe("Error opening file '%s.iset'.\n", name);
+ free(surfaceSet->surface);
+ free(surfaceSet);
+ if (fp) fclose(fp); //COVHI10426
+ return (NULL);
+ }
+ ARLOGi(" end.\n");
+
+ ARLOGi(" Read FeatureSet.\n");
+ surfaceSet->surface[i].featureSet = ar2ReadFeatureSet( name, "fset" );
+ if( surfaceSet->surface[i].featureSet == NULL ) {
+ ARLOGe("Error opening file '%s.fset'.\n", name);
+ ar2FreeImageSet(&surfaceSet->surface[i].imageSet);
+ free(surfaceSet->surface);
+ free(surfaceSet);
+ if (fp) fclose(fp); //COVHI10426
+ return (NULL);
+ }
+ ARLOGi(" end.\n");
+
+ if (pattHandle) {
+ ARLOGi(" Read MarkerSet.\n");
+ ar2UtilRemoveExt( name );
+ surfaceSet->surface[i].markerSet = ar2ReadMarkerSet( name, "mrk", pattHandle );
+ if( surfaceSet->surface[i].markerSet == NULL ) {
+ ARLOGe("Error opening file '%s.mrk'.\n", name);
+ ar2FreeFeatureSet(&surfaceSet->surface[i].featureSet);
+ ar2FreeImageSet(&surfaceSet->surface[i].imageSet);
+ free(surfaceSet->surface);
+ free(surfaceSet);
+ if (fp) fclose(fp); //COVHI10426
+ return (NULL);
+ }
+ ARLOGi(" end.\n");
+ } else {
+ surfaceSet->surface[i].markerSet = NULL;
+ }
+
+ if (readMode) {
+ if( get_buff(buf, 256, fp) == NULL ) break;
+ if( sscanf(buf, "%f %f %f %f",
+ &(surfaceSet->surface[i].trans[0][0]),
+ &(surfaceSet->surface[i].trans[0][1]),
+ &(surfaceSet->surface[i].trans[0][2]),
+ &(surfaceSet->surface[i].trans[0][3])) != 4 ) {
+ ARLOGe("Transformation matrix read error!!\n");
+ fclose(fp);
+ exit(0);
+ }
+ if( get_buff(buf, 256, fp) == NULL ) break;
+ if( sscanf(buf, "%f %f %f %f",
+ &(surfaceSet->surface[i].trans[1][0]),
+ &(surfaceSet->surface[i].trans[1][1]),
+ &(surfaceSet->surface[i].trans[1][2]),
+ &(surfaceSet->surface[i].trans[1][3])) != 4 ) {
+ ARLOGe("Transformation matrix read error!!\n");
+ fclose(fp);
+ exit(0);
+ }
+ if( get_buff(buf, 256, fp) == NULL ) break;
+ if( sscanf(buf, "%f %f %f %f",
+ &(surfaceSet->surface[i].trans[2][0]),
+ &(surfaceSet->surface[i].trans[2][1]),
+ &(surfaceSet->surface[i].trans[2][2]),
+ &(surfaceSet->surface[i].trans[2][3])) != 4 ) {
+ ARLOGe("Transformation matrix read error!!\n");
+ fclose(fp);
+ exit(0);
+ }
+ } else {
+ for( j = 0; j < 3; j++ ) {
+ for( k = 0; k < 4; k++ ) {
+ surfaceSet->surface[i].trans[j][k] = (j == k)? 1.0f: 0.0f;
+ }
+ }
+ }
+ arUtilMatInvf( (const float (*)[4])surfaceSet->surface[i].trans, surfaceSet->surface[i].itrans );
+
+ ar2UtilReplaceExt( name, 256, "jpg");
+ arMalloc( surfaceSet->surface[i].jpegName, char, 256);
+ strncpy( surfaceSet->surface[i].jpegName, name, 256 );
+ }
+
+ if (fp) fclose(fp); //COVHI10459
+
+ if (i < surfaceSet->num) exit(0);
+
+ return surfaceSet;
+}
+
+static char *get_buff( char *buf, int n, FILE *fp )
+{
+ char *ret;
+
+ for(;;) {
+ ret = fgets( buf, n, fp );
+ if( ret == NULL ) return(NULL);
+ if( buf[0] != '\n' && buf[0] != '#' ) return(ret);
+ }
+}
+
+int ar2FreeSurfaceSet( AR2SurfaceSetT **surfaceSet )
+{
+ int i;
+
+ if( *surfaceSet == NULL ) return -1;
+
+ for( i = 0; i < (*surfaceSet)->num; i++ ) {
+ ar2FreeImageSet( &((*surfaceSet)->surface[i].imageSet) );
+ ar2FreeFeatureSet( &((*surfaceSet)->surface[i].featureSet) );
+ if( (*surfaceSet)->surface[i].markerSet != NULL ) {
+ ar2FreeMarkerSet( &((*surfaceSet)->surface[i].markerSet) );
+ }
+ free( (*surfaceSet)->surface[i].jpegName );
+ }
+ free( (*surfaceSet)->surface );
+ free( *surfaceSet );
+ *surfaceSet = NULL;
+
+ return 0;
+}
+
+
+int ar2SetInitTrans( AR2SurfaceSetT *surfaceSet, float trans[3][4] )
+{
+ int i, j;
+
+ if( surfaceSet == NULL ) return -1;
+ surfaceSet->contNum = 1;
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) surfaceSet->trans1[j][i] = trans[j][i];
+ }
+ surfaceSet->prevFeature[0].flag = -1;
+
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/template.c b/ARToolKitUWP/ARToolKit5/src/AR2/template.c
new file mode 100644
index 0000000..c116c37
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/template.c
@@ -0,0 +1,342 @@
+/*
+ * AR2/template.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+AR2TemplateT *ar2GenTemplate( int ts1, int ts2 )
+#else
+AR2TemplateT *ar2GenTemplate( int ts1, int ts2 )
+#endif
+{
+ AR2TemplateT *templ;
+ int xsize, ysize;
+
+ arMalloc( templ, AR2TemplateT, 1 );
+ templ->xts1 = templ->yts1 = ts1;
+ templ->xts2 = templ->yts2 = ts2;
+
+ templ->xsize = xsize = templ->xts1 + templ->xts2 + 1;
+ templ->ysize = ysize = templ->yts1 + templ->yts2 + 1;
+ arMalloc( templ->img1, ARUint16, xsize*ysize );
+
+ return templ;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+AR2Template2T *ar2GenTemplate2( int ts1, int ts2 )
+{
+ AR2Template2T *templ2;
+ int xsize, ysize;
+
+ arMalloc( templ2, AR2Template2T, 1 );
+ templ2->xts1 = templ2->yts1 = ts1;
+ templ2->xts2 = templ2->yts2 = ts2;
+
+ templ2->xsize = xsize = templ2->xts1 + templ2->xts2 + 1;
+ templ2->ysize = ysize = templ2->yts1 + templ2->yts2 + 1;
+ arMalloc( templ2->img1[0], ARUint16, xsize*ysize );
+ arMalloc( templ2->img1[1], ARUint16, xsize*ysize );
+ arMalloc( templ2->img1[2], ARUint16, xsize*ysize );
+
+ return templ2;
+}
+#endif
+
+int ar2FreeTemplate( AR2TemplateT *templ )
+{
+ free( templ->img1 );
+ free( templ );
+
+ return 0;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2FreeTemplate2( AR2Template2T *templ2 )
+{
+ free( templ2->img1[0] );
+ free( templ2->img1[1] );
+ free( templ2->img1[2] );
+ free( templ2 );
+
+ return 0;
+}
+#endif
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2SetTemplateSub( const ARParamLT *cparamLT, const float trans[3][4], AR2ImageSetT *imageSet,
+ AR2FeaturePointsT *featurePoints, int num, int blurLevel,
+ AR2TemplateT *templ )
+#else
+int ar2SetTemplateSub( const ARParamLT *cparamLT, const float trans[3][4], AR2ImageSetT *imageSet,
+ AR2FeaturePointsT *featurePoints, int num,
+ AR2TemplateT *templ )
+#endif
+{
+ float mx, my;
+ float sx, sy;
+ float wtrans[3][4];
+ ARUint16 *img1;
+ int sum, sum2;
+ int vlen;
+ ARUint8 pixel;
+ int ix, iy;
+ int ix2, iy2;
+ int ret;
+ int i, j, k;
+
+ if( cparamLT != NULL ) {
+#ifdef ARDOUBLE_IS_FLOAT
+ arUtilMatMul( cparamLT->param.mat, trans, wtrans );
+#else
+ arUtilMatMuldff( cparamLT->param.mat, trans, wtrans );
+#endif
+
+ mx = featurePoints->coord[num].mx;
+ my = featurePoints->coord[num].my;
+ if( ar2MarkerCoord2ScreenCoord( NULL, (const float (*)[4])wtrans, mx, my, &mx, &my ) < 0 ) return -1;
+ if( arParamIdeal2ObservLTf( &cparamLT->paramLTf, mx, my, &sx, &sy ) < 0 ) return -1;
+ ix = (int)(sx + 0.5F);
+ iy = (int)(sy + 0.5F);
+
+ img1 = templ->img1;
+ sum = sum2 = 0;
+ k = 0;
+ iy2 = iy - (templ->yts1)*AR2_TEMP_SCALE;
+ for( j = -(templ->yts1); j <= templ->yts2; j++, iy2+=AR2_TEMP_SCALE ) {
+ ix2 = ix - (templ->xts1)*AR2_TEMP_SCALE;
+ for( i = -(templ->xts1); i <= templ->xts2; i++, ix2+=AR2_TEMP_SCALE ) {
+
+ if( arParamObserv2IdealLTf( &cparamLT->paramLTf, (float)ix2, (float)iy2, &sx, &sy) < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ continue;
+ }
+
+ ret = ar2GetImageValue( NULL, (const float (*)[4])wtrans, imageSet->scale[featurePoints->scale],
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ sx, sy, blurLevel, &pixel );
+#else
+ sx, sy, &pixel );
+#endif
+ if( ret < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ }
+ else {
+ *(img1++) = pixel;
+ sum += pixel;
+ sum2 += pixel*pixel;
+ k++;
+ }
+ }
+ }
+ }
+ else {
+ mx = featurePoints->coord[num].mx;
+ my = featurePoints->coord[num].my;
+ if( ar2MarkerCoord2ScreenCoord( NULL, trans, mx, my, &sx, &sy ) < 0 ) return -1;
+ ix = (int)(sx + 0.5F);
+ iy = (int)(sy + 0.5F);
+
+ img1 = templ->img1;
+ sum = sum2 = 0;
+ k = 0;
+ iy2 = iy - (templ->yts1)*AR2_TEMP_SCALE;
+ for( j = -(templ->yts1); j <= templ->yts2; j++, iy2+=AR2_TEMP_SCALE ) {
+ ix2 = ix - (templ->xts1)*AR2_TEMP_SCALE;
+ for( i = -(templ->xts1); i <= templ->xts2; i++, ix2+=AR2_TEMP_SCALE ) {
+
+ ret = ar2GetImageValue( NULL, trans, imageSet->scale[featurePoints->scale],
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ (float)ix2, (float)iy2, blurLevel, &pixel );
+#else
+ (float)ix2, (float)iy2, &pixel );
+#endif
+ if( ret < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ }
+ else {
+ *(img1++) = pixel;
+ sum += pixel;
+ sum2 += pixel*pixel;
+ k++;
+ }
+ }
+ }
+ }
+ if( k == 0 ) return -1;
+
+ vlen = sum2 - sum*sum/k;
+ templ->vlen = (int)sqrtf((float)vlen);
+ templ->sum = sum;
+ templ->validNum = k;
+
+ return 0;
+}
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+int ar2SetTemplate2Sub( const ARParamLT *cparamLT, const float trans[3][4], AR2ImageSetT *imageSet,
+ AR2FeaturePointsT *featurePoints, int num, int blurLevel,
+ AR2Template2T *templ2 )
+{
+ float mx, my;
+ float sx, sy;
+ float wtrans[3][4];
+ ARUint16 *img1, *img2, *img3;
+ int sum11, sum21, sum31;
+ int sum12, sum22, sum32;
+ int vlen1, vlen2, vlen3;
+ ARUint8 pixel1, pixel2, pixel3;
+ int ix, iy;
+ int ix2, iy2;
+ int ret;
+ int i, j, k;
+
+ if( cparamLT != NULL ) {
+ arUtilMatMul( cparamLT->param.mat, trans, wtrans );
+
+ mx = featurePoints->coord[num].mx;
+ my = featurePoints->coord[num].my;
+ if( ar2MarkerCoord2ScreenCoord( NULL, wtrans, mx, my, &mx, &my ) < 0 ) return -1;
+ if( arParamIdeal2ObservLTf( &cparamLT->paramLTf, mx, my, &sx, &sy ) < 0 ) return -1;
+ ix = (int)(sx + 0.5F);
+ iy = (int)(sy + 0.5F);
+
+ img1 = templ2->img1[0];
+ img2 = templ2->img1[1];
+ img3 = templ2->img1[2];
+ sum11 = sum21 = sum31 = 0;
+ sum12 = sum22 = sum32 = 0;
+ k = 0;
+ iy2 = iy - (templ2->yts1)*AR2_TEMP_SCALE;
+ for( j = -(templ2->yts1); j <= templ2->yts2; j++, iy2+=AR2_TEMP_SCALE ) {
+ ix2 = ix - (templ2->xts1)*AR2_TEMP_SCALE;
+ for( i = -(templ2->xts1); i <= templ2->xts2; i++, ix2+=AR2_TEMP_SCALE ) {
+
+ if( arParamObserv2IdealLTf( &cparamLT->paramLTf, ix2, iy2, &sx, &sy) < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img2++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img3++) = AR2_TEMPLATE_NULL_PIXEL;
+ continue;
+ }
+
+ ret = ar2GetImageValue2( NULL, wtrans, imageSet->scale[featurePoints->scale],
+ sx, sy, blurLevel, &pixel1, &pixel2, &pixel3 );
+ if( ret < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img2++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img3++) = AR2_TEMPLATE_NULL_PIXEL;
+ }
+ else {
+ *(img1++) = pixel1;
+ sum11 += pixel1;
+ sum12 += pixel1*pixel1;
+ *(img2++) = pixel2;
+ sum21 += pixel2;
+ sum22 += pixel2*pixel2;
+ *(img3++) = pixel3;
+ sum31 += pixel3;
+ sum32 += pixel3*pixel3;
+ k++;
+ }
+ }
+ }
+ }
+ else {
+ mx = featurePoints->coord[num].mx;
+ my = featurePoints->coord[num].my;
+ if( ar2MarkerCoord2ScreenCoord( NULL, trans, mx, my, &sx, &sy ) < 0 ) return -1;
+ ix = (int)(sx + 0.5F);
+ iy = (int)(sy + 0.5F);
+
+ img1 = templ2->img1[0];
+ img2 = templ2->img1[1];
+ img3 = templ2->img1[2];
+ sum11 = sum21 = sum31 = 0;
+ sum12 = sum22 = sum32 = 0;
+ k = 0;
+ iy2 = iy - (templ2->yts1)*AR2_TEMP_SCALE;
+ for( j = -(templ2->yts1); j <= templ2->yts2; j++, iy2+=AR2_TEMP_SCALE ) {
+ ix2 = ix - (templ2->xts1)*AR2_TEMP_SCALE;
+ for( i = -(templ2->xts1); i <= templ2->xts2; i++, ix2+=AR2_TEMP_SCALE ) {
+
+ ret = ar2GetImageValue2( NULL, trans, imageSet->scale[featurePoints->scale],
+ ix2, iy2, blurLevel, &pixel1, &pixel2, &pixel3 );
+ if( ret < 0 ) {
+ *(img1++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img2++) = AR2_TEMPLATE_NULL_PIXEL;
+ *(img3++) = AR2_TEMPLATE_NULL_PIXEL;
+ }
+ else {
+ *(img1++) = pixel1;
+ sum11 += pixel1;
+ sum12 += pixel1*pixel1;
+ *(img2++) = pixel2;
+ sum21 += pixel2;
+ sum22 += pixel2*pixel2;
+ *(img3++) = pixel3;
+ sum31 += pixel3;
+ sum32 += pixel3*pixel3;
+ k++;
+ }
+ }
+ }
+ }
+ if( k == 0 ) return -1;
+
+ vlen1 = sum12 - sum11*sum11/k;
+ vlen2 = sum22 - sum21*sum21/k;
+ vlen3 = sum32 - sum31*sum31/k;
+ templ2->vlen[0] = (int)sqrtf((float)vlen1);
+ templ2->vlen[1] = (int)sqrtf((float)vlen2);
+ templ2->vlen[2] = (int)sqrtf((float)vlen3);
+ templ2->sum[0] = sum11;
+ templ2->sum[0] = sum21;
+ templ2->sum[0] = sum31;
+ templ2->validNum = k;
+
+ return 0;
+}
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/tracking.c b/ARToolKitUWP/ARToolKit5/src/AR2/tracking.c
new file mode 100644
index 0000000..3be170d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/tracking.c
@@ -0,0 +1,828 @@
+/*
+ * AR2/tracking.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#ifndef _WIN32
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static float ar2GetTransMat ( ICPHandleT *icpHandle, float initConv[3][4],
+ float pos2d[][2], float pos3d[][3], int num, float conv[3][4], int robustMode );
+static float ar2GetTransMatHomography ( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num,
+ float conv[3][4], int robustMode, float inlierProb );
+static float ar2GetTransMatHomography2 ( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num, float conv[3][4] );
+static float ar2GetTransMatHomographyRobust ( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num, float conv[3][4], float inlierProb );
+static int extractVisibleFeatures ( const ARParamLT *cparamLT, const float trans1[][3][4], AR2SurfaceSetT *surfaceSet,
+ AR2TemplateCandidateT candidate[],
+ AR2TemplateCandidateT candidate2[] );
+static int extractVisibleFeaturesHomography( int xsize, int ysize, float trans1[][3][4], AR2SurfaceSetT *surfaceSet,
+ AR2TemplateCandidateT candidate[],
+ AR2TemplateCandidateT candidate2[] );
+static int getDeltaS( float H[8], float dU[], float J_U_H[][8], int n );
+
+
+int ar2Tracking( AR2HandleT *ar2Handle, AR2SurfaceSetT *surfaceSet, ARUint8 *dataPtr, float trans[3][4], float *err )
+{
+ AR2TemplateCandidateT *candidatePtr;
+ AR2TemplateCandidateT *cp[AR2_THREAD_MAX];
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ float aveBlur;
+#endif
+ int num, num2;
+ int i, j, k;
+
+ if (!ar2Handle || !surfaceSet || !dataPtr || !trans || !err) return (-1);
+
+ if( surfaceSet->contNum <= 0 ) {
+ ARLOGd("ar2Tracking() error: ar2SetInitTrans() must be called first.\n");
+ return -2;
+ }
+
+ *err = 0.0F;
+
+ for( i = 0; i < surfaceSet->num; i++ ) {
+ arUtilMatMulf( (const float (*)[4])surfaceSet->trans1, (const float (*)[4])surfaceSet->surface[i].trans, ar2Handle->wtrans1[i] );
+ if( surfaceSet->contNum > 1 ) arUtilMatMulf( (const float (*)[4])surfaceSet->trans2, (const float (*)[4])surfaceSet->surface[i].trans, ar2Handle->wtrans2[i] );
+ if( surfaceSet->contNum > 2 ) arUtilMatMulf( (const float (*)[4])surfaceSet->trans3, (const float (*)[4])surfaceSet->surface[i].trans, ar2Handle->wtrans3[i] );
+ }
+
+ if( ar2Handle->trackingMode == AR2_TRACKING_6DOF ) {
+ extractVisibleFeatures(ar2Handle->cparamLT, ar2Handle->wtrans1, surfaceSet, ar2Handle->candidate, ar2Handle->candidate2);
+ }
+ else {
+ extractVisibleFeaturesHomography(ar2Handle->xsize, ar2Handle->ysize, ar2Handle->wtrans1, surfaceSet, ar2Handle->candidate, ar2Handle->candidate2);
+ }
+
+ candidatePtr = ar2Handle->candidate;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ aveBlur = 0.0F;
+#endif
+ i = 0; // Counts up to searchFeatureNum.
+ num = 0;
+ while( i < ar2Handle->searchFeatureNum ) {
+ num2 = num;
+ for( j = 0; j < ar2Handle->threadNum; j++ ) {
+ if( i == ar2Handle->searchFeatureNum ) break;
+
+ k = ar2SelectTemplate( candidatePtr, surfaceSet->prevFeature, num2, ar2Handle->pos, ar2Handle->xsize, ar2Handle->ysize );
+ if( k < 0 ) {
+ if( candidatePtr == ar2Handle->candidate ) {
+ candidatePtr = ar2Handle->candidate2;
+ k = ar2SelectTemplate( candidatePtr, surfaceSet->prevFeature, num2, ar2Handle->pos, ar2Handle->xsize, ar2Handle->ysize );
+ if( k < 0 ) break; // PRL 2012-05-15: Give up if we can't select template from alternate candidate either.
+ }
+ else break;
+ }
+
+ cp[j] = &(candidatePtr[k]);
+ ar2Handle->pos[num2][0] = candidatePtr[k].sx;
+ ar2Handle->pos[num2][1] = candidatePtr[k].sy;
+ ar2Handle->arg[j].ar2Handle = ar2Handle;
+ ar2Handle->arg[j].surfaceSet = surfaceSet;
+ ar2Handle->arg[j].candidate = &(candidatePtr[k]);
+ ar2Handle->arg[j].dataPtr = dataPtr;
+
+ threadStartSignal( ar2Handle->threadHandle[j] );
+ num2++;
+ if( num2 == 5 ) num2 = num;
+ i++;
+ }
+ k = j;
+ if( k == 0 ) break;
+
+ for( j = 0; j < k; j++ ) {
+ threadEndWait( ar2Handle->threadHandle[j] );
+
+ if( ar2Handle->arg[j].ret == 0 && ar2Handle->arg[j].result.sim > ar2Handle->simThresh ) {
+ if( ar2Handle->trackingMode == AR2_TRACKING_6DOF ) {
+#ifdef ARDOUBLE_IS_FLOAT
+ arParamObserv2Ideal(ar2Handle->cparamLT->param.dist_factor,
+ ar2Handle->arg[j].result.pos2d[0], ar2Handle->arg[j].result.pos2d[1],
+ &ar2Handle->pos2d[num][0], &ar2Handle->pos2d[num][1], ar2Handle->cparamLT->param.dist_function_version);
+#else
+ ARdouble pos2d0, pos2d1;
+ arParamObserv2Ideal(ar2Handle->cparamLT->param.dist_factor,
+ (ARdouble)(ar2Handle->arg[j].result.pos2d[0]), (ARdouble)(ar2Handle->arg[j].result.pos2d[1]),
+ &pos2d0, &pos2d1, ar2Handle->cparamLT->param.dist_function_version);
+ ar2Handle->pos2d[num][0] = (float)pos2d0;
+ ar2Handle->pos2d[num][1] = (float)pos2d1;
+#endif
+ }
+ else {
+ ar2Handle->pos2d[num][0] = ar2Handle->arg[j].result.pos2d[0];
+ ar2Handle->pos2d[num][1] = ar2Handle->arg[j].result.pos2d[1];
+ }
+ ar2Handle->pos3d[num][0] = ar2Handle->arg[j].result.pos3d[0];
+ ar2Handle->pos3d[num][1] = ar2Handle->arg[j].result.pos3d[1];
+ ar2Handle->pos3d[num][2] = ar2Handle->arg[j].result.pos3d[2];
+ ar2Handle->pos[num][0] = cp[j]->sx;
+ ar2Handle->pos[num][1] = cp[j]->sy;
+ ar2Handle->usedFeature[num].snum = cp[j]->snum;
+ ar2Handle->usedFeature[num].level = cp[j]->level;
+ ar2Handle->usedFeature[num].num = cp[j]->num;
+ ar2Handle->usedFeature[num].flag = 0;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ aveBlur += ar2Handle->arg[j].result.blurLevel;
+#endif
+ num++;
+ }
+ }
+ }
+ for( i = 0; i < num; i++ ) {
+ surfaceSet->prevFeature[i] = ar2Handle->usedFeature[i];
+ }
+ surfaceSet->prevFeature[num].flag = -1;
+//ARLOG("------\nNum = %d\n", num);
+
+ if( ar2Handle->trackingMode == AR2_TRACKING_6DOF ) {
+ if( num < 3 ) {
+ surfaceSet->contNum = 0;
+ return -3;
+ }
+ *err = ar2GetTransMat( ar2Handle->icpHandle, surfaceSet->trans1, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 0 );
+//ARLOG("outlier 0%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ icpSetInlierProbability( ar2Handle->icpHandle, 0.8F );
+ *err = ar2GetTransMat( ar2Handle->icpHandle, trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1 );
+//ARLOG("outlier 20%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ icpSetInlierProbability( ar2Handle->icpHandle, 0.6F );
+ *err = ar2GetTransMat( ar2Handle->icpHandle, trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1 );
+//ARLOG("outlier 60%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ icpSetInlierProbability( ar2Handle->icpHandle, 0.4F );
+ *err = ar2GetTransMat( ar2Handle->icpHandle, trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1 );
+//ARLOG("outlier 60%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ icpSetInlierProbability( ar2Handle->icpHandle, 0.0F );
+ *err = ar2GetTransMat( ar2Handle->icpHandle, trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1 );
+//ARLOG("outlier Max: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ surfaceSet->contNum = 0;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( ar2Handle->blurMethod == AR2_ADAPTIVE_BLUR ) ar2Handle->blurLevel = AR2_DEFAULT_BLUR_LEVEL; // Reset the blurLevel.
+#endif
+ return -4;
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ if( num < 3 ) {
+ surfaceSet->contNum = 0;
+ return -3;
+ }
+ *err = ar2GetTransMatHomography( surfaceSet->trans1, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 0, 1.0F );
+//ARLOG("outlier 0%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ *err = ar2GetTransMatHomography( trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1, 0.8F );
+//ARLOG("outlier 20%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ *err = ar2GetTransMatHomography( trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1, 0.6F );
+//ARLOG("outlier 40%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ *err = ar2GetTransMatHomography( trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1, 0.4F );
+//ARLOG("outlier 60%%: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ *err = ar2GetTransMatHomography( trans, ar2Handle->pos2d, ar2Handle->pos3d, num, trans, 1, 0.0F );
+//ARLOG("outlier Max: err = %f, num = %d\n", *err, num);
+ if( *err > ar2Handle->trackingThresh ) {
+ surfaceSet->contNum = 0;
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( ar2Handle->blurMethod == AR2_ADAPTIVE_BLUR ) ar2Handle->blurLevel = AR2_DEFAULT_BLUR_LEVEL; // Reset the blurLevel.
+#endif
+ return -4;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( ar2Handle->blurMethod == AR2_ADAPTIVE_BLUR ) {
+ aveBlur = aveBlur/num + 0.5F;
+ ar2Handle->blurLevel += (int)aveBlur - 1;
+ if( ar2Handle->blurLevel < 1 ) ar2Handle->blurLevel = 1;
+ if( ar2Handle->blurLevel >= AR2_BLUR_IMAGE_MAX-1 ) ar2Handle->blurLevel = AR2_BLUR_IMAGE_MAX-2;
+ }
+#endif
+
+ surfaceSet->contNum++;
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) surfaceSet->trans3[j][i] = surfaceSet->trans2[j][i];
+ }
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) surfaceSet->trans2[j][i] = surfaceSet->trans1[j][i];
+ }
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) surfaceSet->trans1[j][i] = trans[j][i];
+ }
+
+ return 0;
+}
+
+static int extractVisibleFeatures(const ARParamLT *cparamLT, const float trans1[][3][4], AR2SurfaceSetT *surfaceSet,
+ AR2TemplateCandidateT candidate[], // candidates inside DPI range of [mindpi, maxdpi].
+ AR2TemplateCandidateT candidate2[]) // candidates inside DPI range of [mindpi/2, maxdpi*2].
+{
+ float trans2[3][4];
+ float sx, sy;
+ float wpos[2], w[2];
+ float vdir[3], vlen;
+ int xsize, ysize;
+ int i, j, k, l, l2;
+
+ xsize = cparamLT->param.xsize;
+ ysize = cparamLT->param.ysize;
+
+ l = l2 = 0;
+ for( i = 0; i < surfaceSet->num; i++ ) {
+ for(j=0;j<3;j++) for(k=0;k<4;k++) trans2[j][k] = trans1[i][j][k];
+
+ for( j = 0; j < surfaceSet->surface[i].featureSet->num; j++ ) {
+ for( k = 0; k < surfaceSet->surface[i].featureSet->list[j].num; k++ ) {
+
+ if( ar2MarkerCoord2ScreenCoord2( cparamLT, (const float (*)[4])trans2,
+ surfaceSet->surface[i].featureSet->list[j].coord[k].mx,
+ surfaceSet->surface[i].featureSet->list[j].coord[k].my,
+ &sx, &sy) < 0 ) continue;
+ if( sx < 0 || sx >= xsize ) continue;
+ if( sy < 0 || sy >= ysize ) continue;
+
+ vdir[0] = trans2[0][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[0][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[0][3];
+ vdir[1] = trans2[1][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[1][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[1][3];
+ vdir[2] = trans2[2][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[2][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[2][3];
+ vlen = sqrtf( vdir[0]*vdir[0] + vdir[1]*vdir[1] + vdir[2]*vdir[2] );
+ vdir[0] /= vlen;
+ vdir[1] /= vlen;
+ vdir[2] /= vlen;
+ if( vdir[0]*trans2[0][2] + vdir[1]*trans2[1][2] + vdir[2]*trans2[2][2] > -0.1f ) continue;
+
+ wpos[0] = surfaceSet->surface[i].featureSet->list[j].coord[k].mx;
+ wpos[1] = surfaceSet->surface[i].featureSet->list[j].coord[k].my;
+ ar2GetResolution( cparamLT, (const float (*)[4])trans2, wpos, w );
+ //if( w[0] <= surfaceSet->surface[i].featureSet->list[j].maxdpi
+ // && w[0] >= surfaceSet->surface[i].featureSet->list[j].mindpi ) {
+ if( w[1] <= surfaceSet->surface[i].featureSet->list[j].maxdpi
+ && w[1] >= surfaceSet->surface[i].featureSet->list[j].mindpi ) {
+ if( l == AR2_TRACKING_CANDIDATE_MAX ) {
+ ARLOGe("### Feature candidates for tracking are overflow.\n");
+ candidate[l].flag = -1;
+ return -1;
+ }
+ candidate[l].snum = i;
+ candidate[l].level = j;
+ candidate[l].num = k;
+ candidate[l].sx = sx;
+ candidate[l].sy = sy;
+ candidate[l].flag = 0;
+ l++;
+ }
+ else if( w[1] <= surfaceSet->surface[i].featureSet->list[j].maxdpi*2
+ && w[1] >= surfaceSet->surface[i].featureSet->list[j].mindpi/2 ) {
+ if( l2 == AR2_TRACKING_CANDIDATE_MAX ) {
+ candidate2[l2].flag = -1;
+ }
+ else {
+ candidate2[l2].snum = i;
+ candidate2[l2].level = j;
+ candidate2[l2].num = k;
+ candidate2[l2].sx = sx;
+ candidate2[l2].sy = sy;
+ candidate2[l2].flag = 0;
+ l2++;
+ }
+ }
+ }
+ }
+ }
+ candidate[l].flag = -1;
+ candidate2[l2].flag = -1;
+
+ return 0;
+}
+
+static int extractVisibleFeaturesHomography(int xsize, int ysize, float trans1[][3][4], AR2SurfaceSetT *surfaceSet,
+ AR2TemplateCandidateT candidate[],
+ AR2TemplateCandidateT candidate2[])
+{
+ float trans2[3][4];
+ float sx, sy;
+ float wpos[2], w[2];
+ //float vdir[3], vlen;
+ int i, j, k, l, l2;
+
+ l = l2 = 0;
+ for( i = 0; i < surfaceSet->num; i++ ) {
+ for(j=0;j<3;j++) for(k=0;k<4;k++) trans2[j][k] = trans1[i][j][k];
+
+ for( j = 0; j < surfaceSet->surface[i].featureSet->num; j++ ) {
+ for( k = 0; k < surfaceSet->surface[i].featureSet->list[j].num; k++ ) {
+
+ if( ar2MarkerCoord2ScreenCoord2( NULL, (const float (*)[4])trans2,
+ surfaceSet->surface[i].featureSet->list[j].coord[k].mx,
+ surfaceSet->surface[i].featureSet->list[j].coord[k].my,
+ &sx, &sy) < 0 ) continue;
+ if( sx < 0 || sx >= xsize ) continue;
+ if( sy < 0 || sy >= ysize ) continue;
+
+/*
+ vdir[0] = trans2[0][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[0][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[0][3];
+ vdir[1] = trans2[1][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[1][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[1][3];
+ vdir[2] = trans2[2][0] * surfaceSet->surface[i].featureSet->list[j].coord[k].mx
+ + trans2[2][1] * surfaceSet->surface[i].featureSet->list[j].coord[k].my
+ + trans2[2][3];
+ vlen = sqrtf( vdir[0]*vdir[0] + vdir[1]*vdir[1] + vdir[2]*vdir[2] );
+ vdir[0] /= vlen;
+ vdir[1] /= vlen;
+ vdir[2] /= vlen;
+ if( vdir[0]*trans2[0][2] + vdir[1]*trans2[1][2] + vdir[2]*trans2[2][2] > -0.1 ) continue;
+*/
+
+ wpos[0] = surfaceSet->surface[i].featureSet->list[j].coord[k].mx;
+ wpos[1] = surfaceSet->surface[i].featureSet->list[j].coord[k].my;
+ ar2GetResolution( NULL, (const float (*)[4])trans2, wpos, w );
+ //if( w[0] <= surfaceSet->surface[i].featureSet->list[j].maxdpi
+ // && w[0] >= surfaceSet->surface[i].featureSet->list[j].mindpi ) {
+ if( w[1] <= surfaceSet->surface[i].featureSet->list[j].maxdpi
+ && w[1] >= surfaceSet->surface[i].featureSet->list[j].mindpi ) {
+ if( l == AR2_TRACKING_CANDIDATE_MAX ) {
+ ARLOGe("### Feature candidates for tracking are overflow.\n");
+ candidate[l].flag = -1;
+ return -1;
+ }
+ candidate[l].snum = i;
+ candidate[l].level = j;
+ candidate[l].num = k;
+ candidate[l].sx = sx;
+ candidate[l].sy = sy;
+ candidate[l].flag = 0;
+ l++;
+ }
+ else if( w[1] <= surfaceSet->surface[i].featureSet->list[j].maxdpi*2
+ && w[1] >= surfaceSet->surface[i].featureSet->list[j].mindpi/2 ) {
+ if( l2 == AR2_TRACKING_CANDIDATE_MAX ) {
+ candidate2[l2].flag = -1;
+ }
+ else {
+ candidate2[l2].snum = i;
+ candidate2[l2].level = j;
+ candidate2[l2].num = k;
+ candidate2[l2].sx = sx;
+ candidate2[l2].sy = sy;
+ candidate2[l2].flag = 0;
+ l2++;
+ }
+ }
+ }
+ }
+ }
+ candidate[l].flag = -1;
+ candidate2[l2].flag = -1;
+
+ return 0;
+}
+
+static float ar2GetTransMat( ICPHandleT *icpHandle, float initConv[3][4], float pos2d[][2], float pos3d[][3], int num,
+ float conv[3][4], int robustMode )
+{
+ ICPDataT data;
+ float dx, dy, dz;
+ ARdouble initMat[3][4], mat[3][4];
+ ARdouble err;
+ int i, j;
+
+ arMalloc( data.screenCoord, ICP2DCoordT, num );
+ arMalloc( data.worldCoord, ICP3DCoordT, num );
+
+ dx = dy = dz = 0.0;
+ for( i = 0; i < num; i++ ) {
+ dx += pos3d[i][0];
+ dy += pos3d[i][1];
+ dz += pos3d[i][2];
+ }
+ dx /= num;
+ dy /= num;
+ dz /= num;
+
+ for( i = 0; i < num; i++ ) {
+ data.screenCoord[i].x = pos2d[i][0];
+ data.screenCoord[i].y = pos2d[i][1];
+ data.worldCoord[i].x = pos3d[i][0] - dx;
+ data.worldCoord[i].y = pos3d[i][1] - dy;
+ data.worldCoord[i].z = pos3d[i][2] - dz;
+ }
+ data.num = num;
+
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 3; i++ ) initMat[j][i] = (ARdouble)(initConv[j][i]);
+ }
+ initMat[0][3] = (ARdouble)(initConv[0][0] * dx + initConv[0][1] * dy + initConv[0][2] * dz + initConv[0][3]);
+ initMat[1][3] = (ARdouble)(initConv[1][0] * dx + initConv[1][1] * dy + initConv[1][2] * dz + initConv[1][3]);
+ initMat[2][3] = (ARdouble)(initConv[2][0] * dx + initConv[2][1] * dy + initConv[2][2] * dz + initConv[2][3]);
+
+ if( robustMode == 0 ) {
+ if( icpPoint( icpHandle, &data, initMat, mat, &err ) < 0 ) {
+ err = 100000000.0F;
+ }
+ }
+ else {
+ if( icpPointRobust( icpHandle, &data, initMat, mat, &err ) < 0 ) {
+ err = 100000000.0F;
+ }
+ }
+
+ free( data.screenCoord );
+ free( data.worldCoord );
+
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 3; i++ ) conv[j][i] = (float)mat[j][i];
+ }
+ conv[0][3] = (float)(mat[0][3] - mat[0][0] * dx - mat[0][1] * dy - mat[0][2] * dz);
+ conv[1][3] = (float)(mat[1][3] - mat[1][0] * dx - mat[1][1] * dy - mat[1][2] * dz);
+ conv[2][3] = (float)(mat[2][3] - mat[2][0] * dx - mat[2][1] * dy - mat[2][2] * dz);
+
+ return (float)err;
+}
+
+static float ar2GetTransMatHomography( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num,
+ float conv[3][4], int robustMode, float inlierProb )
+{
+ if( robustMode == 0 ) {
+ return ar2GetTransMatHomography2( initConv, pos2d, pos3d, num, conv );
+ }
+ else {
+ return ar2GetTransMatHomographyRobust( initConv, pos2d, pos3d, num, conv, inlierProb );
+ }
+}
+
+static float ar2GetTransMatHomography2( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num, float conv[3][4] )
+{
+ float err = 100000000.0F;
+ float *J_U_H;
+ float *dU;
+ float hx, hy, h, hh, ux, uy, dx, dy;
+ float dH[8];
+ float err0, err1;
+ int i, j;
+
+ if( num < 4 ) return err;
+ if( initConv[2][3] == 0.0F ) return err;
+
+ if( (J_U_H = (float *)malloc( sizeof(float)*16*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ return -1;
+ }
+ if( (dU = (float *)malloc( sizeof(float)*2*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ free(J_U_H);
+ return -1;
+ }
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) conv[j][i] = initConv[j][i]/ initConv[2][3];
+ }
+
+ for( i = 0;; i++ ) {
+ err1 = 0.0F;
+ for( j = 0; j < num; j++ ) {
+ hx = conv[0][0] * pos3d[j][0] + conv[0][1] * pos3d[j][1] + conv[0][3];
+ hy = conv[1][0] * pos3d[j][0] + conv[1][1] * pos3d[j][1] + conv[1][3];
+ h = conv[2][0] * pos3d[j][0] + conv[2][1] * pos3d[j][1] + 1.0f;
+ if( h == 0.0 ) {
+ free(J_U_H);
+ free(dU);
+ return err;
+ }
+ hh = h*h;
+ ux = hx / h;
+ uy = hy / h;
+ dx = pos2d[j][0] - ux;
+ dy = pos2d[j][1] - uy;
+ err1 += dx*dx + dy*dy;
+ dU[j*2+0] = dx;
+ dU[j*2+1] = dy;
+ J_U_H[16*j+ 0] = pos3d[j][0]/h;
+ J_U_H[16*j+ 1] = pos3d[j][1]/h;
+ J_U_H[16*j+ 2] = 1.0f/h;
+ J_U_H[16*j+ 3] = 0.0f;
+ J_U_H[16*j+ 4] = 0.0f;
+ J_U_H[16*j+ 5] = 0.0f;
+ J_U_H[16*j+ 6] = -pos3d[j][0]*hx/hh;
+ J_U_H[16*j+ 7] = -pos3d[j][1]*hx/hh;
+ J_U_H[16*j+ 8] = 0.0f;
+ J_U_H[16*j+ 9] = 0.0f;
+ J_U_H[16*j+10] = 0.0f;
+ J_U_H[16*j+11] = pos3d[j][0]/h;
+ J_U_H[16*j+12] = pos3d[j][1]/h;
+ J_U_H[16*j+13] = 1.0f/h;
+ J_U_H[16*j+14] = -pos3d[j][0]*hy/hh;
+ J_U_H[16*j+15] = -pos3d[j][1]*hy/hh;
+ }
+ err1 /= num;
+ //ARLOG("Loop[%d]: err = %15.10f\n", i, err1);
+ if( err1 < ICP_BREAK_LOOP_ERROR_THRESH ) break;
+ if( i > 0 && err1 < ICP_BREAK_LOOP_ERROR_THRESH2 && err1/err0 > ICP_BREAK_LOOP_ERROR_RATIO_THRESH ) break;
+ if( i == ICP_MAX_LOOP ) break;
+ err0 = err1;
+
+ if( getDeltaS( dH, dU, (float (*)[8])J_U_H, num*2 ) < 0 ) {
+ free(J_U_H);
+ free(dU);
+ return err;
+ }
+ //for(j=0;j<8;j++) ARLOG("%f\t", dH[j]); ARLOG("\n");
+ conv[0][0] += dH[0];
+ conv[0][1] += dH[1];
+ conv[0][3] += dH[2];
+ conv[1][0] += dH[3];
+ conv[1][1] += dH[4];
+ conv[1][3] += dH[5];
+ conv[2][0] += dH[6];
+ conv[2][1] += dH[7];
+ }
+
+ //ARLOG("*********** %f\n", err1);
+ //ARLOG("Loop = %d\n", i);
+
+ free(J_U_H);
+ free(dU);
+
+ return err1;
+}
+
+#define K2_FACTOR 4.0F
+
+static int compE( const void *a, const void *b )
+{
+ float c;
+ c = *(float *)a - *(float *)b;
+ if( c < 0.0F ) return -1;
+ if( c > 0.0F ) return 1;
+ return 0;
+}
+
+static float ar2GetTransMatHomographyRobust ( float initConv[3][4], float pos2d[][2], float pos3d[][3], int num, float conv[3][4], float inlierProb )
+{
+ float err = 100000000.0F;
+ float *J_U_H;
+ float *dU;
+ float *E, *E2, K2, W;
+ float hx, hy, h, hh, ux, uy, dx, dy;
+ float dH[8];
+ float err0, err1;
+ int inlierNum;
+ int i, j, k;
+
+ if( num < 4 ) return err;
+ if( initConv[2][3] == 0.0F ) return err;
+
+ inlierNum = (int)(num * inlierProb) - 1;
+ if( inlierNum < 4 ) inlierNum = 4;
+
+ if( (J_U_H = (float *)malloc( sizeof(float)*16*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ return -1;
+ }
+ if( (dU = (float *)malloc( sizeof(float)*2*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ free(J_U_H);
+ return -1;
+ }
+ if( (E = (float *)malloc( sizeof(float)*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ free(J_U_H);
+ free(dU);
+ return -1;
+ }
+ if( (E2 = (float *)malloc( sizeof(float)*num )) == NULL ) {
+ ARLOGe("Error: malloc\n");
+ free(J_U_H);
+ free(dU);
+ free(E);
+ return -1;
+ }
+
+ for( j = 0; j < 3; j++ ) {
+ for( i = 0; i < 4; i++ ) conv[j][i] = initConv[j][i]/ initConv[2][3];
+ }
+
+ for( i = 0;; i++ ) {
+ for( j = 0; j < num; j++ ) {
+ hx = conv[0][0] * pos3d[j][0] + conv[0][1] * pos3d[j][1] + conv[0][3];
+ hy = conv[1][0] * pos3d[j][0] + conv[1][1] * pos3d[j][1] + conv[1][3];
+ h = conv[2][0] * pos3d[j][0] + conv[2][1] * pos3d[j][1] + 1.0F;
+ if( h == 0.0f ) {
+ free(J_U_H);
+ free(dU);
+ free(E);
+ free(E2);
+ return err;
+ }
+ hh = h*h;
+ ux = hx / h;
+ uy = hy / h;
+ dx = pos2d[j][0] - ux;
+ dy = pos2d[j][1] - uy;
+ dU[j*2+0] = dx;
+ dU[j*2+1] = dy;
+ E[j] = E2[j] = dx*dx + dy*dy;
+
+ J_U_H[16*j+ 0] = pos3d[j][0]/h;
+ J_U_H[16*j+ 1] = pos3d[j][1]/h;
+ J_U_H[16*j+ 2] = 1.0f/h;
+ J_U_H[16*j+ 3] = 0.0f;
+ J_U_H[16*j+ 4] = 0.0f;
+ J_U_H[16*j+ 5] = 0.0f;
+ J_U_H[16*j+ 6] = -pos3d[j][0]*hx/hh;
+ J_U_H[16*j+ 7] = -pos3d[j][1]*hx/hh;
+ J_U_H[16*j+ 8] = 0.0f;
+ J_U_H[16*j+ 9] = 0.0f;
+ J_U_H[16*j+10] = 0.0f;
+ J_U_H[16*j+11] = pos3d[j][0]/h;
+ J_U_H[16*j+12] = pos3d[j][1]/h;
+ J_U_H[16*j+13] = 1.0f/h;
+ J_U_H[16*j+14] = -pos3d[j][0]*hy/hh;
+ J_U_H[16*j+15] = -pos3d[j][1]*hy/hh;
+ }
+ qsort(E2, num, sizeof(float), compE);
+ K2 = E2[inlierNum] * K2_FACTOR;
+ if( K2 < 16.0F ) K2 = 16.0F;
+
+ err1 = 0.0F;
+ for( j = 0; j < num; j++ ) {
+ if( E2[j] > K2 ) err1 += K2/6.0F;
+ else err1 += K2/6.0F * (1.0F - (1.0F-E2[j]/K2)*(1.0F-E2[j]/K2)*(1.0F-E2[j]/K2));
+ }
+ err1 /= num;
+ //ARLOG("Loop[%d]: err = %15.10f\n", i, err1);
+ if( err1 < ICP_BREAK_LOOP_ERROR_THRESH ) break;
+ if( i > 0 && err1 < ICP_BREAK_LOOP_ERROR_THRESH2 && err1/err0 > ICP_BREAK_LOOP_ERROR_RATIO_THRESH ) break;
+ if( i == ICP_MAX_LOOP ) break;
+ err0 = err1;
+
+ k = 0;
+ for( j = 0; j < num; j++ ) {
+ if( E[j] <= K2 ) {
+ W = (1.0F - E[j]/K2)*(1.0F - E[j]/K2);
+ J_U_H[k*8+ 0] = W * J_U_H[16*j+0];
+ J_U_H[k*8+ 1] = W * J_U_H[16*j+1];
+ J_U_H[k*8+ 2] = W * J_U_H[16*j+2];
+ J_U_H[k*8+ 3] = W * J_U_H[16*j+3];
+ J_U_H[k*8+ 4] = W * J_U_H[16*j+4];
+ J_U_H[k*8+ 5] = W * J_U_H[16*j+5];
+ J_U_H[k*8+ 6] = W * J_U_H[16*j+6];
+ J_U_H[k*8+ 7] = W * J_U_H[16*j+7];
+ J_U_H[k*8+ 8] = W * J_U_H[16*j+8];
+ J_U_H[k*8+ 9] = W * J_U_H[16*j+9];
+ J_U_H[k*8+10] = W * J_U_H[16*j+10];
+ J_U_H[k*8+11] = W * J_U_H[16*j+11];
+ J_U_H[k*8+12] = W * J_U_H[16*j+12];
+ J_U_H[k*8+13] = W * J_U_H[16*j+13];
+ J_U_H[k*8+14] = W * J_U_H[16*j+14];
+ J_U_H[k*8+15] = W * J_U_H[16*j+15];
+ dU[k+0] = W * dU[j*2+0];
+ dU[k+1] = W * dU[j*2+1];
+ k+=2;
+ }
+ }
+ if( k < 6 ) {
+ free(J_U_H);
+ free(dU);
+ free(E);
+ free(E2);
+ return -1;
+ }
+
+ if( getDeltaS( dH, dU, (float (*)[8])J_U_H, k ) < 0 ) {
+ free(J_U_H);
+ free(dU);
+ free(E);
+ free(E2);
+ return err;
+ }
+ //for(j=0;j<8;j++) ARLOG("%f\t", dH[j]); ARLOG("\n");
+ conv[0][0] += dH[0];
+ conv[0][1] += dH[1];
+ conv[0][3] += dH[2];
+ conv[1][0] += dH[3];
+ conv[1][1] += dH[4];
+ conv[1][3] += dH[5];
+ conv[2][0] += dH[6];
+ conv[2][1] += dH[7];
+ }
+
+ //ARLOG("*********** %f\n", err1);
+ //ARLOG("Loop = %d\n", i);
+
+ free(J_U_H);
+ free(dU);
+ free(E);
+ free(E2);
+
+ return err1;
+}
+
+static int getDeltaS( float H[8], float dU[], float J_U_H[][8], int n )
+{
+ ARMatf matH, matU, matJ;
+ ARMatf *matJt, *matJtJ, *matJtU;
+ int ret = 0;
+
+ matH.row = 8;
+ matH.clm = 1;
+ matH.m = H;
+
+ matU.row = n;
+ matU.clm = 1;
+ matU.m = dU;
+
+ matJ.row = n;
+ matJ.clm = 8;
+ matJ.m = &J_U_H[0][0];
+
+ matJt = arMatrixAllocTransf( &matJ );
+ if( matJt == NULL ) {
+ ret = -1;
+ goto bail;
+ }
+ matJtJ = arMatrixAllocMulf( matJt, &matJ );
+ if( matJtJ == NULL ) {
+ ret = -1;
+ goto bail1;
+ }
+ matJtU = arMatrixAllocMulf( matJt, &matU );
+ if( matJtU == NULL ) {
+ ret = -1;
+ goto bail2;
+ }
+ if( arMatrixSelfInvf(matJtJ) < 0 ) {
+ ret = -1;
+ goto bail3;
+ }
+
+ arMatrixMulf( &matH, matJtJ, matJtU );
+bail3:
+ arMatrixFreef( matJtU );
+bail2:
+ arMatrixFreef( matJtJ );
+bail1:
+ arMatrixFreef( matJt );
+bail:
+ return (ret);
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/tracking2d.c b/ARToolKitUWP/ARToolKit5/src/AR2/tracking2d.c
new file mode 100644
index 0000000..7a9bffb
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/tracking2d.c
@@ -0,0 +1,242 @@
+/*
+ * AR2/tracking2d.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static int ar2Tracking2dSub ( AR2HandleT *handle, AR2SurfaceSetT *surfaceSet, AR2TemplateCandidateT *candidate,
+ ARUint8 *dataPtr, ARUint8 *mfImage, AR2TemplateT **templ,
+ AR2Template2T **templ2, AR2Tracking2DResultT *result );
+#else
+static int ar2Tracking2dSub ( AR2HandleT *handle, AR2SurfaceSetT *surfaceSet, AR2TemplateCandidateT *candidate,
+ ARUint8 *dataPtr, ARUint8 *mfImage, AR2TemplateT **templ,
+ AR2Tracking2DResultT *result );
+#endif
+
+void *ar2Tracking2d( THREAD_HANDLE_T *threadHandle )
+{
+ AR2Tracking2DParamT *arg;
+ int ID;
+
+ arg = (AR2Tracking2DParamT *)threadGetArg(threadHandle);
+ ID = threadGetID(threadHandle);
+
+ ARLOGi("Start tracking_thread #%d.\n", ID);
+ for(;;) {
+ if( threadStartWait(threadHandle) < 0 ) break;
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ arg->ret = ar2Tracking2dSub( arg->ar2Handle, arg->surfaceSet, arg->candidate,
+ arg->dataPtr, arg->mfImage, &(arg->templ), &(arg->templ2), &(arg->result) );
+#else
+ arg->ret = ar2Tracking2dSub( arg->ar2Handle, arg->surfaceSet, arg->candidate,
+ arg->dataPtr, arg->mfImage, &(arg->templ), &(arg->result) );
+#endif
+ threadEndSignal(threadHandle);
+ }
+ ARLOGi("End tracking_thread #%d.\n", ID);
+
+ return NULL;
+}
+
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+static int ar2Tracking2dSub ( AR2HandleT *handle, AR2SurfaceSetT *surfaceSet, AR2TemplateCandidateT *candidate,
+ ARUint8 *dataPtr, ARUint8 *mfImage, AR2TemplateT **templ,
+ AR2Template2T **templ2, AR2Tracking2DResultT *result )
+#else
+static int ar2Tracking2dSub ( AR2HandleT *handle, AR2SurfaceSetT *surfaceSet, AR2TemplateCandidateT *candidate,
+ ARUint8 *dataPtr, ARUint8 *mfImage, AR2TemplateT **templ,
+ AR2Tracking2DResultT *result )
+#endif
+{
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ AR2Template2T *templ2;
+#endif
+ int snum, level, fnum;
+ int search[3][2];
+ int bx, by;
+
+ snum = candidate->snum;
+ level = candidate->level;
+ fnum = candidate->num;
+
+ if( *templ == NULL ) *templ = ar2GenTemplate( handle->templateSize1, handle->templateSize2 );
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( *templ2 == NULL ) *templ2 = ar2GenTemplate2( handle->templateSize1, handle->templateSize2 );
+#endif
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( handle->blurMethod == AR2_CONSTANT_BLUR ) {
+ if( ar2SetTemplateSub( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum],
+ surfaceSet->surface[snum].imageSet,
+ &(surfaceSet->surface[snum].featureSet->list[level]),
+ fnum,
+ handle->blurLevel,
+ *templ ) < 0 ) return -1;
+
+ if( (*templ)->vlen * (*templ)->vlen
+ < ((*templ)->xts1+(*templ)->xts2+1) * ((*templ)->yts1+(*templ)->yts2+1)
+ * AR2_DEFAULT_TRACKING_SD_THRESH * AR2_DEFAULT_TRACKING_SD_THRESH ) {
+ return -1;
+ }
+ }
+ else {
+ if( ar2SetTemplate2Sub( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum],
+ surfaceSet->surface[snum].imageSet,
+ &(surfaceSet->surface[snum].featureSet->list[level]),
+ fnum,
+ handle->blurLevel,
+ *templ2 ) < 0 ) return -1;
+
+ if( (*templ2)->vlen[1] * (*templ2)->vlen[1]
+ < ((*templ2)->xts1+(*templ2)->xts2+1) * ((*templ2)->yts1+(*templ2)->yts2+1)
+ * AR2_DEFAULT_TRACKING_SD_THRESH * AR2_DEFAULT_TRACKING_SD_THRESH ) {
+ return -1;
+ }
+ }
+#else
+ if( ar2SetTemplateSub( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum],
+ surfaceSet->surface[snum].imageSet,
+ &(surfaceSet->surface[snum].featureSet->list[level]),
+ fnum,
+ *templ ) < 0 ) return -1;
+
+ if( (*templ)->vlen * (*templ)->vlen
+ < ((*templ)->xts1 + (*templ)->xts2 + 1) * ((*templ)->yts1 + (*templ)->yts2 + 1)
+ * AR2_DEFAULT_TRACKING_SD_THRESH * AR2_DEFAULT_TRACKING_SD_THRESH ) {
+ return -1;
+ }
+#endif
+
+ // Get the screen coordinates for up to three previous positions of this feature into search[][].
+ if( surfaceSet->contNum == 1 ) {
+ ar2GetSearchPoint( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum], NULL, NULL,
+ &(surfaceSet->surface[snum].featureSet->list[level].coord[fnum]),
+ search );
+ }
+ else if( surfaceSet->contNum == 2 ) {
+ ar2GetSearchPoint( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum],
+ (const float (*)[4])handle->wtrans2[snum], NULL,
+ &(surfaceSet->surface[snum].featureSet->list[level].coord[fnum]),
+ search );
+ }
+ else {
+ ar2GetSearchPoint( handle->cparamLT,
+ (const float (*)[4])handle->wtrans1[snum],
+ (const float (*)[4])handle->wtrans2[snum],
+ (const float (*)[4])handle->wtrans3[snum],
+ &(surfaceSet->surface[snum].featureSet->list[level].coord[fnum]),
+ search );
+ }
+
+#if AR2_CAPABLE_ADAPTIVE_TEMPLATE
+ if( handle->blurMethod == AR2_CONSTANT_BLUR ) {
+ if( ar2GetBestMatching( dataPtr,
+ mfImage,
+ handle->xsize,
+ handle->ysize,
+ handle->pixFormat,
+ *templ,
+ handle->searchSize,
+ handle->searchSize,
+ search,
+ &bx, &by,
+ &(result->sim)) < 0 ) {
+ return -1;
+ }
+ result->blurLevel = handle->blurLevel;
+ }
+ else {
+ if( ar2GetBestMatching2( dataPtr,
+ mfImage,
+ handle->xsize,
+ handle->ysize,
+ handle->pixFormat,
+ *templ2,
+ handle->searchSize,
+ handle->searchSize,
+ search,
+ &bx, &by,
+ &(result->sim),
+ &(result->blurLevel)) < 0 ) {
+ return -1;
+ }
+ }
+#else
+ if( ar2GetBestMatching( dataPtr,
+ mfImage,
+ handle->xsize,
+ handle->ysize,
+ handle->pixFormat,
+ *templ,
+ handle->searchSize,
+ handle->searchSize,
+ search,
+ &bx, &by,
+ &(result->sim)) < 0 ) {
+ return -1;
+ }
+#endif
+
+ result->pos2d[0] = (float)bx;
+ result->pos2d[1] = (float)by;
+ result->pos3d[0] = surfaceSet->surface[snum].trans[0][0] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].mx
+ + surfaceSet->surface[snum].trans[0][1] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].my
+ + surfaceSet->surface[snum].trans[0][3];
+ result->pos3d[1] = surfaceSet->surface[snum].trans[1][0] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].mx
+ + surfaceSet->surface[snum].trans[1][1] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].my
+ + surfaceSet->surface[snum].trans[1][3];
+ result->pos3d[2] = surfaceSet->surface[snum].trans[2][0] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].mx
+ + surfaceSet->surface[snum].trans[2][1] * surfaceSet->surface[snum].featureSet->list[level].coord[fnum].my
+ + surfaceSet->surface[snum].trans[2][3];
+
+ return 0;
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/AR2/util.c b/ARToolKitUWP/ARToolKit5/src/AR2/util.c
new file mode 100644
index 0000000..1327eb9
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/AR2/util.c
@@ -0,0 +1,57 @@
+/*
+ * AR2/util.c
+ * ARToolKit5
+ *
+ * This file is part of ARToolKit.
+ *
+ * ARToolKit is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * ARToolKit is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with ARToolKit. If not, see .
+ *
+ * As a special exception, the copyright holders of this library give you
+ * permission to link this library with independent modules to produce an
+ * executable, regardless of the license terms of these independent modules, and to
+ * copy and distribute the resulting executable under terms of your choice,
+ * provided that you also meet, for each linked independent module, the terms and
+ * conditions of the license of that module. An independent module is a module
+ * which is neither derived from nor based on this library. If you modify this
+ * library, you may extend this exception to your version of the library, but you
+ * are not obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Copyright 2015 Daqri, LLC.
+ * Copyright 2006-2015 ARToolworks, Inc.
+ *
+ * Author(s): Hirokazu Kato, Philip Lamb
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+int ar2UtilReplaceExt( char *filename, int n, char *ext )
+{
+ return arUtilReplaceExt( filename, n, ext );
+}
+
+int ar2UtilRemoveExt( char *filename )
+{
+ return arUtilRemoveExt( filename );
+}
+
+int ar2UtilDivideExt( const char *filename, char *s1, char *s2 )
+{
+ return arUtilDivideExt( filename, s1, s2 );
+}
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Array b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Array
new file mode 100644
index 0000000..3d004fb
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Array
@@ -0,0 +1,11 @@
+#ifndef EIGEN_ARRAY_MODULE_H
+#define EIGEN_ARRAY_MODULE_H
+
+// include Core first to handle Eigen2 support macros
+#include "Core"
+
+#ifndef EIGEN2_SUPPORT
+ #error The Eigen/Array header does no longer exist in Eigen3. All that functionality has moved to Eigen/Core.
+#endif
+
+#endif // EIGEN_ARRAY_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CMakeLists.txt b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CMakeLists.txt
new file mode 100644
index 0000000..a92dd6f
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CMakeLists.txt
@@ -0,0 +1,19 @@
+include(RegexUtils)
+test_escape_string_as_regex()
+
+file(GLOB Eigen_directory_files "*")
+
+escape_string_as_regex(ESCAPED_CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+
+foreach(f ${Eigen_directory_files})
+ if(NOT f MATCHES "\\.txt" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/[.].+" AND NOT f MATCHES "${ESCAPED_CMAKE_CURRENT_SOURCE_DIR}/src")
+ list(APPEND Eigen_directory_files_to_install ${f})
+ endif()
+endforeach(f ${Eigen_directory_files})
+
+install(FILES
+ ${Eigen_directory_files_to_install}
+ DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen COMPONENT Devel
+ )
+
+add_subdirectory(src)
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Cholesky b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Cholesky
new file mode 100644
index 0000000..f727f5d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Cholesky
@@ -0,0 +1,32 @@
+#ifndef EIGEN_CHOLESKY_MODULE_H
+#define EIGEN_CHOLESKY_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup Cholesky_Module Cholesky module
+ *
+ *
+ *
+ * This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
+ * Those decompositions are accessible via the following MatrixBase methods:
+ * - MatrixBase::llt(),
+ * - MatrixBase::ldlt()
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/misc/Solve.h"
+#include "src/Cholesky/LLT.h"
+#include "src/Cholesky/LDLT.h"
+#ifdef EIGEN_USE_LAPACKE
+#include "src/Cholesky/LLT_MKL.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_CHOLESKY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CholmodSupport b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CholmodSupport
new file mode 100644
index 0000000..88c29a6
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/CholmodSupport
@@ -0,0 +1,45 @@
+#ifndef EIGEN_CHOLMODSUPPORT_MODULE_H
+#define EIGEN_CHOLMODSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+extern "C" {
+ #include
+}
+
+/** \ingroup Support_modules
+ * \defgroup CholmodSupport_Module CholmodSupport module
+ *
+ * This module provides an interface to the Cholmod library which is part of the suitesparse package.
+ * It provides the two following main factorization classes:
+ * - class CholmodSupernodalLLT: a supernodal LLT Cholesky factorization.
+ * - class CholmodDecomposiiton: a general L(D)LT Cholesky factorization with automatic or explicit runtime selection of the underlying factorization method (supernodal or simplicial).
+ *
+ * For the sake of completeness, this module also propose the two following classes:
+ * - class CholmodSimplicialLLT
+ * - class CholmodSimplicialLDLT
+ * Note that these classes does not bring any particular advantage compared to the built-in
+ * SimplicialLLT and SimplicialLDLT factorization classes.
+ *
+ * \code
+ * #include
+ * \endcode
+ *
+ * In order to use this module, the cholmod headers must be accessible from the include paths, and your binary must be linked to the cholmod library and its dependencies.
+ * The dependencies depend on how cholmod has been compiled.
+ * For a cmake based project, you can use our FindCholmod.cmake module to help you in this task.
+ *
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
+#include "src/CholmodSupport/CholmodSupport.h"
+
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_CHOLMODSUPPORT_MODULE_H
+
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Core b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Core
new file mode 100644
index 0000000..509c529
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Core
@@ -0,0 +1,376 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008 Gael Guennebaud
+// Copyright (C) 2007-2011 Benoit Jacob
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_CORE_H
+#define EIGEN_CORE_H
+
+// first thing Eigen does: stop the compiler from committing suicide
+#include "src/Core/util/DisableStupidWarnings.h"
+
+// then include this file where all our macros are defined. It's really important to do it first because
+// it's where we do all the alignment settings (platform detection and honoring the user's will if he
+// defined e.g. EIGEN_DONT_ALIGN) so it needs to be done before we do anything with vectorization.
+#include "src/Core/util/Macros.h"
+
+// Disable the ipa-cp-clone optimization flag with MinGW 6.x or newer (enabled by default with -O3)
+// See http://eigen.tuxfamily.org/bz/show_bug.cgi?id=556 for details.
+#if defined(__MINGW32__) && EIGEN_GNUC_AT_LEAST(4,6)
+ #pragma GCC optimize ("-fno-ipa-cp-clone")
+#endif
+
+#include
+
+// this include file manages BLAS and MKL related macros
+// and inclusion of their respective header files
+#include "src/Core/util/MKL_support.h"
+
+// if alignment is disabled, then disable vectorization. Note: EIGEN_ALIGN is the proper check, it takes into
+// account both the user's will (EIGEN_DONT_ALIGN) and our own platform checks
+#if !EIGEN_ALIGN
+ #ifndef EIGEN_DONT_VECTORIZE
+ #define EIGEN_DONT_VECTORIZE
+ #endif
+#endif
+
+#ifdef _MSC_VER
+ #include // for _aligned_malloc -- need it regardless of whether vectorization is enabled
+ #if (_MSC_VER >= 1500) // 2008 or later
+ // Remember that usage of defined() in a #define is undefined by the standard.
+ // a user reported that in 64-bit mode, MSVC doesn't care to define _M_IX86_FP.
+ #if (defined(_M_IX86_FP) && (_M_IX86_FP >= 2)) || defined(_M_X64)
+ #define EIGEN_SSE2_ON_MSVC_2008_OR_LATER
+ #endif
+ #endif
+#else
+ // Remember that usage of defined() in a #define is undefined by the standard
+ #if (defined __SSE2__) && ( (!defined __GNUC__) || (defined __INTEL_COMPILER) || EIGEN_GNUC_AT_LEAST(4,2) )
+ #define EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC
+ #endif
+#endif
+
+#ifndef EIGEN_DONT_VECTORIZE
+
+ #if defined (EIGEN_SSE2_ON_NON_MSVC_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
+
+ // Defines symbols for compile-time detection of which instructions are
+ // used.
+ // EIGEN_VECTORIZE_YY is defined if and only if the instruction set YY is used
+ #define EIGEN_VECTORIZE
+ #define EIGEN_VECTORIZE_SSE
+ #define EIGEN_VECTORIZE_SSE2
+
+ // Detect sse3/ssse3/sse4:
+ // gcc and icc defines __SSE3__, ...
+ // there is no way to know about this on msvc. You can define EIGEN_VECTORIZE_SSE* if you
+ // want to force the use of those instructions with msvc.
+ #ifdef __SSE3__
+ #define EIGEN_VECTORIZE_SSE3
+ #endif
+ #ifdef __SSSE3__
+ #define EIGEN_VECTORIZE_SSSE3
+ #endif
+ #ifdef __SSE4_1__
+ #define EIGEN_VECTORIZE_SSE4_1
+ #endif
+ #ifdef __SSE4_2__
+ #define EIGEN_VECTORIZE_SSE4_2
+ #endif
+
+ // include files
+
+ // This extern "C" works around a MINGW-w64 compilation issue
+ // https://sourceforge.net/tracker/index.php?func=detail&aid=3018394&group_id=202880&atid=983354
+ // In essence, intrin.h is included by windows.h and also declares intrinsics (just as emmintrin.h etc. below do).
+ // However, intrin.h uses an extern "C" declaration, and g++ thus complains of duplicate declarations
+ // with conflicting linkage. The linkage for intrinsics doesn't matter, but at that stage the compiler doesn't know;
+ // so, to avoid compile errors when windows.h is included after Eigen/Core, ensure intrinsics are extern "C" here too.
+ // notice that since these are C headers, the extern "C" is theoretically needed anyways.
+ extern "C" {
+ // In theory we should only include immintrin.h and not the other *mmintrin.h header files directly.
+ // Doing so triggers some issues with ICC. However old gcc versions seems to not have this file, thus:
+ #if defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 1110
+ #include
+ #else
+ #include
+ #include
+ #ifdef EIGEN_VECTORIZE_SSE3
+ #include
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSSE3
+ #include
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSE4_1
+ #include
+ #endif
+ #ifdef EIGEN_VECTORIZE_SSE4_2
+ #include
+ #endif
+ #endif
+ } // end extern "C"
+ #elif defined __ALTIVEC__
+ #define EIGEN_VECTORIZE
+ #define EIGEN_VECTORIZE_ALTIVEC
+ #include
+ // We need to #undef all these ugly tokens defined in
+ // => use __vector instead of vector
+ #undef bool
+ #undef vector
+ #undef pixel
+ #elif defined __ARM_NEON
+ #define EIGEN_VECTORIZE
+ #define EIGEN_VECTORIZE_NEON
+ #include
+ #endif
+#endif
+
+#if (defined _OPENMP) && (!defined EIGEN_DONT_PARALLELIZE)
+ #define EIGEN_HAS_OPENMP
+#endif
+
+#ifdef EIGEN_HAS_OPENMP
+#include
+#endif
+
+// MSVC for windows mobile does not have the errno.h file
+#if !(defined(_MSC_VER) && defined(_WIN32_WCE)) && !defined(__ARMCC_VERSION)
+#define EIGEN_HAS_ERRNO
+#endif
+
+#ifdef EIGEN_HAS_ERRNO
+#include
+#endif
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include // for CHAR_BIT
+// for min/max:
+#include
+
+// for outputting debug info
+#ifdef EIGEN_DEBUG_ASSIGN
+#include
+#endif
+
+// required for __cpuid, needs to be included after cmath
+#if defined(_MSC_VER) && (defined(_M_IX86)||defined(_M_X64)) && (!defined(_WIN32_WCE))
+ #include
+#endif
+
+#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
+ #define EIGEN_EXCEPTIONS
+#endif
+
+#ifdef EIGEN_EXCEPTIONS
+ #include
+#endif
+
+/** \brief Namespace containing all symbols from the %Eigen library. */
+namespace Eigen {
+
+inline static const char *SimdInstructionSetsInUse(void) {
+#if defined(EIGEN_VECTORIZE_SSE4_2)
+ return "SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2";
+#elif defined(EIGEN_VECTORIZE_SSE4_1)
+ return "SSE, SSE2, SSE3, SSSE3, SSE4.1";
+#elif defined(EIGEN_VECTORIZE_SSSE3)
+ return "SSE, SSE2, SSE3, SSSE3";
+#elif defined(EIGEN_VECTORIZE_SSE3)
+ return "SSE, SSE2, SSE3";
+#elif defined(EIGEN_VECTORIZE_SSE2)
+ return "SSE, SSE2";
+#elif defined(EIGEN_VECTORIZE_ALTIVEC)
+ return "AltiVec";
+#elif defined(EIGEN_VECTORIZE_NEON)
+ return "ARM NEON";
+#else
+ return "None";
+#endif
+}
+
+} // end namespace Eigen
+
+#define STAGE10_FULL_EIGEN2_API 10
+#define STAGE20_RESOLVE_API_CONFLICTS 20
+#define STAGE30_FULL_EIGEN3_API 30
+#define STAGE40_FULL_EIGEN3_STRICTNESS 40
+#define STAGE99_NO_EIGEN2_SUPPORT 99
+
+#if defined EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS
+ #define EIGEN2_SUPPORT
+ #define EIGEN2_SUPPORT_STAGE STAGE40_FULL_EIGEN3_STRICTNESS
+#elif defined EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
+ #define EIGEN2_SUPPORT
+ #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
+#elif defined EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS
+ #define EIGEN2_SUPPORT
+ #define EIGEN2_SUPPORT_STAGE STAGE20_RESOLVE_API_CONFLICTS
+#elif defined EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API
+ #define EIGEN2_SUPPORT
+ #define EIGEN2_SUPPORT_STAGE STAGE10_FULL_EIGEN2_API
+#elif defined EIGEN2_SUPPORT
+ // default to stage 3, that's what it's always meant
+ #define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API
+ #define EIGEN2_SUPPORT_STAGE STAGE30_FULL_EIGEN3_API
+#else
+ #define EIGEN2_SUPPORT_STAGE STAGE99_NO_EIGEN2_SUPPORT
+#endif
+
+#ifdef EIGEN2_SUPPORT
+#undef minor
+#endif
+
+// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
+// ensure QNX/QCC support
+using std::size_t;
+// gcc 4.6.0 wants std:: for ptrdiff_t
+using std::ptrdiff_t;
+
+/** \defgroup Core_Module Core module
+ * This is the main module of Eigen providing dense matrix and vector support
+ * (both fixed and dynamic size) with all the features corresponding to a BLAS library
+ * and much more...
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/Core/util/Constants.h"
+#include "src/Core/util/ForwardDeclarations.h"
+#include "src/Core/util/Meta.h"
+#include "src/Core/util/StaticAssert.h"
+#include "src/Core/util/XprHelper.h"
+#include "src/Core/util/Memory.h"
+
+#include "src/Core/NumTraits.h"
+#include "src/Core/MathFunctions.h"
+#include "src/Core/GenericPacketMath.h"
+
+#if defined EIGEN_VECTORIZE_SSE
+ #include "src/Core/arch/SSE/PacketMath.h"
+ #include "src/Core/arch/SSE/MathFunctions.h"
+ #include "src/Core/arch/SSE/Complex.h"
+#elif defined EIGEN_VECTORIZE_ALTIVEC
+ #include "src/Core/arch/AltiVec/PacketMath.h"
+ #include "src/Core/arch/AltiVec/Complex.h"
+#elif defined EIGEN_VECTORIZE_NEON
+ #include "src/Core/arch/NEON/PacketMath.h"
+ #include "src/Core/arch/NEON/Complex.h"
+#endif
+
+#include "src/Core/arch/Default/Settings.h"
+
+#include "src/Core/Functors.h"
+#include "src/Core/DenseCoeffsBase.h"
+#include "src/Core/DenseBase.h"
+#include "src/Core/MatrixBase.h"
+#include "src/Core/EigenBase.h"
+
+#ifndef EIGEN_PARSED_BY_DOXYGEN // work around Doxygen bug triggered by Assign.h r814874
+ // at least confirmed with Doxygen 1.5.5 and 1.5.6
+ #include "src/Core/Assign.h"
+#endif
+
+#include "src/Core/util/BlasUtil.h"
+#include "src/Core/DenseStorage.h"
+#include "src/Core/NestByValue.h"
+#include "src/Core/ForceAlignedAccess.h"
+#include "src/Core/ReturnByValue.h"
+#include "src/Core/NoAlias.h"
+#include "src/Core/PlainObjectBase.h"
+#include "src/Core/Matrix.h"
+#include "src/Core/Array.h"
+#include "src/Core/CwiseBinaryOp.h"
+#include "src/Core/CwiseUnaryOp.h"
+#include "src/Core/CwiseNullaryOp.h"
+#include "src/Core/CwiseUnaryView.h"
+#include "src/Core/SelfCwiseBinaryOp.h"
+#include "src/Core/Dot.h"
+#include "src/Core/StableNorm.h"
+#include "src/Core/MapBase.h"
+#include "src/Core/Stride.h"
+#include "src/Core/Map.h"
+#include "src/Core/Block.h"
+#include "src/Core/VectorBlock.h"
+#include "src/Core/Ref.h"
+#include "src/Core/Transpose.h"
+#include "src/Core/DiagonalMatrix.h"
+#include "src/Core/Diagonal.h"
+#include "src/Core/DiagonalProduct.h"
+#include "src/Core/PermutationMatrix.h"
+#include "src/Core/Transpositions.h"
+#include "src/Core/Redux.h"
+#include "src/Core/Visitor.h"
+#include "src/Core/Fuzzy.h"
+#include "src/Core/IO.h"
+#include "src/Core/Swap.h"
+#include "src/Core/CommaInitializer.h"
+#include "src/Core/Flagged.h"
+#include "src/Core/ProductBase.h"
+#include "src/Core/GeneralProduct.h"
+#include "src/Core/TriangularMatrix.h"
+#include "src/Core/SelfAdjointView.h"
+#include "src/Core/products/GeneralBlockPanelKernel.h"
+#include "src/Core/products/Parallelizer.h"
+#include "src/Core/products/CoeffBasedProduct.h"
+#include "src/Core/products/GeneralMatrixVector.h"
+#include "src/Core/products/GeneralMatrixMatrix.h"
+#include "src/Core/SolveTriangular.h"
+#include "src/Core/products/GeneralMatrixMatrixTriangular.h"
+#include "src/Core/products/SelfadjointMatrixVector.h"
+#include "src/Core/products/SelfadjointMatrixMatrix.h"
+#include "src/Core/products/SelfadjointProduct.h"
+#include "src/Core/products/SelfadjointRank2Update.h"
+#include "src/Core/products/TriangularMatrixVector.h"
+#include "src/Core/products/TriangularMatrixMatrix.h"
+#include "src/Core/products/TriangularSolverMatrix.h"
+#include "src/Core/products/TriangularSolverVector.h"
+#include "src/Core/BandMatrix.h"
+#include "src/Core/CoreIterators.h"
+
+#include "src/Core/BooleanRedux.h"
+#include "src/Core/Select.h"
+#include "src/Core/VectorwiseOp.h"
+#include "src/Core/Random.h"
+#include "src/Core/Replicate.h"
+#include "src/Core/Reverse.h"
+#include "src/Core/ArrayBase.h"
+#include "src/Core/ArrayWrapper.h"
+
+#ifdef EIGEN_USE_BLAS
+#include "src/Core/products/GeneralMatrixMatrix_MKL.h"
+#include "src/Core/products/GeneralMatrixVector_MKL.h"
+#include "src/Core/products/GeneralMatrixMatrixTriangular_MKL.h"
+#include "src/Core/products/SelfadjointMatrixMatrix_MKL.h"
+#include "src/Core/products/SelfadjointMatrixVector_MKL.h"
+#include "src/Core/products/TriangularMatrixMatrix_MKL.h"
+#include "src/Core/products/TriangularMatrixVector_MKL.h"
+#include "src/Core/products/TriangularSolverMatrix_MKL.h"
+#endif // EIGEN_USE_BLAS
+
+#ifdef EIGEN_USE_MKL_VML
+#include "src/Core/Assign_MKL.h"
+#endif
+
+#include "src/Core/GlobalFunctions.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#ifdef EIGEN2_SUPPORT
+#include "Eigen2Support"
+#endif
+
+#endif // EIGEN_CORE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Dense b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Dense
new file mode 100644
index 0000000..5768910
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Dense
@@ -0,0 +1,7 @@
+#include "Core"
+#include "LU"
+#include "Cholesky"
+#include "QR"
+#include "SVD"
+#include "Geometry"
+#include "Eigenvalues"
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen
new file mode 100644
index 0000000..19b40ea
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen
@@ -0,0 +1,2 @@
+#include "Dense"
+//#include "Sparse"
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen2Support b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen2Support
new file mode 100644
index 0000000..6aa009d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigen2Support
@@ -0,0 +1,95 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2009 Gael Guennebaud
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN2SUPPORT_H
+#define EIGEN2SUPPORT_H
+
+#if (!defined(EIGEN2_SUPPORT)) || (!defined(EIGEN_CORE_H))
+#error Eigen2 support must be enabled by defining EIGEN2_SUPPORT before including any Eigen header
+#endif
+
+#ifndef EIGEN_NO_EIGEN2_DEPRECATED_WARNING
+
+#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__clang__)
+#warning "Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)"
+#else
+#pragma message ("Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3. (Define EIGEN_NO_EIGEN2_DEPRECATED_WARNING to disable this warning)")
+#endif
+
+#endif // EIGEN_NO_EIGEN2_DEPRECATED_WARNING
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \ingroup Support_modules
+ * \defgroup Eigen2Support_Module Eigen2 support module
+ *
+ * \warning Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.
+ *
+ * This module provides a couple of deprecated functions improving the compatibility with Eigen2.
+ *
+ * To use it, define EIGEN2_SUPPORT before including any Eigen header
+ * \code
+ * #define EIGEN2_SUPPORT
+ * \endcode
+ *
+ */
+
+#include "src/Eigen2Support/Macros.h"
+#include "src/Eigen2Support/Memory.h"
+#include "src/Eigen2Support/Meta.h"
+#include "src/Eigen2Support/Lazy.h"
+#include "src/Eigen2Support/Cwise.h"
+#include "src/Eigen2Support/CwiseOperators.h"
+#include "src/Eigen2Support/TriangularSolver.h"
+#include "src/Eigen2Support/Block.h"
+#include "src/Eigen2Support/VectorBlock.h"
+#include "src/Eigen2Support/Minor.h"
+#include "src/Eigen2Support/MathFunctions.h"
+
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+// Eigen2 used to include iostream
+#include
+
+#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \
+using Eigen::Matrix##SizeSuffix##TypeSuffix; \
+using Eigen::Vector##SizeSuffix##TypeSuffix; \
+using Eigen::RowVector##SizeSuffix##TypeSuffix;
+
+#define EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(TypeSuffix) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \
+
+#define EIGEN_USING_MATRIX_TYPEDEFS \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(i) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(f) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(d) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cf) \
+EIGEN_USING_MATRIX_TYPEDEFS_FOR_TYPE(cd)
+
+#define USING_PART_OF_NAMESPACE_EIGEN \
+EIGEN_USING_MATRIX_TYPEDEFS \
+using Eigen::Matrix; \
+using Eigen::MatrixBase; \
+using Eigen::ei_random; \
+using Eigen::ei_real; \
+using Eigen::ei_imag; \
+using Eigen::ei_conj; \
+using Eigen::ei_abs; \
+using Eigen::ei_abs2; \
+using Eigen::ei_sqrt; \
+using Eigen::ei_exp; \
+using Eigen::ei_log; \
+using Eigen::ei_sin; \
+using Eigen::ei_cos;
+
+#endif // EIGEN2SUPPORT_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigenvalues b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigenvalues
new file mode 100644
index 0000000..53c5a73
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Eigenvalues
@@ -0,0 +1,48 @@
+#ifndef EIGEN_EIGENVALUES_MODULE_H
+#define EIGEN_EIGENVALUES_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "Cholesky"
+#include "Jacobi"
+#include "Householder"
+#include "LU"
+#include "Geometry"
+
+/** \defgroup Eigenvalues_Module Eigenvalues module
+ *
+ *
+ *
+ * This module mainly provides various eigenvalue solvers.
+ * This module also provides some MatrixBase methods, including:
+ * - MatrixBase::eigenvalues(),
+ * - MatrixBase::operatorNorm()
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/Eigenvalues/Tridiagonalization.h"
+#include "src/Eigenvalues/RealSchur.h"
+#include "src/Eigenvalues/EigenSolver.h"
+#include "src/Eigenvalues/SelfAdjointEigenSolver.h"
+#include "src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h"
+#include "src/Eigenvalues/HessenbergDecomposition.h"
+#include "src/Eigenvalues/ComplexSchur.h"
+#include "src/Eigenvalues/ComplexEigenSolver.h"
+#include "src/Eigenvalues/RealQZ.h"
+#include "src/Eigenvalues/GeneralizedEigenSolver.h"
+#include "src/Eigenvalues/MatrixBaseEigenvalues.h"
+#ifdef EIGEN_USE_LAPACKE
+#include "src/Eigenvalues/RealSchur_MKL.h"
+#include "src/Eigenvalues/ComplexSchur_MKL.h"
+#include "src/Eigenvalues/SelfAdjointEigenSolver_MKL.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_EIGENVALUES_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Geometry b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Geometry
new file mode 100644
index 0000000..efd9d45
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Geometry
@@ -0,0 +1,63 @@
+#ifndef EIGEN_GEOMETRY_MODULE_H
+#define EIGEN_GEOMETRY_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "SVD"
+#include "LU"
+#include
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+/** \defgroup Geometry_Module Geometry module
+ *
+ *
+ *
+ * This module provides support for:
+ * - fixed-size homogeneous transformations
+ * - translation, scaling, 2D and 3D rotations
+ * - quaternions
+ * - \ref MatrixBase::cross() "cross product"
+ * - \ref MatrixBase::unitOrthogonal() "orthognal vector generation"
+ * - some linear components: parametrized-lines and hyperplanes
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/Geometry/OrthoMethods.h"
+#include "src/Geometry/EulerAngles.h"
+
+#if EIGEN2_SUPPORT_STAGE > STAGE20_RESOLVE_API_CONFLICTS
+ #include "src/Geometry/Homogeneous.h"
+ #include "src/Geometry/RotationBase.h"
+ #include "src/Geometry/Rotation2D.h"
+ #include "src/Geometry/Quaternion.h"
+ #include "src/Geometry/AngleAxis.h"
+ #include "src/Geometry/Transform.h"
+ #include "src/Geometry/Translation.h"
+ #include "src/Geometry/Scaling.h"
+ #include "src/Geometry/Hyperplane.h"
+ #include "src/Geometry/ParametrizedLine.h"
+ #include "src/Geometry/AlignedBox.h"
+ #include "src/Geometry/Umeyama.h"
+
+ #if defined EIGEN_VECTORIZE_SSE
+ #include "src/Geometry/arch/Geometry_SSE.h"
+ #endif
+#endif
+
+#ifdef EIGEN2_SUPPORT
+#include "src/Eigen2Support/Geometry/All.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_GEOMETRY_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Householder b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Householder
new file mode 100644
index 0000000..6e348db
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Householder
@@ -0,0 +1,23 @@
+#ifndef EIGEN_HOUSEHOLDER_MODULE_H
+#define EIGEN_HOUSEHOLDER_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup Householder_Module Householder module
+ * This module provides Householder transformations.
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/Householder/Householder.h"
+#include "src/Householder/HouseholderSequence.h"
+#include "src/Householder/BlockHouseholder.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_HOUSEHOLDER_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/IterativeLinearSolvers b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/IterativeLinearSolvers
new file mode 100644
index 0000000..0f4159d
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/IterativeLinearSolvers
@@ -0,0 +1,40 @@
+#ifndef EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
+#define EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
+
+#include "SparseCore"
+#include "OrderingMethods"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/**
+ * \defgroup IterativeLinearSolvers_Module IterativeLinearSolvers module
+ *
+ * This module currently provides iterative methods to solve problems of the form \c A \c x = \c b, where \c A is a squared matrix, usually very large and sparse.
+ * Those solvers are accessible via the following classes:
+ * - ConjugateGradient for selfadjoint (hermitian) matrices,
+ * - BiCGSTAB for general square matrices.
+ *
+ * These iterative solvers are associated with some preconditioners:
+ * - IdentityPreconditioner - not really useful
+ * - DiagonalPreconditioner - also called JAcobi preconditioner, work very well on diagonal dominant matrices.
+ * - IncompleteILUT - incomplete LU factorization with dual thresholding
+ *
+ * Such problems can also be solved using the direct sparse decomposition modules: SparseCholesky, CholmodSupport, UmfPackSupport, SuperLUSupport.
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
+#include "src/IterativeLinearSolvers/IterativeSolverBase.h"
+#include "src/IterativeLinearSolvers/BasicPreconditioners.h"
+#include "src/IterativeLinearSolvers/ConjugateGradient.h"
+#include "src/IterativeLinearSolvers/BiCGSTAB.h"
+#include "src/IterativeLinearSolvers/IncompleteLUT.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_ITERATIVELINEARSOLVERS_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Jacobi b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Jacobi
new file mode 100644
index 0000000..ba8a4dc
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Jacobi
@@ -0,0 +1,26 @@
+#ifndef EIGEN_JACOBI_MODULE_H
+#define EIGEN_JACOBI_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup Jacobi_Module Jacobi module
+ * This module provides Jacobi and Givens rotations.
+ *
+ * \code
+ * #include
+ * \endcode
+ *
+ * In addition to listed classes, it defines the two following MatrixBase methods to apply a Jacobi or Givens rotation:
+ * - MatrixBase::applyOnTheLeft()
+ * - MatrixBase::applyOnTheRight().
+ */
+
+#include "src/Jacobi/Jacobi.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_JACOBI_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LU b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LU
new file mode 100644
index 0000000..db57955
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LU
@@ -0,0 +1,41 @@
+#ifndef EIGEN_LU_MODULE_H
+#define EIGEN_LU_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup LU_Module LU module
+ * This module includes %LU decomposition and related notions such as matrix inversion and determinant.
+ * This module defines the following MatrixBase methods:
+ * - MatrixBase::inverse()
+ * - MatrixBase::determinant()
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/Kernel.h"
+#include "src/misc/Image.h"
+#include "src/LU/FullPivLU.h"
+#include "src/LU/PartialPivLU.h"
+#ifdef EIGEN_USE_LAPACKE
+#include "src/LU/PartialPivLU_MKL.h"
+#endif
+#include "src/LU/Determinant.h"
+#include "src/LU/Inverse.h"
+
+#if defined EIGEN_VECTORIZE_SSE
+ #include "src/LU/arch/Inverse_SSE.h"
+#endif
+
+#ifdef EIGEN2_SUPPORT
+ #include "src/Eigen2Support/LU.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_LU_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LeastSquares b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LeastSquares
new file mode 100644
index 0000000..35137c2
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/LeastSquares
@@ -0,0 +1,32 @@
+#ifndef EIGEN_REGRESSION_MODULE_H
+#define EIGEN_REGRESSION_MODULE_H
+
+#ifndef EIGEN2_SUPPORT
+#error LeastSquares is only available in Eigen2 support mode (define EIGEN2_SUPPORT)
+#endif
+
+// exclude from normal eigen3-only documentation
+#ifdef EIGEN2_SUPPORT
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "Eigenvalues"
+#include "Geometry"
+
+/** \defgroup LeastSquares_Module LeastSquares module
+ * This module provides linear regression and related features.
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/Eigen2Support/LeastSquares.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN2_SUPPORT
+
+#endif // EIGEN_REGRESSION_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/MetisSupport b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/MetisSupport
new file mode 100644
index 0000000..6a113f7
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/MetisSupport
@@ -0,0 +1,28 @@
+#ifndef EIGEN_METISSUPPORT_MODULE_H
+#define EIGEN_METISSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+extern "C" {
+#include
+}
+
+
+/** \ingroup Support_modules
+ * \defgroup MetisSupport_Module MetisSupport module
+ *
+ * \code
+ * #include
+ * \endcode
+ * This module defines an interface to the METIS reordering package (http://glaros.dtc.umn.edu/gkhome/views/metis).
+ * It can be used just as any other built-in method as explained in \link OrderingMethods_Module here. \endlink
+ */
+
+
+#include "src/MetisSupport/MetisSupport.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_METISSUPPORT_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/OrderingMethods b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/OrderingMethods
new file mode 100644
index 0000000..7c0f1ff
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/OrderingMethods
@@ -0,0 +1,66 @@
+#ifndef EIGEN_ORDERINGMETHODS_MODULE_H
+#define EIGEN_ORDERINGMETHODS_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/**
+ * \defgroup OrderingMethods_Module OrderingMethods module
+ *
+ * This module is currently for internal use only
+ *
+ * It defines various built-in and external ordering methods for sparse matrices.
+ * They are typically used to reduce the number of elements during
+ * the sparse matrix decomposition (LLT, LU, QR).
+ * Precisely, in a preprocessing step, a permutation matrix P is computed using
+ * those ordering methods and applied to the columns of the matrix.
+ * Using for instance the sparse Cholesky decomposition, it is expected that
+ * the nonzeros elements in LLT(A*P) will be much smaller than that in LLT(A).
+ *
+ *
+ * Usage :
+ * \code
+ * #include
+ * \endcode
+ *
+ * A simple usage is as a template parameter in the sparse decomposition classes :
+ *
+ * \code
+ * SparseLU > solver;
+ * \endcode
+ *
+ * \code
+ * SparseQR > solver;
+ * \endcode
+ *
+ * It is possible as well to call directly a particular ordering method for your own purpose,
+ * \code
+ * AMDOrdering ordering;
+ * PermutationMatrix perm;
+ * SparseMatrix A;
+ * //Fill the matrix ...
+ *
+ * ordering(A, perm); // Call AMD
+ * \endcode
+ *
+ * \note Some of these methods (like AMD or METIS), need the sparsity pattern
+ * of the input matrix to be symmetric. When the matrix is structurally unsymmetric,
+ * Eigen computes internally the pattern of \f$A^T*A\f$ before calling the method.
+ * If your matrix is already symmetric (at leat in structure), you can avoid that
+ * by calling the method with a SelfAdjointView type.
+ *
+ * \code
+ * // Call the ordering on the pattern of the lower triangular matrix A
+ * ordering(A.selfadjointView(), perm);
+ * \endcode
+ */
+
+#ifndef EIGEN_MPL2_ONLY
+#include "src/OrderingMethods/Amd.h"
+#endif
+
+#include "src/OrderingMethods/Ordering.h"
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_ORDERINGMETHODS_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PaStiXSupport b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PaStiXSupport
new file mode 100644
index 0000000..7c616ee
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PaStiXSupport
@@ -0,0 +1,46 @@
+#ifndef EIGEN_PASTIXSUPPORT_MODULE_H
+#define EIGEN_PASTIXSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include
+extern "C" {
+#include
+#include
+}
+
+#ifdef complex
+#undef complex
+#endif
+
+/** \ingroup Support_modules
+ * \defgroup PaStiXSupport_Module PaStiXSupport module
+ *
+ * This module provides an interface to the PaSTiX library.
+ * PaSTiX is a general \b supernodal, \b parallel and \b opensource sparse solver.
+ * It provides the two following main factorization classes:
+ * - class PastixLLT : a supernodal, parallel LLt Cholesky factorization.
+ * - class PastixLDLT: a supernodal, parallel LDLt Cholesky factorization.
+ * - class PastixLU : a supernodal, parallel LU factorization (optimized for a symmetric pattern).
+ *
+ * \code
+ * #include
+ * \endcode
+ *
+ * In order to use this module, the PaSTiX headers must be accessible from the include paths, and your binary must be linked to the PaSTiX library and its dependencies.
+ * The dependencies depend on how PaSTiX has been compiled.
+ * For a cmake based project, you can use our FindPaSTiX.cmake module to help you in this task.
+ *
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+
+#include "src/PaStiXSupport/PaStiXSupport.h"
+
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_PASTIXSUPPORT_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PardisoSupport b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PardisoSupport
new file mode 100644
index 0000000..99330ce
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/PardisoSupport
@@ -0,0 +1,30 @@
+#ifndef EIGEN_PARDISOSUPPORT_MODULE_H
+#define EIGEN_PARDISOSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include
+
+#include
+
+/** \ingroup Support_modules
+ * \defgroup PardisoSupport_Module PardisoSupport module
+ *
+ * This module brings support for the Intel(R) MKL PARDISO direct sparse solvers.
+ *
+ * \code
+ * #include
+ * \endcode
+ *
+ * In order to use this module, the MKL headers must be accessible from the include paths, and your binary must be linked to the MKL library and its dependencies.
+ * See this \ref TopicUsingIntelMKL "page" for more information on MKL-Eigen integration.
+ *
+ */
+
+#include "src/PardisoSupport/PardisoSupport.h"
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_PARDISOSUPPORT_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QR b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QR
new file mode 100644
index 0000000..ac5b026
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QR
@@ -0,0 +1,45 @@
+#ifndef EIGEN_QR_MODULE_H
+#define EIGEN_QR_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "Cholesky"
+#include "Jacobi"
+#include "Householder"
+
+/** \defgroup QR_Module QR module
+ *
+ *
+ *
+ * This module provides various QR decompositions
+ * This module also provides some MatrixBase methods, including:
+ * - MatrixBase::qr(),
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/misc/Solve.h"
+#include "src/QR/HouseholderQR.h"
+#include "src/QR/FullPivHouseholderQR.h"
+#include "src/QR/ColPivHouseholderQR.h"
+#ifdef EIGEN_USE_LAPACKE
+#include "src/QR/HouseholderQR_MKL.h"
+#include "src/QR/ColPivHouseholderQR_MKL.h"
+#endif
+
+#ifdef EIGEN2_SUPPORT
+#include "src/Eigen2Support/QR.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#ifdef EIGEN2_SUPPORT
+#include "Eigenvalues"
+#endif
+
+#endif // EIGEN_QR_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QtAlignedMalloc b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QtAlignedMalloc
new file mode 100644
index 0000000..46f7d83
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/QtAlignedMalloc
@@ -0,0 +1,34 @@
+
+#ifndef EIGEN_QTMALLOC_MODULE_H
+#define EIGEN_QTMALLOC_MODULE_H
+
+#include "Core"
+
+#if (!EIGEN_MALLOC_ALREADY_ALIGNED)
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+void *qMalloc(size_t size)
+{
+ return Eigen::internal::aligned_malloc(size);
+}
+
+void qFree(void *ptr)
+{
+ Eigen::internal::aligned_free(ptr);
+}
+
+void *qRealloc(void *ptr, size_t size)
+{
+ void* newPtr = Eigen::internal::aligned_malloc(size);
+ memcpy(newPtr, ptr, size);
+ Eigen::internal::aligned_free(ptr);
+ return newPtr;
+}
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif
+
+#endif // EIGEN_QTMALLOC_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SPQRSupport b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SPQRSupport
new file mode 100644
index 0000000..7f1eb47
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SPQRSupport
@@ -0,0 +1,29 @@
+#ifndef EIGEN_SPQRSUPPORT_MODULE_H
+#define EIGEN_SPQRSUPPORT_MODULE_H
+
+#include "SparseCore"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include "SuiteSparseQR.hpp"
+
+/** \ingroup Support_modules
+ * \defgroup SPQRSupport_Module SuiteSparseQR module
+ *
+ * This module provides an interface to the SPQR library, which is part of the suitesparse package.
+ *
+ * \code
+ * #include
+ * \endcode
+ *
+ * In order to use this module, the SPQR headers must be accessible from the include paths, and your binary must be linked to the SPQR library and its dependencies (Cholmod, AMD, COLAMD,...).
+ * For a cmake based project, you can use our FindSPQR.cmake and FindCholmod.Cmake modules
+ *
+ */
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+#include "src/CholmodSupport/CholmodSupport.h"
+#include "src/SPQRSupport/SuiteSparseQRSupport.h"
+
+#endif
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SVD b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SVD
new file mode 100644
index 0000000..fd31001
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SVD
@@ -0,0 +1,37 @@
+#ifndef EIGEN_SVD_MODULE_H
+#define EIGEN_SVD_MODULE_H
+
+#include "QR"
+#include "Householder"
+#include "Jacobi"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/** \defgroup SVD_Module SVD module
+ *
+ *
+ *
+ * This module provides SVD decomposition for matrices (both real and complex).
+ * This decomposition is accessible via the following MatrixBase method:
+ * - MatrixBase::jacobiSvd()
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "src/misc/Solve.h"
+#include "src/SVD/JacobiSVD.h"
+#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)
+#include "src/SVD/JacobiSVD_MKL.h"
+#endif
+#include "src/SVD/UpperBidiagonalization.h"
+
+#ifdef EIGEN2_SUPPORT
+#include "src/Eigen2Support/SVD.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_SVD_MODULE_H
+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Sparse b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Sparse
new file mode 100644
index 0000000..7cc9c09
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/Sparse
@@ -0,0 +1,27 @@
+#ifndef EIGEN_SPARSE_MODULE_H
+#define EIGEN_SPARSE_MODULE_H
+
+/** \defgroup Sparse_Module Sparse meta-module
+ *
+ * Meta-module including all related modules:
+ * - \ref SparseCore_Module
+ * - \ref OrderingMethods_Module
+ * - \ref SparseCholesky_Module
+ * - \ref SparseLU_Module
+ * - \ref SparseQR_Module
+ * - \ref IterativeLinearSolvers_Module
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#include "SparseCore"
+#include "OrderingMethods"
+#include "SparseCholesky"
+#include "SparseLU"
+#include "SparseQR"
+#include "IterativeLinearSolvers"
+
+#endif // EIGEN_SPARSE_MODULE_H
+
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCholesky b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCholesky
new file mode 100644
index 0000000..9f5056a
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCholesky
@@ -0,0 +1,47 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2008-2013 Gael Guennebaud
+//
+// This Source Code Form is subject to the terms of the Mozilla
+// Public License v. 2.0. If a copy of the MPL was not distributed
+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef EIGEN_SPARSECHOLESKY_MODULE_H
+#define EIGEN_SPARSECHOLESKY_MODULE_H
+
+#include "SparseCore"
+#include "OrderingMethods"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+/**
+ * \defgroup SparseCholesky_Module SparseCholesky module
+ *
+ * This module currently provides two variants of the direct sparse Cholesky decomposition for selfadjoint (hermitian) matrices.
+ * Those decompositions are accessible via the following classes:
+ * - SimplicialLLt,
+ * - SimplicialLDLt
+ *
+ * Such problems can also be solved using the ConjugateGradient solver from the IterativeLinearSolvers module.
+ *
+ * \code
+ * #include
+ * \endcode
+ */
+
+#ifdef EIGEN_MPL2_ONLY
+#error The SparseCholesky module has nothing to offer in MPL2 only mode
+#endif
+
+#include "src/misc/Solve.h"
+#include "src/misc/SparseSolve.h"
+#include "src/SparseCholesky/SimplicialCholesky.h"
+
+#ifndef EIGEN_MPL2_ONLY
+#include "src/SparseCholesky/SimplicialCholesky_impl.h"
+#endif
+
+#include "src/Core/util/ReenableStupidWarnings.h"
+
+#endif // EIGEN_SPARSECHOLESKY_MODULE_H
diff --git a/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCore b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCore
new file mode 100644
index 0000000..24bcf01
--- /dev/null
+++ b/ARToolKitUWP/ARToolKit5/src/KPM/FreakMatcher/Eigen/SparseCore
@@ -0,0 +1,64 @@
+#ifndef EIGEN_SPARSECORE_MODULE_H
+#define EIGEN_SPARSECORE_MODULE_H
+
+#include "Core"
+
+#include "src/Core/util/DisableStupidWarnings.h"
+
+#include
+#include