/* Panoama_Tools - Generate, Edit and Convert Panoramic Images Copyright (C) 1998,1999 - Helmut Dersch der@fh-furtwangen.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this software; see the file COPYING. If not, a copy can be downloaded from http://www.gnu.org/licenses/gpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Modifications by Max Lyons (maxlyons@erols.com): March 16, 2002. Added LINE_LENGTH to increase the amount of memory allocated when reading optimizer scripts. Needed to reduce constraint on number of parameters than can be read by optimizer / *------------------------------------------------------------*/ /* Modifications by Fulvio Senore, June.2004 Added support for a new letter "f" to enable fast pisels transform in "ReadModeDescription()" Added code between // FS+ and // FS- / *------------------------------------------------------------*/ #define _CRT_SECURE_NO_WARNINGS #include #include #include /* strcpy_unsecure() is equivalent to strcpy() */ /* to get rid of warnings. */ void strcpy_unsecure(char* destination, const char* source) { while (0 != (*(destination++) = *(source++))) ; } /* Strncat() is equivalent to strncat() */ /* to get rid of warnings. */ void Strncat(char* destination, const char* source, int max_append_chars_without_null) { while (0 != *destination) destination++; while (--max_append_chars_without_null >= 0 && 0 != (*(destination++) = *(source++))) { } *destination = 0; } /* StrcpyN() */ /* Copies maximal bufsize-1 chars from source to destination. */ /* If bufsize>0, the destination string is always terminated with a zero */ /* even if not all chars of source could be copied. */ /* If strlen(source)+1 < bufsize, the remaining memory in destination */ /* is NOT padded with zeros. */ /* The possibly dangerous cases that source[] and destination[] */ /* are partially overlapping is handled correctly, but in this case the */ /* the source string must not be further used after the call of */ /* StrcpyN() because it will be destroyed. */ void StrcpyN(char* destination, const char* source, int64_t bufsize) { int64_t L; if (bufsize <= 0) { return; } L = (int64_t)strlen(source); if (source >= destination) { if (L >= bufsize) { while (0 != --bufsize) { *(destination++) = *(source++); } *destination = 0; } else { while (0 != (*(destination++) = *(source++))) ; } } else { if (L >= bufsize) { source += bufsize - 1; destination += bufsize - 1; *destination = 0; while (0 != --bufsize) { *(--destination) = *(--source); } } else { source += L; destination += L; do { *(destination--) = *(source--); } while (0 != (L--)); } } } /* Strdup(): equivalent to strdup() */ /* To get rid of the Visual C warning C4996: 'strdup': The POSIX name for this item is deprecated */ char* Strdup(char* src) { char* dup; dup = (char*)malloc(strlen(src) + 1); strcpy_unsecure(dup, src); return dup; } /* NrTokensSeparatedBy() */ /* Think the string str is broken into substrings that are sepatared by */ /* one or more sequential chars from the char set in 'delim' */ /* Returns the number of the found substrings. */ int NrTokensSeparatedBy(const char* str, const char* delim) { int n, i; for (n = 0; 0 != *str; ) { while (1) { for (i = 0; 0 != delim[i] && *str != delim[i]; i++) ; if (0 == delim[i]) break; if (0 == *(++str)) return n; } /* found a character *str that is not equal to one of the chars in 'delim', */ /* so a new substring is found. */ ++n; if (0 == *(++str)) return n; while (1) { for (i = 0; 0 != delim[i] && *str != delim[i]; i++) ; if (0 != delim[i]) { /* found a character *str that is equal to one of the chars in 'delim', */ /* so the substring has ended. */ ++str; break; } if (0 == *(++str)) return n; } } return n; } /* Strtok(): equivalent to strtok() */ /* to get rid of warnings. */ char* Strtok(char* s, const char* delim) { static char* p = 0; // start of the next search const char* tmp; char* ret; if (!s) { s = p; if (!s || !delim) { return 0; } } // handle beginning of the string containing delims while (1) { if (0 == *s) { p = 0; return 0; // we've reached the end of the string } for (tmp = delim; 0 != *tmp && *s != *tmp; tmp++) ; if (0 == *tmp) { // now, we've hit a regular character. Let's exit the // loop, and we'd need to give the caller a string // that starts here. break; } /* found the delimiter *tmp in *s */ s++; } ret = s; do { /* s points to non-delimiter, loop until found a delimiter or end of string */ if (0 == *(++s)) { p = 0; // next call will return 0 return ret; } for (tmp = delim; 0 != *tmp && *s != *tmp; tmp++) ; } while (0 == *tmp); /* found the delimiter *tmp in *s */ *s = 0; p = s + 1; return ret; } //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // // float.h // // Copyright (c) Microsoft Corporation. All rights reserved. // // Implementation-defined values commonly used by sophisticated numerical // (floating point) programs. // #pragma once #ifndef _INC_FLOAT // include guard for 3rd party interop #define _INC_FLOAT #include #pragma warning(push) #pragma warning(disable: _UCRT_DISABLED_WARNINGS) _UCRT_DISABLE_CLANG_WARNINGS _CRT_BEGIN_C_HEADER #ifndef _CRT_MANAGED_FP_DEPRECATE #ifdef _CRT_MANAGED_FP_NO_DEPRECATE #define _CRT_MANAGED_FP_DEPRECATE #else #ifdef _M_CEE #define _CRT_MANAGED_FP_DEPRECATE _CRT_DEPRECATE_TEXT("Direct floating point control is not supported or reliable from within managed code. ") #else #define _CRT_MANAGED_FP_DEPRECATE #endif #endif #endif // Define the floating point precision used. // // For x86, results are in double precision (unless /arch:sse2 is used, in which // case results are in source precision. // // For x64 and ARM, results are in source precision. // // If the compiler is invoked with /fp:fast, the compiler is allowed to use the // fastest precision and even mix within a single function, so precision is // indeterminable. // // Note that manipulating the floating point behavior using the float_control/ // fenv_access/fp_contract #pragmas may alter the actual floating point evaluation // method, which may in turn invalidate the value of FLT_EVAL_METHOD. #ifdef _M_FP_FAST #define FLT_EVAL_METHOD -1 #else #ifdef _M_IX86 #if _M_IX86_FP >= 2 #define FLT_EVAL_METHOD 0 #else #define FLT_EVAL_METHOD 2 #endif #else #define FLT_EVAL_METHOD 0 #endif #endif //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // Constants // //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define DBL_DECIMAL_DIG 17 // # of decimal digits of rounding precision #define DBL_DIG 15 // # of decimal digits of precision #define DBL_EPSILON 2.2204460492503131e-016 // smallest such that 1.0+DBL_EPSILON != 1.0 #define DBL_HAS_SUBNORM 1 // type does support subnormal numbers #define DBL_MANT_DIG 53 // # of bits in mantissa #define DBL_MAX 1.7976931348623158e+308 // max value #define DBL_MAX_10_EXP 308 // max decimal exponent #define DBL_MAX_EXP 1024 // max binary exponent #define DBL_MIN 2.2250738585072014e-308 // min positive value #define DBL_MIN_10_EXP (-307) // min decimal exponent #define DBL_MIN_EXP (-1021) // min binary exponent #define _DBL_RADIX 2 // exponent radix #define DBL_TRUE_MIN 4.9406564584124654e-324 // min positive value #define FLT_DECIMAL_DIG 9 // # of decimal digits of rounding precision #define FLT_DIG 6 // # of decimal digits of precision #define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0 #define FLT_HAS_SUBNORM 1 // type does support subnormal numbers #define FLT_GUARD 0 #define FLT_MANT_DIG 24 // # of bits in mantissa #define FLT_MAX 3.402823466e+38F // max value #define FLT_MAX_10_EXP 38 // max decimal exponent #define FLT_MAX_EXP 128 // max binary exponent #define FLT_MIN 1.175494351e-38F // min normalized positive value #define FLT_MIN_10_EXP (-37) // min decimal exponent #define FLT_MIN_EXP (-125) // min binary exponent #define FLT_NORMALIZE 0 #define FLT_RADIX 2 // exponent radix #define FLT_TRUE_MIN 1.401298464e-45F // min positive value #define LDBL_DIG DBL_DIG // # of decimal digits of precision #define LDBL_EPSILON DBL_EPSILON // smallest such that 1.0+LDBL_EPSILON != 1.0 #define LDBL_HAS_SUBNORM DBL_HAS_SUBNORM // type does support subnormal numbers #define LDBL_MANT_DIG DBL_MANT_DIG // # of bits in mantissa #define LDBL_MAX DBL_MAX // max value #define LDBL_MAX_10_EXP DBL_MAX_10_EXP // max decimal exponent #define LDBL_MAX_EXP DBL_MAX_EXP // max binary exponent #define LDBL_MIN DBL_MIN // min normalized positive value #define LDBL_MIN_10_EXP DBL_MIN_10_EXP // min decimal exponent #define LDBL_MIN_EXP DBL_MIN_EXP // min binary exponent #define _LDBL_RADIX _DBL_RADIX // exponent radix #define LDBL_TRUE_MIN DBL_TRUE_MIN // min positive value #define DECIMAL_DIG DBL_DECIMAL_DIG //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // Flags // //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #define _SW_INEXACT 0x00000001 // Inexact (precision) #define _SW_UNDERFLOW 0x00000002 // Underflow #define _SW_OVERFLOW 0x00000004 // Overflow #define _SW_ZERODIVIDE 0x00000008 // Divide by zero #define _SW_INVALID 0x00000010 // Invalid #define _SW_DENORMAL 0x00080000 // Denormal status bit // New Control Bit that specifies the ambiguity in control word. #define _EM_AMBIGUIOUS 0x80000000 // For backwards compatibility #define _EM_AMBIGUOUS 0x80000000 // Abstract User Control Word Mask and bit definitions #define _MCW_EM 0x0008001f // Interrupt Exception Masks #define _EM_INEXACT 0x00000001 // inexact (precision) #define _EM_UNDERFLOW 0x00000002 // underflow #define _EM_OVERFLOW 0x00000004 // overflow #define _EM_ZERODIVIDE 0x00000008 // zero divide #define _EM_INVALID 0x00000010 // invalid #define _EM_DENORMAL 0x00080000 // Denormal exception mask (_control87 only) #define _MCW_RC 0x00000300 // Rounding Control #define _RC_NEAR 0x00000000 // near #define _RC_DOWN 0x00000100 // down #define _RC_UP 0x00000200 // up #define _RC_CHOP 0x00000300 // chop // i386 specific definitions #define _MCW_PC 0x00030000 // Precision Control #define _PC_64 0x00000000 // 64 bits #define _PC_53 0x00010000 // 53 bits #define _PC_24 0x00020000 // 24 bits #define _MCW_IC 0x00040000 // Infinity Control #define _IC_AFFINE 0x00040000 // affine #define _IC_PROJECTIVE 0x00000000 // projective // RISC specific definitions #define _MCW_DN 0x03000000 // Denormal Control #define _DN_SAVE 0x00000000 // save denormal results and operands #define _DN_FLUSH 0x01000000 // flush denormal results and operands to zero #define _DN_FLUSH_OPERANDS_SAVE_RESULTS 0x02000000 // flush operands to zero and save results #define _DN_SAVE_OPERANDS_FLUSH_RESULTS 0x03000000 // save operands and flush results to zero // Invalid subconditions (_SW_INVALID also set) #define _SW_UNEMULATED 0x0040 // Unemulated instruction #define _SW_SQRTNEG 0x0080 // Square root of a negative number #define _SW_STACKOVERFLOW 0x0200 // FP stack overflow #define _SW_STACKUNDERFLOW 0x0400 // FP stack underflow // Floating point error signals and return codes #define _FPE_INVALID 0x81 #define _FPE_DENORMAL 0x82 #define _FPE_ZERODIVIDE 0x83 #define _FPE_OVERFLOW 0x84 #define _FPE_UNDERFLOW 0x85 #define _FPE_INEXACT 0x86 #define _FPE_UNEMULATED 0x87 #define _FPE_SQRTNEG 0x88 #define _FPE_STACKOVERFLOW 0x8a #define _FPE_STACKUNDERFLOW 0x8b #define _FPE_EXPLICITGEN 0x8c // raise(SIGFPE); // On x86 with arch:SSE2, the OS returns these exceptions #define _FPE_MULTIPLE_TRAPS 0x8d #define _FPE_MULTIPLE_FAULTS 0x8e #define _FPCLASS_SNAN 0x0001 // signaling NaN #define _FPCLASS_QNAN 0x0002 // quiet NaN #define _FPCLASS_NINF 0x0004 // negative infinity #define _FPCLASS_NN 0x0008 // negative normal #define _FPCLASS_ND 0x0010 // negative denormal #define _FPCLASS_NZ 0x0020 // -0 #define _FPCLASS_PZ 0x0040 // +0 #define _FPCLASS_PD 0x0080 // positive denormal #define _FPCLASS_PN 0x0100 // positive normal #define _FPCLASS_PINF 0x0200 // positive infinity // Initial Control Word value #if defined _M_IX86 #define _CW_DEFAULT (_RC_NEAR + _PC_53 + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) #elif defined _M_X64 || defined _M_ARM || defined _M_ARM64 #define _CW_DEFAULT (_RC_NEAR + _EM_INVALID + _EM_ZERODIVIDE + _EM_OVERFLOW + _EM_UNDERFLOW + _EM_INEXACT + _EM_DENORMAL) #endif //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // State Manipulation // //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // Note that reading or writing the floating point control or status words is // not supported in managed code. _CRT_MANAGED_FP_DEPRECATE _ACRTIMP unsigned int __cdecl _clearfp(void); #pragma warning(push) #pragma warning(disable: 4141) // Double deprecation _CRT_MANAGED_FP_DEPRECATE _CRT_INSECURE_DEPRECATE(_controlfp_s) _ACRTIMP unsigned int __cdecl _controlfp( _In_ unsigned int _NewValue, _In_ unsigned int _Mask ); #pragma warning(pop) _CRT_MANAGED_FP_DEPRECATE _ACRTIMP void __cdecl _set_controlfp( _In_ unsigned int _NewValue, _In_ unsigned int _Mask ); _CRT_MANAGED_FP_DEPRECATE _ACRTIMP errno_t __cdecl _controlfp_s( _Out_opt_ unsigned int* _CurrentState, _In_ unsigned int _NewValue, _In_ unsigned int _Mask ); _CRT_MANAGED_FP_DEPRECATE _ACRTIMP unsigned int __cdecl _statusfp(void); _CRT_MANAGED_FP_DEPRECATE _ACRTIMP void __cdecl _fpreset(void); #ifdef _M_IX86 _CRT_MANAGED_FP_DEPRECATE _ACRTIMP void __cdecl _statusfp2( _Out_opt_ unsigned int* _X86Status, _Out_opt_ unsigned int* _SSE2Status ); #endif #define _clear87 _clearfp #define _status87 _statusfp _CRT_MANAGED_FP_DEPRECATE _ACRTIMP unsigned int __cdecl _control87( _In_ unsigned int _NewValue, _In_ unsigned int _Mask ); #ifdef _M_IX86 _CRT_MANAGED_FP_DEPRECATE _ACRTIMP int __cdecl __control87_2( _In_ unsigned int _NewValue, _In_ unsigned int _Mask, _Out_opt_ unsigned int* _X86ControlWord, _Out_opt_ unsigned int* _Sse2ControlWord ); #endif // Global variable holding floating point error code _Check_return_ _ACRTIMP int* __cdecl __fpecode(void); #define _fpecode (*__fpecode()) _Check_return_ _ACRTIMP int __cdecl __fpe_flt_rounds(void); #define FLT_ROUNDS (__fpe_flt_rounds()) #define _DBL_ROUNDS FLT_ROUNDS #define _LDBL_ROUNDS _DBL_ROUNDS //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // IEEE Recommended Functions // //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ _Check_return_ _ACRTIMP double __cdecl _copysign(_In_ double _Number, _In_ double _Sign); _Check_return_ _ACRTIMP double __cdecl _chgsign(_In_ double _X); _Check_return_ _ACRTIMP double __cdecl _scalb(_In_ double _X, _In_ long _Y); _Check_return_ _ACRTIMP double __cdecl _logb(_In_ double _X); _Check_return_ _ACRTIMP double __cdecl _nextafter(_In_ double _X, _In_ double _Y); _Check_return_ _ACRTIMP int __cdecl _finite(_In_ double _X); _Check_return_ _ACRTIMP int __cdecl _isnan(_In_ double _X); _Check_return_ _ACRTIMP int __cdecl _fpclass(_In_ double _X); #ifdef _M_X64 _Check_return_ _ACRTIMP float __cdecl _scalbf(_In_ float _X, _In_ long _Y); #endif //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ // // Nonstandard Names for Compatibility // //-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ #if defined(_CRT_INTERNAL_NONSTDC_NAMES) && _CRT_INTERNAL_NONSTDC_NAMES #define clear87 _clear87 #define status87 _status87 #define control87 _control87 _CRT_MANAGED_FP_DEPRECATE _ACRTIMP void __cdecl fpreset(void); #define DBL_RADIX _DBL_RADIX #define DBL_ROUNDS _DBL_ROUNDS #define LDBL_RADIX _LDBL_RADIX #define LDBL_ROUNDS _LDBL_ROUNDS // For backwards compatibility with the old spelling #define EM_AMBIGUIOUS _EM_AMBIGUOUS #define EM_AMBIGUOUS _EM_AMBIGUOUS #define MCW_EM _MCW_EM #define EM_INVALID _EM_INVALID #define EM_DENORMAL _EM_DENORMAL #define EM_ZERODIVIDE _EM_ZERODIVIDE #define EM_OVERFLOW _EM_OVERFLOW #define EM_UNDERFLOW _EM_UNDERFLOW #define EM_INEXACT _EM_INEXACT #define MCW_IC _MCW_IC #define IC_AFFINE _IC_AFFINE #define IC_PROJECTIVE _IC_PROJECTIVE #define MCW_RC _MCW_RC #define RC_CHOP _RC_CHOP #define RC_UP _RC_UP #define RC_DOWN _RC_DOWN #define RC_NEAR _RC_NEAR #define MCW_PC _MCW_PC #define PC_24 _PC_24 #define PC_53 _PC_53 #define PC_64 _PC_64 #define CW_DEFAULT _CW_DEFAULT #define SW_INVALID _SW_INVALID #define SW_DENORMAL _SW_DENORMAL #define SW_ZERODIVIDE _SW_ZERODIVIDE #define SW_OVERFLOW _SW_OVERFLOW #define SW_UNDERFLOW _SW_UNDERFLOW #define SW_INEXACT _SW_INEXACT #define SW_UNEMULATED _SW_UNEMULATED #define SW_SQRTNEG _SW_SQRTNEG #define SW_STACKOVERFLOW _SW_STACKOVERFLOW #define SW_STACKUNDERFLOW _SW_STACKUNDERFLOW #define FPE_INVALID _FPE_INVALID #define FPE_DENORMAL _FPE_DENORMAL #define FPE_ZERODIVIDE _FPE_ZERODIVIDE #define FPE_OVERFLOW _FPE_OVERFLOW #define FPE_UNDERFLOW _FPE_UNDERFLOW #define FPE_INEXACT _FPE_INEXACT #define FPE_UNEMULATED _FPE_UNEMULATED #define FPE_SQRTNEG _FPE_SQRTNEG #define FPE_STACKOVERFLOW _FPE_STACKOVERFLOW #define FPE_STACKUNDERFLOW _FPE_STACKUNDERFLOW #define FPE_EXPLICITGEN _FPE_EXPLICITGEN #endif // _CRT_INTERNAL_NONSTDC_NAMES _CRT_END_C_HEADER _UCRT_RESTORE_CLANG_WARNINGS #pragma warning(pop) // _UCRT_DISABLED_WARNINGS #endif // _INC_FLOAT //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // pt_stdint.h /* * This file is created to guarantee compatibility with MS Compiler * * Under GNU gcc, data types are defined based on their lenght, but under * MSC, they don't exist, so here they are defined * * pt_stdint.h */ #ifndef PT_STDINT__H #define PT_STDINT__H // define some int #if defined _MSC_VER && _MSC_VER<1600 /* Microsoft Visual C++ */ typedef signed char int8_t; typedef short int int16_t; typedef int int32_t; typedef __int64 int64_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; /* no uint64_t */ #define INT32_MAX _I32_MAX # else /* #ifdef _MSC_VER */ #include #endif /* #ifdef _MSC_VER */ #ifdef _MSC_VER #if _MSC_VER < 1900 #define vsnprintf _vsnprintf #define snprintf _snprintf #endif #ifdef _CPLUSPLUS /* define if your compiler understands inline commands */ #define INLINE _inline #else #define INLINE #endif # else /* #ifdef _MSC_VER */ #ifndef INLINE #define INLINE inline #endif #endif /* #ifdef _MSC_VER */ #endif //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // panorama.h /* Panorama_Tools - Generate, Edit and Convert Panoramic Images Copyright (C) 1998,1999 - Helmut Dersch der@fh-furtwangen.de This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this software; see the file COPYING. If not, a copy can be downloaded from http://www.gnu.org/licenses/gpl.html, or obtained by writing to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*------------------------------------------------------------*/ #ifndef PANORAMA_H #define PANORAMA_H #define USE_SPARSE_LEVENBERG_MARQUARDT #define CAN_READ_HUGIN_FILES #if defined _WIN32 && defined PANO13_DLL #if defined pano13_EXPORTS #define PANO13_IMPEX __declspec(dllexport) #else #define PANO13_IMPEX __declspec(dllimport) #endif #else #define PANO13_IMPEX #endif //#include "pt_stdint.h" //#include "version.h" //#include "panotypes.h" // MRDL: Replaced BIGENDIAN with PT_BIGENDIAN to eliminate conflict with // BIGENDIAN defined in winsock2.h distributed with MingW 2.0 // Determine which machine we are using. Macs are set to PT_BIGENDIAN, all others not // If you need PT_BIGENDIAN, and don't use MacOS, define it here: //#define PT_BIGENDIAN 1 typedef unsigned char Boolean; // Create a definition if we're on a Windows machine: #ifndef __Ansi__ #if (defined(MSDOS) || defined(_CONSOLE) || defined(__DOS__) || defined(__MSDOS__)) #define __Ansi__ 1 #endif #endif #ifndef __Win__ #if (defined(_WINDOWS) || defined(WINDOWS)) #define __Win__ 1 #endif #endif #ifndef __Mac_OSX__ #if defined(__APPLE_CC__) #define __Mac_OSX__ 1 #if (defined(__ppc__) || defined(__ppc64__)) #define PT_BIGENDIAN 1 #elif defined(__i386__) #undef PT_BIGENDIAN #endif #endif #endif // Use FSSpec on Macs as Path-specifyers, else strings #define PATH_SEP '/' #ifdef _WIN32 #ifndef __NO_SYSTEM__ #include // including this causes problems with libjpeg #endif #define MAX_PATH_LENGTH 260 // was MAX_PATH #undef PATH_SEP #define PATH_SEP '\\' #else #define MAX_PATH_LENGTH 512 #endif // I really want to get rid of this one. it is legacy from OS 9 typedef struct { char name[MAX_PATH_LENGTH]; } fullPath; // Some important defaults (perhaps to be moved somewhere else later // Enumerates for TrFormStr.tool enum { // Panorama Tools _perspective, _correct, _remap, _adjust, _interpolate, _sizep, // dummy for size-preferences _version, // dummy for version _panright, // Pan Controls _panleft, _panup, _pandown, _zoomin, _zoomout, _apply, _getPano, _increment }; // Enumerates for TrFormStr.mode enum { // Modes _interactive, // display dialogs and do Xform _useprefs, // load saved prefs and do Xform/ no dialogs _setprefs, // display dialogs and set preferences, no Xform _usedata, // use supplied data in TrFormStr.data, do Xform _honor_valid = 8, // Use only pixels with alpha channel set _show_progress = 16, // Interpolator displays progress bar _hostCanResize = 32, // o-no; 1-yes (Photoshop: no; GraphicConverter: yes) _destSupplied = 64, // Destination image allocated by plug-in host _wrapX = 128 // Wrap image horizontally (if HFOV==360 degrees) }; // Enumerates for Image.dataformat enum { _RGB, _Lab, _Grey }; // Enumerates for TrFormStr.interpolator enum { // Interpolators _poly3 = 0, // Third order polynomial fitting 16 nearest pixels _spline16 = 1, // Cubic Spline fitting 16 nearest pixels _spline36 = 2, // Cubic Spline fitting 36 nearest pixels _sinc256 = 3, // Sinc windowed to 8 pixels _spline64, // Cubic Spline fitting 64 nearest pixels _bilinear, // Bilinear interpolation _nn, // Nearest neighbor _sinc1024, // Thomas Rauscher: New antialiasing filter. // Plots of the functions are available at http://www.pano2qtvr.com/dll_patch/ _aabox, // Antialiasing: Box _aatriangle, // Antialiasing: Bartlett/Triangle Filter _aahermite, // Antialiasing: Hermite Filter _aahanning, // Antialiasing: Hanning Filter _aahamming, // Antialiasing: Hamming Filter _aablackman, // Antialiasing: Blackmann Filter _aagaussian, // Antialiasing: Gaussian 1/sqrt(2) Filter (blury) _aagaussian2, // Antialiasing: Gaussian 1/2 Filter (sharper) _aaquadratic, // Antialiasing: Quadardic Filter _aacubic, // Antialiasing: Cubic Filter _aacatrom, // Antialiasing: Catmull-Rom Filter _aamitchell, // Antialiasing: Mitchell Filter _aalanczos2, // Antialiasing: Lanczos2 Filter _aalanczos3, // Antialiasing: Lanczos3 Filter _aablackmanbessel, // Antialiasing: Blackman/Bessel Filter _aablackmansinc // Antialiasing: Blackman/sinc Filter }; // Corrections struct correct_Prefs { // Preferences structure for tool correct uint32_t magic; // File validity check, must be 20 int radial; // Radial correction requested? double radial_params[3][5]; // 3 colors x (4 coeffic. for 3rd order polys + correction radius) int vertical; // Vertical shift requested ? double vertical_params[3]; // 3 colors x vertical shift value int horizontal; // horizontal tilt ( in screenpoints) double horizontal_params[3]; // 3 colours x horizontal shift value int shear; // shear correction requested? double shear_x; // horizontal shear values double shear_y; // vertical shear values int tilt; // tilt correction requested? double tilt_x; // tilt on x values double tilt_y; // tilt on y values double tilt_z; // tilt on z values double tilt_scale; // scale for tilting int trans; // translation of camera plane requested? double trans_x; // x component of translation vector double trans_y; // y component of translation vector double trans_z; // z component of translation vector double trans_yaw; // yaw of remapping plane for translation double trans_pitch; // pitch of remapping plane for translation int test; // these parameters are for testing new projections double test_p0; // and make it easier for others to experiment double test_p1; // double test_p2; // double test_p3; // int resize; // scaling requested ? uint32_t width; // new width uint32_t height; // new height int luminance; // correct luminance variation? double lum_params[3]; // parameters for luminance corrections int correction_mode; // 0 - radial correction;1 - vertical correction;2 - deregistration int cutFrame; // remove frame? 0 - no; 1 - yes int fwidth; int fheight; int frame; int fourier; // Fourier filtering requested? int fourier_mode; // _faddBlurr vs _fremoveBlurr fullPath psf; // Point Spread Function, full path/fsspec to psd-file int fourier_nf; // Noise filtering: _nf_internal vs _nf_custom fullPath nff; // noise filtered file: full path/fsspec to psd-file double filterfactor; // Hunt factor double fourier_frame; // To correct edge errors }; typedef struct correct_Prefs cPrefs; enum { correction_mode_radial = 0, correction_mode_vertical = 1, correction_mode_deregister = 2, correction_mode_morph = 4 }; enum { _faddBlurr, _fremoveBlurr, _nf_internal, _nf_custom, _fresize, _flogtransform }; enum { // Enumerates for Image.format _rectilinear = 0, // (Standand) FOV (rectilinear) = 2 * arctan (frame size/(focal length * 2)) _panorama = 1, // Cylindrical _fisheye_circ = 2, // fisheye-equidistance Circular _fisheye_ff = 3, // fisheye-equidistance Full Frame _equirectangular = 4, _spherical_cp = 5, // Fisheye-Horizontal is an image shot with the camera held horizontally. The equator is now in the center of the image. _spherical_tp = 6, // Fisheye-vertical is an image shot with the camera held vertically up. The panorama is extracted from the circumpherence of the image. _mirror = 7, // convex mirror. This is the reflection of a convex, spherical image. The horizontal field of view is calculated using the formula HFov = 2*arcsin(radius of mirror/radius of curvature of mirror) _orthographic = 8, // fisheye-orthographic FOV (orthogonal fisheye) = 2 * arcsin (frame size/(focal length *2) _cubic = 9, _stereographic = 10, // fisheye stereographic FOV (stereographic fisheye) = 4 * arctan (frame size/(focal length * 4)) _mercator = 11, _trans_mercator = 12, _trans_panorama = 13, _sinusoidal = 14, _lambert = 15, _lambertazimuthal = 16, _albersequalareaconic = 17, _millercylindrical = 18, _panini = 19, _architectural = 20, _equisolid = 21, // fisheye-equisolid FOV (equisolid fisheye) = 4 * arcsin (frame size/(focal length * 4)) _equipanini = 22, _biplane = 23, _triplane = 24, _panini_general = 25, _thoby = 26, // generalizes the model found in modern fisheye lenses. It is // parametrizable but it defaults to the Nikkor 10.5 fisheye lens _hammer = 27, }; enum { // Enumerates external number of panorama f PANO_FORMAT_RECTILINEAR = 0, PANO_FORMAT_PANORAMA = 1, PANO_FORMAT_EQUIRECTANGULAR = 2, PANO_FORMAT_FISHEYE_FF = 3, PANO_FORMAT_STEREOGRAPHIC = 4, PANO_FORMAT_MERCATOR = 5, PANO_FORMAT_TRANS_MERCATOR = 6, PANO_FORMAT_SINUSOIDAL = 7, PANO_FORMAT_LAMBERT_EQUAL_AREA_CONIC = 8, PANO_FORMAT_LAMBERT_AZIMUTHAL = 9, PANO_FORMAT_ALBERS_EQUAL_AREA_CONIC = 10, PANO_FORMAT_MILLER_CYLINDRICAL = 11, PANO_FORMAT_PANINI = 12, PANO_FORMAT_ARCHITECTURAL = 13, PANO_FORMAT_ORTHOGRAPHIC = 14, PANO_FORMAT_EQUISOLID = 15, PANO_FORMAT_EQUI_PANINI = 16, PANO_FORMAT_BIPLANE = 17, PANO_FORMAT_TRIPLANE = 18, PANO_FORMAT_PANINI_GENERAL = 19, PANO_FORMAT_THOBY = 20, PANO_FORMAT_HAMMER = 21, }; #define PANO_FORMAT_COUNT 22 enum { // Enumerates external number of image f IMAGE_FORMAT_RECTILINEAR = 0, IMAGE_FORMAT_PANORAMA = 1, IMAGE_FORMAT_FISHEYE_EQUIDISTANCECIRC = 2, IMAGE_FORMAT_FISHEYE_EQUIDISTANCEFF = 3, IMAGE_FORMAT_EQUIRECTANGULAR = 4, IMAGE_FORMAT_MIRROR = 7, IMAGE_FORMAT_FISHEYE_ORTHOGRAPHIC = 8, IMAGE_FORMAT_FISHEYE_STEREOGRAPHIC = 10, IMAGE_FORMAT_FISHEYE_EQUISOLID = 21, IMAGE_FORMAT_FISHEYE_THOBY = PANO_FORMAT_THOBY, }; #define IMAGE_FORMAT_COUNT 10 // A large rectangle typedef struct { int32_t top; int32_t bottom; int32_t left; int32_t right; } PTRect; typedef struct { uint32_t full_width; uint32_t full_height; uint32_t cropped_width; uint32_t cropped_height; uint32_t x_offset; uint32_t y_offset; } CropInfo; typedef struct { uint32_t fullWidth; uint32_t fullHeight; uint32_t croppedWidth; uint32_t croppedHeight; uint32_t xOffset; uint32_t yOffset; } pano_CropInfo; typedef struct { uint16_t type; uint16_t predictor; } pano_TiffCompression; typedef struct { uint32_t size; char* data; } pano_ICCProfile; typedef struct { // Full size of image uint32_t imageWidth; uint32_t imageHeight; int isCropped; float xPixelsPerResolution; float yPixelsPerResolution; uint16_t resolutionUnits; uint16_t samplesPerPixel; uint16_t bitsPerSample; int bytesPerLine; // Equal to the scanlinesize uint32_t rowsPerStrip; pano_TiffCompression compression; pano_ICCProfile iccProfile; pano_CropInfo cropInfo; // other metadata char* copyright; char* datetime; char* imageDescription; char* artist; uint16_t imageNumber; // saved in the page number TIFF field uint16_t imageTotalNumber; // total number of images // These fields are computed int bytesPerPixel; // This is a common value to use int bitsPerPixel; // This is a common value to use } pano_ImageMetadata; // THe following constants define the number of parameters used by a projection // THe first is the number provided by the user. In most cases it is // zero, sometimes 1 and sometimes 2. // The second is the number of internally used parameters. THis is // used for optimization purposes, as some projections require to compute // the same value over and over again. // This are the maximum number of parameters accepted by a given projection #define PANO_PROJECTION_MAX_PARMS 6 // This are the maximum number of internal parameters used by a given projection #define PANO_PROJECTION_PRECOMPUTED_VALUES 10 #ifdef CAN_READ_HUGIN_FILES enum { HuginImgInfoLineSize = 1024 }; extern char LastHuginImgInfoLine[HuginImgInfoLineSize + 1]; #endif // CAN_READ_HUGIN_FILES struct Image { // Pixel data uint32_t width; uint32_t height; uint32_t bytesPerLine; uint32_t bitsPerPixel; // Must be 24 or 32 size_t dataSize; unsigned char** data; int32_t dataformat; // rgb, Lab etc int32_t format; // Projection: rectilinear etc int formatParamCount; // Number of format parameters. double formatParam[PANO_PROJECTION_MAX_PARMS]; // Parameters for format. int precomputedCount; // number of values precomputed for a given pano double precomputedValue[PANO_PROJECTION_PRECOMPUTED_VALUES]; // to speed up pano creation double hfov; double yaw; double pitch; double roll; cPrefs cP; // How to correct the image char name[MAX_PATH_LENGTH]; PTRect selection; CropInfo cropInformation; // TO BE DEPRECATED pano_ImageMetadata metadata; #ifdef CAN_READ_HUGIN_FILES double Ra, Rb, Rc, Rd, Re; double Eev, Er, Eb; int Vm; double Va, Vb, Vc, Vd; double Vx, Vy; char Vfilename[MAX_PATH_LENGTH]; int jStackNr; char HuginImgInfoLine[HuginImgInfoLineSize + 1]; #endif // CAN_READ_HUGIN_FILES }; typedef struct Image Image; #ifdef CAN_READ_HUGIN_FILES enum { PanoramaImageTParamSize = 16 }; struct PanoImageInfo { int pto_format; int k; int d; int b; int u; uint32_t SelLeft, SelRight, SelTop, SelBottom; char TParam[PanoramaImageTParamSize + 1]; int RParam; double EParam; }; typedef struct PanoImageInfo PanoImageInfo; struct HuginImageMask { int image_nr; int type; int numcoords; double* coords; }; typedef struct HuginImageMask HuginImageMask; #endif // CAN_READ_HUGIN_FILES struct TrformStr // This structure holds all image information { Image* src; // Source image, must be supplied on entry Image* dest; // Destination image data, valid if success = 1 int32_t success; // 0 - no, 1 - yes int32_t tool; // Panorama Tool requested int32_t mode; // how to run transformation void* data; // data for tool requested. // Required only if mode = _usedata; then it // must point to valid preferences structure // for requested tool (see filter.h). int32_t interpolator;// Select interpolator double gamma; // Gamma value for internal gamma correction int fastStep; // 0 no fast Transformation (default), FAST_TRANSFORM_STEP_MORPH, FAST_TRANSFORM_STEP_NORMAL }; typedef struct TrformStr TrformStr; // Useful for looping through images #define LOOP_IMAGE( image, action ) { int x,y,bpp=(image)->bitsPerPixel/8; \ unsigned char *idata; \ for(y=0; y<(image)->height; y++){ \ idata = *((image)->data) + y * (image)->bytesPerLine; \ for(x=0; x<(image)->width;x++, idata+=bpp){ \ action;} } } // These structs are to be used to query the features of the different projection formats typedef struct { double minValue; // used only if float double maxValue; double defValue; // default char* name; // name of the parameter (for the purpose of legibility) } pano_projection_parameter; typedef struct { int projection; int internalFormat; // internal id for Image.format double maxVFOV; // units in degrees double maxHFOV; char* name; int numberOfParameters; // so far we dont have more than 3 parameters pano_projection_parameter parm[PANO_PROJECTION_MAX_PARMS]; } pano_projection_features; PANO13_IMPEX int panoProjectionFeaturesQuery(int projection, pano_projection_features* features); PANO13_IMPEX int panoProjectionFormatCount(void); /** APIs to read dynamic features that depend on projection parameters projection argument is an index, same as for queryFeatures() **/ PANO13_IMPEX int queryFOVLimits(int projection, double* params, /* length depends on projection */ double* lims /* [0] = maxhfov, [1] = maxvfov */ ); //void filter_main(); //#include "PTcommon.h" #endif // PANORAMA_H //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // Filter.h #ifndef FILTER_H #define FILTER_H #include #include #include #include #include #include #include #include //#include "panorama.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef bzero #define bzero(dest, len) memset((dest), 0, (len)) #endif //---------------------- Some useful math defines -------------------------- #ifndef PI #define PI 3.14159265358979323846264338327950288 #endif #ifndef HALF_PI #define HALF_PI (PI*0.5) #endif #define EPSLN 1.0e-10 // Normalize an angle to +/-180degrees #define NORM_ANGLE( x ) while( x >180.0 ) x -= 360.0; while( x < -180.0 ) x += 360.0; #define NORM_ANGLE_RAD( x ) while( (x) >PI ) (x) -= 2 * PI; while( (x) < -PI ) (x) += 2 * PI; // Convert degree to radian #define DEG_TO_RAD( x ) ( (x) * 2.0 * PI / 360.0 ) // and reverse #define RAD_TO_DEG( x ) ( (x) * 360.0 / ( 2.0 * PI ) ) // Convert double x to unsigned char/short c #define DBL_TO_UC( c, x ) if((x)>255.0) c=255U; \ else if((x)<0.0) c=0; \ else c=(unsigned char)floor((x)+0.5); #define DBL_TO_US( c, x ) if((x)>65535.0) c=65535U; \ else if((x)<0.0) c=0; \ else c=(unsigned short)floor((x)+0.5); #define DBL_TO_FL( c, x ) if((x)>1e+038) c=1e+038; \ else if((x)<0.0) c=0; \ else c=(float)(x); #define MAX_FISHEYE_FOV 179.0 extern int JavaUI; // Flag to indicate use of java dialogs PANO13_IMPEX void JPrintError(char* text); #define FAST_TRANSFORM_STEP_NORMAL 40 #define FAST_TRANSFORM_STEP_MORPH 6 #define FAST_TRANSFORM_STEP_NONE 0 struct PTPoint { double x; double y; }; typedef struct PTPoint PTPoint; #define CopyPTPoint( to, from ) memcpy( &to, &from, sizeof( PTPoint )) #define SamePTPoint( p, s ) ((p).x == (s).x && (p).y == (s).y) struct PTLine { PTPoint v[2]; }; typedef struct PTLine PTLine; struct PTTriangle { PTPoint v[3]; }; typedef struct PTTriangle PTTriangle; // Maximum number of controlpoints in a pair of images, which can be read // via Barcodes #define NUMPTS 21 // Randomization of feather in stitching tools #define BLEND_RANDOMIZE 0.1 // Randomization of luminance adjustment in correct filter #define LUMINANCE_RANDOMIZE 0.007 //----------------------- Structures ------------------------------------------- struct remap_Prefs { // Preferences Structure for remap int32_t magic; // File validity check, must be 30 int from; // Image format source image int to; // Image format destination image double hfov; // horizontal field of view /in degrees double vfov; // vertical field of view (usually ignored) }; typedef struct remap_Prefs rPrefs; struct perspective_Prefs { // Preferences structure for tool perspective int32_t magic; // File validity check, must be 40 int format; // rectilinear or fisheye? double hfov; // Horizontal field of view (in degree) double x_alpha; // New viewing direction (x coordinate or angle) double y_beta; // New viewing direction (y coordinate or angle) double gamma; // Angle of rotation int unit_is_cart; // true, if viewing direction is specified in coordinates int width; // new width int height; // new height }; typedef struct perspective_Prefs pPrefs; struct optVars { // Indicate to optimizer which variables to optimize // panotools uses these variables for two purposes: to // determine which variables are used for reference to another one // and to determine which variables to optimize /* 0 */ int hfov, nhfov; double shfov; double whfov; double minhfov; double maxhfov; /* 1 */ int yaw, nyaw; double syaw; double wyaw; double minyaw; double maxyaw; /* 2 */ int pitch, npitch; double spitch; double wpitch; double minpitch; double maxpitch; /* 3 */ int roll, nroll; double sroll; double wroll; double minroll; double maxroll; /* 4 */ int a, na; double sa; double wa; double mina; double maxa; /* 5 */ int b, nb; double sb; double wb; double minb; double maxb; /* 6 */ int c, nc; double sc; double wc; double minc; double maxc; /* 7 */ int d, nd; double sd; double wd; double mind; double maxd; /* 8 */ int e, ne; double se; double we; double mine; double maxe; /* 9 */ int shear_x, nshear_x; double sshear_x; double wshear_x; double minshear_x; double maxshear_x; /* 10 */ int shear_y, nshear_y; double sshear_y; double wshear_y; double minshear_y; double maxshear_y; /* 11 */ int tiltXopt, ntiltXopt; double stiltXopt; double wtiltXopt; double mintiltXopt; double maxtiltXopt; /* 12 */ int tiltYopt, ntiltYopt; double stiltYopt; double wtiltYopt; double mintiltYopt; double maxtiltYopt; /* 13 */ int tiltZopt, ntiltZopt; double stiltZopt; double wtiltZopt; double mintiltZopt; double maxtiltZopt; /* 14 */ int tiltScaleOpt, ntiltScaleOpt; double stiltScaleOpt; double wtiltScaleOpt; double mintiltScaleOpt; double maxtiltScaleOpt; /* 15 */ int transXopt, ntransXopt; double stransXopt; double wtransXopt; double mintransXopt; double maxtransXopt; /* 16 */ int transYopt, ntransYopt; double stransYopt; double wtransYopt; double mintransYopt; double maxtransYopt; /* 17 */ int transZopt, ntransZopt; double stransZopt; double wtransZopt; double mintransZopt; double maxtransZopt; /* 18 */ int transYawOpt, ntransYawOpt; double stransYawOpt; double wtransYawOpt; double mintransYawOpt; double maxtransYawOpt; /* 19 */ int transPitchOpt, ntransPitchOpt; double stransPitchOpt; double wtransPitchOpt; double mintransPitchOpt; double maxtransPitchOpt; /* 20 */ int testP0opt, ntestP0opt; double stestP0opt; double wtestP0opt; double mintestP0opt; double maxtestP0opt; /* 21 */ int testP1opt, ntestP1opt; double stestP1opt; double wtestP1opt; double mintestP1opt; double maxtestP1opt; /* 22 */ int testP2opt, ntestP2opt; double stestP2opt; double wtestP2opt; double mintestP2opt; double maxtestP2opt; /* 23 */ int testP3opt, ntestP3opt; double stestP3opt; double wtestP3opt; double mintestP3opt; double maxtestP3opt; /* 24 */ int nn[24]; int nnz; #ifdef CAN_READ_HUGIN_FILES /************ photometric optimization parameters - not used by PTOptimizer *************/ int Va; double sVa; double wVa; double minVa; double maxVa; int Vb; double sVb; double wVb; double minVb; double maxVb; int Vc; double sVc; double wVc; double minVc; double maxVc; int Vd; double sVd; double wVd; double minVd; double maxVd; int Vx; double sVx; double wVx; double minVx; double maxVx; int Vy; double sVy; double wVy; double minVy; double maxVy; int Ra; double sRa; double wRa; double minRa; double maxRa; int Rb; double sRb; double wRb; double minRb; double maxRb; int Rc; double sRc; double wRc; double minRc; double maxRc; int Rd; double sRd; double wRd; double minRd; double maxRd; int Re; double sRe; double wRe; double minRe; double maxRe; int Eev; double sEev; double wEev; double minEev; double maxEev; int Er; double sEr; double wEr; double minEr; double maxEr; int Eb; double sEb; double wEb; double minEb; double maxEb; #endif // CAN_READ_HUGIN_FILES }; typedef struct optVars optVars; enum { // Enumerates for stBuf.seam _middle, // seam is placed in the middle of the overlap _dest // seam is places at the edge of the image to be inserted }; enum { // Enumerates for colcorrect _colCorrectImage = 1, _colCorrectBuffer = 2, _colCorrectBoth = 3, }; struct stitchBuffer { // Used describe how images should be merged char srcName[256]; // Buffer should be merged to image; 0 if not. char destName[256]; // Converted image (ie pano) should be saved to buffer; 0 if not int feather; // Width of feather int colcorrect; // Should the images be color corrected? int seam; // Where to put the seam (see above) unsigned char psdOpacity; // Opacity of the layer. Currently used only by PSD output. 0 trans, 255 opaque unsigned char psdBlendingMode; // blending mode (photoshop) }; typedef struct stitchBuffer stBuf; struct panControls { // Structure for realtime Panoeditor double panAngle; // The amount by which yaw/pitch are changed per click double zoomFactor; // The percentage for zoom in/out }; typedef struct panControls panControls; enum { // Enumerates for aPrefs.mode _readControlPoints, _runOptimizer, _insert, _extract, _useScript = 8, // else use options }; struct adjust_Prefs { // Preferences structure for tool adjust int32_t magic; // File validity check, must be 50 int32_t mode; // What to do: create Panorama etc? Image im; // Image to be inserted/extracted Image pano; // Panorama to be created/ used for extraction stBuf sBuf; fullPath scriptFile; // On Mac: Cast to FSSpec; else: full path to scriptFile int nt; // morphing triangles PTTriangle* ts; // Source triangles PTTriangle* td; // Destination triangles int interpolator; // Which interpolator to use double gamma; // Gamma correction value int fastStep; // 0 no fast Transformation (default), FAST_TRANSFORM_STEP_MORPH, FAST_TRANSFORM_STEP_NORMAL }; typedef struct adjust_Prefs aPrefs; union panoPrefs { cPrefs cP; pPrefs pP; rPrefs rP; aPrefs aP; panControls pc; }; typedef union panoPrefs panoPrefs; struct size_Prefs { // Preferences structure for 'pref' dialog int32_t magic; // File validity check; must be 70 int displayPart; // Display cropped/framed image ? int saveFile; // Save to tempfile? 0-no, 1-yes fullPath sFile; // Full path to file (short name) int launchApp; // Open sFile ? fullPath lApp; // the Application to launch int interpolator; // Which interpolator to use double gamma; // Gamma correction value int noAlpha; // If new file is created: Don't save mask (Photoshop LE) int optCreatePano; // Optimizer creates panos? 0 no/ 1 yes int fastStep; // 0 no fast Transformation (default), FAST_TRANSFORM_STEP_MORPH, FAST_TRANSFORM_STEP_NORMAL }; typedef struct size_Prefs sPrefs; #if 0 struct controlPoint { // Control Points to adjust images int num[2]; // Indices of Images int x[2]; // x - Coordinates int y[2]; // y - Coordinates int type; // What to optimize: 0-r, 1-x, 2-y }; #endif struct controlPoint { // Control Points to adjust images int num[2]; // Indices of Images double x[2]; // x - Coordinates double y[2]; // y - Coordinates int type; // What to optimize: 0-r, 1-x, 2-y double stddev, weight; // for weighting the contribution of this point pair's alignment error to the sum of squares }; typedef struct controlPoint controlPoint; struct CoordInfo { // Real World 3D coordinates int num; // auxilliary index double x[3]; int set[3]; }; typedef struct CoordInfo CoordInfo; // Some useful macros for vectors #define SCALAR_PRODUCT( v1, v2 ) ( (v1)->x[0]*(v2)->x[0] + (v1)->x[1]*(v2)->x[1] + (v1)->x[2]*(v2)->x[2] ) #define ABS_SQUARED( v ) SCALAR_PRODUCT( v, v ) #define ABS_VECTOR( v ) sqrt( ABS_SQUARED( v ) ) #define CROSS_PRODUCT( v1, v2, r ) { (r)->x[0] = (v1)->x[1] * (v2)->x[2] - (v1)->x[2]*(v2)->x[1]; \ (r)->x[1] = (v1)->x[2] * (v2)->x[0] - (v1)->x[0]*(v2)->x[2]; \ (r)->x[2] = (v1)->x[0] * (v2)->x[1] - (v1)->x[1]*(v2)->x[0]; } #define DIFF_VECTOR( v1, v2, r ) { (r)->x[0] = (v1)->x[0] - (v2)->x[0]; \ (r)->x[1] = (v1)->x[1] - (v2)->x[1]; \ (r)->x[2] = (v1)->x[2] - (v2)->x[2]; } #define DIST_VECTOR( v1, v2 ) sqrt( ((v1)->x[0] - (v2)->x[0]) * ((v1)->x[0] - (v2)->x[0]) + \ ((v1)->x[1] - (v2)->x[1]) * ((v1)->x[1] - (v2)->x[1]) + \ ((v1)->x[2] - (v2)->x[2]) * ((v1)->x[2] - (v2)->x[2]) ) struct transformCoord { // int nump; // Number of p-coordinates CoordInfo* p; // Coordinates "as is" int numr; // Number of r-coordinates CoordInfo* r; // Requested values for coordinates }; typedef struct transformCoord transformCoord; struct tMatrix { double alpha; double beta; double gamma; double x_shift[3]; double scale; }; typedef struct tMatrix tMatrix; struct MakeParams { // Actual parameters used by Xform functions for pano-creation double scale[2]; // scaling factors for resize; double shear[2]; // shear values double rot[2]; // horizontal rotation params void* perspect[2]; // Parameters for perspective control functions double rad[6]; // coefficients for polynomial correction (0,...3) and source width/2 (4) and correction radius (5) double mt[3][3]; // Matrix double distance; double horizontal; double vertical; // Tilt double tilt[4]; // 0 around x, 1 around y, 2 around z, 3 scaling factor // Translation of camera plane double trans[5]; // 0 x, 1 y, 2 z, 3 yaw, 4 pitch // For testing new projections double test[4]; Image* im; Image* pn; }; struct LMStruct { // Parameters used by the Levenberg Marquardt-Solver int m; int n; double* x; double* fvec; double ftol; double xtol; double gtol; int64_t maxfev; double epsfcn; double mindeltax; int forward_diff; double* diag; int mode; double factor; int force_rank_estimation_1; int force_rank_estimation_2; int nprint; int64_t info; int64_t nfev; #ifndef USE_SPARSE_LEVENBERG_MARQUARDT double* fjac; int ldfjac; int64_t* ipvt; double* qtf; double* wa1; double* wa2; double* wa3; double* wa4; #endif }; // function to minimize in Levenberg-Marquardt solver typedef int64_t(*lmfunc)(int64_t m, int64_t n, double x[], double fvec[], int64_t* iflag); struct triangle { int vert[3]; // Three vertices from list int nIm; // number of image for texture mapping }; typedef struct triangle triangle; #ifdef CAN_READ_HUGIN_FILES enum { MaxNrHuginOptions = 1024 }; enum { MaxHuginOptionsCharMemSize = 0x100000 }; #endif // CAN_READ_HUGIN_FILES struct AlignInfo { // Global data structure used by alignment optimization Image* im; // Array of Pointers to Image Structs optVars* opt; // Mark variables to optimize exclusive photometric variables optVars* allopt; // Mark variables to optimize inclusive photometric variables int numIm; // Number of images controlPoint* cpt; // List of Control points triangle* t; // List of triangular faces int nt; // Number of triangular faces int numPts; // Number of Control Points int numParam; // Number of parameters to optimize int nr_var_constraints; // Number of parameters with weight or nonzero standard deviation constraints int* var_constraint_indices; double* initial_cned_parameters; double* cned_parameters_weights; double* min_cned_parameters; double* max_cned_parameters; Image pano; // Panoramic Image decription #ifdef CAN_READ_HUGIN_FILES PanoImageInfo panoinfo; #endif stBuf st; // Info on how to stitch the panorama void* data; lmfunc fcn; sPrefs sP; CoordInfo* cim; // Real World coordinates #ifdef CAN_READ_HUGIN_FILES char* HuginOptionsCharMem; char** HuginOptions; int numhuginmasks; HuginImageMask* huginmasks; #endif // CAN_READ_HUGIN_FILES }; typedef struct AlignInfo AlignInfo; struct OptInfo { int numVars; // Number of variables to fit int numData; // Number of data to fit to int nr_var_constraints; // Number of variables with weight or nonzero standard deviation constraints int (*SetVarsToX)(double* x); // Translate variables to x-values int (*SetXToVars)(double* x); // and reverse lmfunc fcn; // Levenberg Marquardt function measuring quality char message[256]; // info returned by LM-optimizer }; typedef struct OptInfo OptInfo; struct VRPanoOptions { int width; int height; double pan; double tilt; double fov; int codec; int cquality; int progressive; }; typedef struct VRPanoOptions VRPanoOptions; struct MultiLayerImage { int numLayers; Image* Layer; PTRect selection; }; typedef struct MultiLayerImage MultiLayerImage; PANO13_IMPEX void filter_main(TrformStr* TrPtr, sPrefs* spref); // Transformation function type (we have only one...) typedef int (*trfn)(double x_dest, double y_dest, double* x_src, double* y_src, void* params); // Function descriptor to be executed by exec_function struct fDesc { trfn func; // The function to be called void* param; // The parameters to be used }; typedef struct fDesc fDesc; #define SetDesc(fD,f,p) fD.func = f; fD.param = p // Panorama tool type typedef void (*fnPtr)(TrformStr* TrPtr); // Filter function type typedef unsigned char (*flfn)(unsigned char srcPixel, int xc, int yc, void* params); typedef unsigned short (*flfn16)(unsigned short srcPixel, int xc, int yc, void* params); // Interpolating functions for resampler typedef void (*intFunc)(unsigned char* dst, unsigned char** rgb, register double Dx, register double Dy, int color, int SamplesPerPixel); // Filter function type for anti aliasing Filter typedef double (*aaFilter)(const double, const double); // Gamma Correction struct PTGamma { double* DeGamma; unsigned short* Gamma; int ChannelSize; int ChannelStretch; int GammaSize; }; typedef struct PTGamma PTGamma; extern PTGamma glu; // Some macros to find out more about images #define GetBitsPerChannel( im, x ) switch( (im)->bitsPerPixel ) \ { \ case 24: x = 8; break; \ case 32: x = 8; break; \ case 48: x = 16; break; \ case 64: x = 16; break; \ default: x = 8; break; \ } #define GetChannels( im, x ) switch( (im)->bitsPerPixel ) \ { \ case 24: x = 3; break; \ case 32: x = 4; break; \ case 48: x = 3; break; \ case 64: x = 4; break; \ default: x = 3; break; \ } //---------------------------------- Functions identical in all platforms ------------------------ PANO13_IMPEX void dispatch(TrformStr* TrPtr, sPrefs* s); // Entry into platform independent code PANO13_IMPEX void DoTransForm(TrformStr* TrPtr, panoPrefs* p); PANO13_IMPEX void setLibToResFile(void); // MacOS: Get resources from shared lib PANO13_IMPEX void unsetLibToResFile(void); // MacOS: Don't get resources from shared lib enum { // Enumerates used by Progress and infoDlg _initProgress, // display message "argument" _setProgress, // display progress (argument is percentage converted to string) _disposeProgress, // dispose progress indicator _idleProgress // do nothing; on Mac: call waitnextevent; }; PANO13_IMPEX void PT_setProgressFcn(int (*ptr)(int, char*)); // set custom progress callback PANO13_IMPEX int Progress(int command, char* argument); // Progress Reporting PANO13_IMPEX void PT_setInfoDlgFcn(int (*ptr)(int, char*)); // set custom info callback PANO13_IMPEX int infoDlg(int command, char* argument); // Display info: same argumenmts as progress PANO13_IMPEX void PT_setErrorFcn(void (*ptr)(char*, va_list va)); // set custom error function PANO13_IMPEX void PrintError(char* fmt, ...); // Error Reporting PANO13_IMPEX void dieWithError(char* fmt, ...); PANO13_IMPEX int ccommand(char*** argvPtr); // Shell for standalone programs // Panorama Tool functions PANO13_IMPEX void perspective(TrformStr* TrPtr, pPrefs* p); PANO13_IMPEX void correct(TrformStr* TrPtr, cPrefs* c); PANO13_IMPEX void remap(TrformStr* TrPtr, rPrefs* r); PANO13_IMPEX void adjust(TrformStr* TrPtr, aPrefs* a); PANO13_IMPEX void pan(TrformStr* TrPtr, panControls* pc); // Set Struct defaults PANO13_IMPEX void SetPrefDefaults(panoPrefs* prPtr, int selector); PANO13_IMPEX void SetCorrectDefaults(cPrefs* p); PANO13_IMPEX void SetAdjustDefaults(aPrefs* p); PANO13_IMPEX void SetRemapDefaults(rPrefs* p); PANO13_IMPEX void SetPerspectiveDefaults(pPrefs* p); PANO13_IMPEX void SetImageDefaults(Image* im); #ifdef CAN_READ_HUGIN_FILES PANO13_IMPEX void SetPanoImageInfoDefaults(PanoImageInfo* im); #endif PANO13_IMPEX void SetOptDefaults(optVars* opt); PANO13_IMPEX void SetPanDefaults(panControls* pc); PANO13_IMPEX void SetSizeDefaults(sPrefs* pref); PANO13_IMPEX void SetStitchDefaults(stBuf* sbuf); PANO13_IMPEX void SetVRPanoOptionsDefaults(VRPanoOptions* v); PANO13_IMPEX void SettMatrixDefaults(tMatrix* t); PANO13_IMPEX void SetCoordDefaults(CoordInfo* c, int num); PANO13_IMPEX int SetAlignParams(double* x); PANO13_IMPEX int SetLMParams(double* x); PANO13_IMPEX void SetGlobalPtr(AlignInfo* p); PANO13_IMPEX int CheckParams(AlignInfo* g); PANO13_IMPEX void setFcnPanoHuberSigma(double sigma); // Dialogs PANO13_IMPEX int SetPrefs(panoPrefs* p); PANO13_IMPEX int SetPanPrefs(panControls* p); PANO13_IMPEX int SetCorrectPrefs(cPrefs* p); PANO13_IMPEX int SetRadialOptions(cPrefs* p); PANO13_IMPEX int SetHorizontalOptions(cPrefs* p); PANO13_IMPEX int SetVerticalOptions(cPrefs* p); PANO13_IMPEX int SetShearOptions(cPrefs* p); PANO13_IMPEX int SetScaleOptions(cPrefs* p); PANO13_IMPEX int SetLumOptions(cPrefs* p); PANO13_IMPEX int setSizePrefs(sPrefs* p, int can_resize); PANO13_IMPEX int SetRemapPrefs(rPrefs* p); PANO13_IMPEX int SetPerspectivePrefs(pPrefs* p); PANO13_IMPEX int SetAdjustPrefs(aPrefs* p); PANO13_IMPEX int SetInterpolator(sPrefs* p); PANO13_IMPEX int SetCreateOptions(aPrefs* p); PANO13_IMPEX int SetCutOptions(cPrefs* p); PANO13_IMPEX int SetFourierOptions(cPrefs* p); // File I/O PANO13_IMPEX int readPrefs(char* p, int selector); // Preferences, same selector as dispatch PANO13_IMPEX void writePrefs(char* p, int selector); // Preferences, same selector as dispatch PANO13_IMPEX int LoadBufImage(Image* image, char* fname, int mode); PANO13_IMPEX int SaveBufImage(Image* image, char* fname); PANO13_IMPEX int writeCroppedTIFF(Image* im, fullPath* sfile, CropInfo* crop_info); PANO13_IMPEX int writeTIFF(Image* im, fullPath* fname); // On Mac: fname is FSSpec* PANO13_IMPEX void SaveOptions(struct correct_Prefs* thePrefs); PANO13_IMPEX int LoadOptions(struct correct_Prefs* thePrefs); PANO13_IMPEX void FindScript(struct adjust_Prefs* thePrefs); PANO13_IMPEX char* LoadScript(fullPath* scriptFile); PANO13_IMPEX int WriteScript(char* res, fullPath* scriptFile, int launch); // Write PSB and PSD files PANO13_IMPEX int writePS(Image* im, fullPath* fname, Boolean bBig); // On Mac: fname is FSSpec* PANO13_IMPEX int writePSD(Image* im, fullPath* fname); PANO13_IMPEX int readPSD(Image* im, fullPath* fname, int mode); // Can handle both PSD and PSB PANO13_IMPEX int writePSwithLayer(Image* im, fullPath* fname, Boolean bBig); PANO13_IMPEX int writePSDwithLayer(Image* im, fullPath* fname); PANO13_IMPEX int addLayerToFile(Image* im, fullPath* sfile, fullPath* dfile, stBuf* sB); //works with PSD & PSB PANO13_IMPEX int readPSDMultiLayerImage(MultiLayerImage* mim, fullPath* sfile); PANO13_IMPEX int FindFile(fullPath* fname); PANO13_IMPEX int SaveFileAs(fullPath* fname, char* prompt, char* name); PANO13_IMPEX void ConvFileName(fullPath* fname, char* string); PANO13_IMPEX void showScript(fullPath* scriptFile); PANO13_IMPEX void MakeTempName(fullPath* fspec, char* fname); PANO13_IMPEX void makePathForResult(fullPath* path); PANO13_IMPEX int makePathToHost(fullPath* path); PANO13_IMPEX void open_selection(fullPath* path); PANO13_IMPEX int GetFullPath(fullPath* path, char* filename); // Somewhat confusing, for compatibility easons PANO13_IMPEX int StringtoFullPath(fullPath* path, char* filename); PANO13_IMPEX int IsTextFile(char* fname); PANO13_IMPEX int readPositions(char* script, transformCoord* tP); PANO13_IMPEX int readJPEG(Image* im, fullPath* sfile); PANO13_IMPEX int readTIFF(Image* im, fullPath* sfile); PANO13_IMPEX int writeJPEG(Image* im, fullPath* sfile, int quality, int progressive); PANO13_IMPEX int writePNG(Image* im, fullPath* sfile); PANO13_IMPEX int readPNG(Image* im, fullPath* sfile); PANO13_IMPEX int LaunchAndSendScript(char* application, char* script); PANO13_IMPEX aPrefs* readAdjustLine(fullPath* theScript); #ifdef __Mac__ int readImage(Image* im, fullPath* sfile); int writeImage(Image* im, fullPath* sfile); int makeTempPath(fullPath* path); #endif //int readtif(Image *im, TIFF* tif); PANO13_IMPEX void getCropInformation(char* filename, CropInfo* c); // Read and Write Radiance HDR files PANO13_IMPEX int writeHDR(Image* im, fullPath* sfile); PANO13_IMPEX int readHDR(Image* im, fullPath* sfile); #define FullPathtoString( path, string ) GetFullPath( path, string) PANO13_IMPEX int ReadMorphPoints(char* script, AlignInfo* gl, int nIm); // Image manipulation PANO13_IMPEX void addAlpha(Image* im); PANO13_IMPEX void transForm(TrformStr* TrPtr, fDesc* fD, int color); PANO13_IMPEX void transFormEx(TrformStr* TrPtr, fDesc* fD, fDesc* finvD, int color, int imageNum); PANO13_IMPEX void filter(TrformStr* TrPtr, flfn func, flfn16 func16, void* params, int color); PANO13_IMPEX void CopyImageData(Image* dest, Image* src); PANO13_IMPEX void laplace(Image* im); PANO13_IMPEX void blurr(Image* im); PANO13_IMPEX void MakePano(TrformStr* TrPtr, aPrefs* aP); PANO13_IMPEX void MyMakePano(TrformStr* TrPtr, aPrefs* aP, int imageNum); PANO13_IMPEX void ExtractStill(TrformStr* TrPtr, aPrefs* p); PANO13_IMPEX int HaveEqualSize(Image* im1, Image* im2); PANO13_IMPEX int merge(Image* dst, Image* src, int feather, int showprogress, int seam); PANO13_IMPEX void mergeAlpha(Image* im, unsigned char* alpha, int feather, PTRect* theRect); PANO13_IMPEX void SetEquColor(cPrefs* p); PANO13_IMPEX void CopyPosition(Image* to, Image* from); PANO13_IMPEX int isColorSpecific(cPrefs* p); PANO13_IMPEX void ThreeToFourBPP(Image* im); PANO13_IMPEX void FourToThreeBPP(Image* im); PANO13_IMPEX int SetUpGamma(double pgamma, unsigned int psize); PANO13_IMPEX int cutTheFrame(Image* dest, Image* src, int width, int height, int showprogress); PANO13_IMPEX int PositionCmp(Image* im1, Image* im2); PANO13_IMPEX int MorphImage(Image* src, Image* dst, PTTriangle* ts, PTTriangle* td, int nt); PANO13_IMPEX int MorphImageFile(fullPath* sfile, fullPath* dfile, AlignInfo* g, int nIm); PANO13_IMPEX int blendImages(fullPath* f0, fullPath* f1, fullPath* result, double s); PANO13_IMPEX int InterpolateImage(Image* src, Image* dst, PTTriangle* ts, PTTriangle* td, int nt); PANO13_IMPEX int InterpolateTrianglesPerspective(AlignInfo* g, int nIm, double s, PTTriangle** t); PANO13_IMPEX int InterpolateImageFile(fullPath* sfile, fullPath* dfile, AlignInfo* g, int nIm); PANO13_IMPEX void OneToTwoByte(Image* im); PANO13_IMPEX void TwoToOneByte(Image* im); PANO13_IMPEX void SetMakeParams(struct fDesc* stack, struct MakeParams* mp, Image* im, Image* pn, int color); PANO13_IMPEX void SetInvMakeParams(struct fDesc* stack, struct MakeParams* mp, Image* im, Image* pn, int color); // same as SetInvMakeParams but includes Joosts inverted changes to SetMakeParams PANO13_IMPEX void SetInvMakeParamsCorrect(struct fDesc* stack, struct MakeParams* mp, Image* im, Image* pn, int color); PANO13_IMPEX void GetControlPointCoordinates(int i, double* x, double* y, AlignInfo* gl); PANO13_IMPEX void ARGBtoRGBA(uint8_t* buf, int width, int bitsPerPixel); PANO13_IMPEX void RGBAtoARGB(uint8_t* buf, int width, int bitsPerPixel); PANO13_IMPEX int CropImage(Image* im, PTRect* r); PANO13_IMPEX void DoColorCorrection(Image* im1, Image* im2, int mode); // Script Reading/Parsing/Writing PANO13_IMPEX int ParseScript(char* script, AlignInfo* gl); #ifdef CAN_READ_HUGIN_FILES PANO13_IMPEX void WriteHuginPtoFile(char* script, fullPath* sfile, AlignInfo* g); #endif // CAN_READ_HUGIN_FILES PANO13_IMPEX void WriteResults(char* script, fullPath* sfile, AlignInfo* g, double ds(int i), int launch); PANO13_IMPEX int readAdjust(aPrefs* p, fullPath* sfile, int insert, sPrefs* sP); PANO13_IMPEX void readControlPoints(char* script, controlPoint* c); PANO13_IMPEX int getVRPanoOptions(VRPanoOptions* v, char* line); PANO13_IMPEX void nextWord(register char* word, char** ch, int max_word_length); PANO13_IMPEX int nextLine(register char* line, char** ch); PANO13_IMPEX int numLines(char* script, char first); PANO13_IMPEX char* panoParserFindOLine(char* script, int index); PANO13_IMPEX void StrcpyN(char* destination, const char* source, int64_t bufsize); // Memory PANO13_IMPEX void DisposeAlignInfo(AlignInfo* g); PANO13_IMPEX void** mymalloc(size_t numBytes); // Memory allocation, use Handles PANO13_IMPEX void myfree(void** Hdl); // free Memory, use Handles PANO13_IMPEX int SetDestImage(TrformStr* TrPtr, int width, int height); PANO13_IMPEX void DisposeMultiLayerImage(MultiLayerImage* mim); // Math PANO13_IMPEX void RunLMOptimizer(OptInfo* g); PANO13_IMPEX void RunBROptimizer(OptInfo* g, double minStepWidth); PANO13_IMPEX void RunOverlapOptimizer(AlignInfo* g); PANO13_IMPEX void SetMatrix(double a, double b, double c, double m[3][3], int cl); PANO13_IMPEX void matrix_mult(double m[3][3], double vector[3]); PANO13_IMPEX void matrix_inv_mult(double m[3][3], double vector[3]); PANO13_IMPEX double smallestRoot(double* p); PANO13_IMPEX void SetCorrectionRadius(cPrefs* cP); PANO13_IMPEX int64_t lmdif(int64_t m, int64_t n, double x[], double fvec[], double ftol, double xtol, double gtol, int64_t maxfev, double epsfcn, double diag[], int64_t mode, double factor, int64_t nprint, int64_t* info, int64_t* nfev, double fjac[], int64_t ldfjac, int64_t ipvt[], double qtf[], double wa1[], double wa2[], double wa3[], double wa4[]); PANO13_IMPEX void fourier(TrformStr* TrPtr, cPrefs* cP); PANO13_IMPEX unsigned short gamma_correct(double pix); PANO13_IMPEX int EqualCPrefs(cPrefs* c1, cPrefs* c2); PANO13_IMPEX double OverlapRMS(MultiLayerImage* mim); PANO13_IMPEX double distSquared(int num); PANO13_IMPEX int64_t fcnPano(int64_t m, int64_t n, double x[], double fvec[], int64_t* iflag); PANO13_IMPEX int EvaluateControlPointError(int num, double* errptr, double errComponent[2]); PANO13_IMPEX void doCoordinateTransform(CoordInfo* c, tMatrix* t); PANO13_IMPEX void findOptimumtMatrix(transformCoord* tP, tMatrix* tM, lmfunc f); PANO13_IMPEX int SolveLinearEquation2(double a[2][2], double b[2], double x[2]); PANO13_IMPEX void SortControlPoints(AlignInfo* g, int nIm); PANO13_IMPEX void noisefilter(Image* dest, Image* src); PANO13_IMPEX void fwiener(TrformStr* TrPtr, Image* nf, Image* psf, double gamma, double frame); // Triangulation PANO13_IMPEX int PointInTriangle(double x, double y, PTTriangle* T, double c[2]); PANO13_IMPEX int SetSourceTriangles(AlignInfo* g, int nIm, PTTriangle** t); PANO13_IMPEX int SetDestTriangles(AlignInfo* g, int nIm, PTTriangle** t); PANO13_IMPEX int InterpolateTriangles(AlignInfo* g, int nIm, double s, PTTriangle** t); PANO13_IMPEX int DelaunayIteration(AlignInfo* g, int nIm); PANO13_IMPEX int PointInCircumcircle(double x, double y, PTTriangle* tC); PANO13_IMPEX int TriangulatePoints(AlignInfo* g, int nIm); PANO13_IMPEX int AddTriangle(triangle* t, AlignInfo* g); PANO13_IMPEX int RemoveTriangle(int nt, AlignInfo* g); PANO13_IMPEX void OrderVerticesInTriangle(int nt, AlignInfo* g); PANO13_IMPEX void SetTriangleCoordinates(triangle* t, PTTriangle* tC, AlignInfo* g); PANO13_IMPEX int TrianglesOverlap(PTTriangle* t0, PTTriangle* t1); PANO13_IMPEX int LinesIntersect(PTLine* s0, PTLine* s1); PANO13_IMPEX double PTDistance(PTPoint* s0, PTPoint* s1); PANO13_IMPEX int PTPointInRectangle(PTPoint* p, PTLine* r); PANO13_IMPEX int PTElementOf(double x, double a, double b); PANO13_IMPEX int PTNormal(double* a, double* b, double* c, PTLine* s); PANO13_IMPEX int PTGetLineCrossing(PTLine* s0, PTLine* s1, PTPoint* ps); PANO13_IMPEX int ReduceTriangles(AlignInfo* g, int nIm); PANO13_IMPEX double PTAreaOfTriangle(PTTriangle* t); PANO13_IMPEX int normalToTriangle(CoordInfo* n, CoordInfo* v, triangle* t); PANO13_IMPEX double GetBlendfactor(int d, int s, int feather); PANO13_IMPEX void execute_stack(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int execute_stack_new(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int resize(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int shear(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int shearInv(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int horiz(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int vert(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int radial(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int radial_brown(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int tiltForward(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int tiltInverse(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int persp_sphere(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int persp_rect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int rect_pano(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int pano_rect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int pano_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_pano(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_cp_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_sphere_cp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int rect_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_rect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_cp_pano(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int rect_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_rect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int plane_transfer_to_camera(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int plane_transfer_from_camera(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int mirror_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int mercator_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_mercator(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int lambert_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_lambert(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_lambertazimuthal(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int lambertazimuthal_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_hammer(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int hammer_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int transmercator_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_transmercator(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sinusoidal_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_sinusoidal(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int stereographic_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_stereographic(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int albersequalareaconic_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_albersequalareaconic(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int albersequalareaconic_distance(double* x_src, void* params); PANO13_IMPEX int millercylindrical_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_millercylindrical(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int panini_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_panini(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int equipanini_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_equipanini(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int panini_general_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_panini_general(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX Image* setup_panini_general(struct MakeParams* pmp); PANO13_IMPEX int maxFOVs_panini_general(double* params, double* fovs); PANO13_IMPEX int arch_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_arch(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int biplane_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_biplane(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int biplane_distance(double width, double b, void* params); PANO13_IMPEX int triplane_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int erect_triplane(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int triplane_distance(double width, double b, void* params); PANO13_IMPEX int mirror_sphere_cp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int mirror_pano(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_cp_mirror(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_pano(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int pano_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_mirror(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int mirror_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_equisolid(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int equisolid_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_orthographic(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int orthographic_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int sphere_tp_thoby(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int thoby_sphere_tp(double x_dest, double y_dest, double* x_src, double* y_src, void* params); #define THOBY_K1_PARM 1.47 #define THOBY_K2_PARM 0.713 PANO13_IMPEX int rotate_erect(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int inv_radial(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int inv_radial_brown(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int vertical(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int inv_vertical(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int deregister(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int tmorph(double x_dest, double y_dest, double* x_src, double* y_src, void* params); PANO13_IMPEX int shift_scale_rotate(double x_dest, double y_dest, double* x_src, double* y_src, void* params); unsigned char radlum(unsigned char srcPixel, int xc, int yc, void* params); //Kekus 16 bit 2003/Nov/18 unsigned short radlum16(unsigned short srcPixel, int xc, int yc, void* params);// , long bitsPerComponent); //Kekus. extern TrformStr* gTrPtr; extern sPrefs* gsPrPtr; // Endian stuff: Read and write numbers from and to memory (ptr) #ifdef PT_BIGENDIAN #define LONGLONGNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[0]; \ *ptr++ = ((char*)(&number))[1]; \ *ptr++ = ((char*)(&number))[2]; \ *ptr++ = ((char*)(&number))[3]; \ *ptr++ = ((char*)(&number))[4]; \ *ptr++ = ((char*)(&number))[5]; \ *ptr++ = ((char*)(&number))[6]; \ *ptr++ = ((char*)(&number))[7]; #define NUMBERLONGLONG( number, ptr ) ((char*)(&number))[0] = *ptr++; \ ((char*)(&number))[1] = *ptr++; \ ((char*)(&number))[2] = *ptr++; \ ((char*)(&number))[3] = *ptr++; \ ((char*)(&number))[4] = *ptr++; \ ((char*)(&number))[5] = *ptr++; \ ((char*)(&number))[6] = *ptr++; \ ((char*)(&number))[7] = *ptr++; #define LONGNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[0]; \ *ptr++ = ((char*)(&number))[1]; \ *ptr++ = ((char*)(&number))[2]; \ *ptr++ = ((char*)(&number))[3]; #define NUMBERLONG( number, ptr ) ((char*)(&number))[0] = *ptr++; \ ((char*)(&number))[1] = *ptr++; \ ((char*)(&number))[2] = *ptr++; \ ((char*)(&number))[3] = *ptr++; #define SHORTNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[0]; \ *ptr++ = ((char*)(&number))[1]; \ #define NUMBERSHORT( number, ptr ) ((char*)(&number))[0] = *ptr++; \ ((char*)(&number))[1] = *ptr++; \ #else #define LONGLONGNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[7]; \ *ptr++ = ((char*)(&number))[6]; \ *ptr++ = ((char*)(&number))[5]; \ *ptr++ = ((char*)(&number))[4]; \ *ptr++ = ((char*)(&number))[3]; \ *ptr++ = ((char*)(&number))[2]; \ *ptr++ = ((char*)(&number))[1]; \ *ptr++ = ((char*)(&number))[0]; #define NUMBERLONGLONG( number, ptr ) ((char*)(&number))[7] = *ptr++; \ ((char*)(&number))[6] = *ptr++; \ ((char*)(&number))[5] = *ptr++; \ ((char*)(&number))[4] = *ptr++; \ ((char*)(&number))[3] = *ptr++; \ ((char*)(&number))[2] = *ptr++; \ ((char*)(&number))[1] = *ptr++; \ ((char*)(&number))[0] = *ptr++; #define LONGNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[3]; \ *ptr++ = ((char*)(&number))[2]; \ *ptr++ = ((char*)(&number))[1]; \ *ptr++ = ((char*)(&number))[0]; #define NUMBERLONG( number, ptr ) ((char*)(&number))[3] = *ptr++; \ ((char*)(&number))[2] = *ptr++; \ ((char*)(&number))[1] = *ptr++; \ ((char*)(&number))[0] = *ptr++; #define SHORTNUMBER( number, ptr ) *ptr++ = ((char*)(&number))[1]; \ *ptr++ = ((char*)(&number))[0]; \ #define NUMBERSHORT( number, ptr ) ((char*)(&number))[1] = *ptr++; \ ((char*)(&number))[0] = *ptr++; \ #endif // PT_BIGENDIAN //TODO: JMW These File i/o macros are to be replaced in code with the error catching functions below #if USEWRITEREADMACROS #define WRITEUCHAR( theChar ) ch = theChar; count = 1; mywrite(fnum,count,&ch); #define WRITESHORT( theShort ) svar = theShort; d = data; SHORTNUMBER( svar, d ); \ count = 2; mywrite (fnum,count,data); #define WRITEINT32( theLong ) var = theLong; d = data; LONGNUMBER( var, d ); \ count = 4; mywrite (fnum,count,data); #define READINT32( theLong ) count = 4; myread(src,count,data); \ d = data; NUMBERLONG( var, d ); \ theLong = var; #define WRITEINT64( theLong ) var64 = theLong; d = data; LONGLONGNUMBER( var64, d ); \ count = 8; mywrite (fnum,count,data); #define READINT64( theLong ) count = 8; myread(src,count,data); \ d = data; NUMBERLONGLONG( var64, d ); \ theLong = var64; #define READSHORT( theShort ) count = 2; myread(src,count,data); \ d = data; NUMBERSHORT( svar, d ); \ theShort = svar; #define READUCHAR( theChar ) count = 1; myread(src,count,&ch); theChar = ch; #endif // Cross platform file functions #ifdef __Mac__ #include // Kekus Digital #include "sys_mac.h" #define file_spec short #define nfile_spec short #define myopen( path, perm, fspec ) ( FSpOpenDF( path, perm, &fspec ) != noErr ) #define mywrite( fspec, count, data ) FSWrite (fspec, &count, data) #define myread( fspec, count, data ) FSRead (fspec, &count, data) #define myclose( fspec ) FSClose (fspec ) #define mycreate( path, creator, type ) FSpCreate( path, creator, type,0) #define mydelete( path ) FSpDelete( path ) #define myrename( path, newpath ) FSpRename (path, (newpath)->name) #define write_text fsWrPerm #define write_bin fsWrPerm #define read_text fsRdPerm #define read_bin fsRdPerm #define read_write_text fsRdWrPerm #else // __Mac__, use ANSI-filefunctions #define file_spec FILE* #define nfile_spec int #define myopen( path, perm, fspec ) ( (fspec = fopen( (path)->name, perm )) == NULL) #define mywrite( fspec, count, data ) count = fwrite( data, 1, count, fspec) #define myread( fspec, count, data ) count = fread( data, 1, count, fspec ) #define myclose( fspec ) fclose (fspec ) #define mycreate( path, creator, type ) #define mydelete( path ) remove((path)->name ) #define myrename( path, newpath ) rename ((path)->name, (newpath)->name) #define write_text "w" #define write_bin "wb" #define read_text "r" #define read_bin "rb" #define read_write_text "rw" #define append_bin "ab" // Ippei hack. OSX with GCC+ANSI mode. #ifdef MAC_OS_X_VERSION_10_4 // MacOSX 10.4 has those functions predefined in Carbon API. #include // CoreServices/TextUtils.h #else #define p2cstr( x ) #define c2pstr( x ) #endif #endif /* ENDIAN aware file i/o funtions. Used for reading and writing photoshop files */ PANO13_IMPEX Boolean panoWriteUCHAR(file_spec fnum, uint8_t theChar); PANO13_IMPEX Boolean panoWriteSHORT(file_spec fnum, uint16_t theShort); PANO13_IMPEX Boolean panoWriteINT32(file_spec fnum, uint32_t theLong); PANO13_IMPEX Boolean panoWriteINT64(file_spec fnum, int64_t theLongLong); PANO13_IMPEX Boolean panoWriteINT32or64(file_spec fnum, int64_t theLongLong, Boolean bBig); PANO13_IMPEX Boolean panoReadUCHAR(file_spec fnum, uint8_t* pChar); PANO13_IMPEX Boolean panoReadSHORT(file_spec fnum, uint16_t* pShort); PANO13_IMPEX Boolean panoReadINT32(file_spec fnum, uint32_t* pLong); PANO13_IMPEX Boolean panoReadINT64(file_spec fnum, int64_t* pLongLong); PANO13_IMPEX Boolean panoReadINT32or64(file_spec fnum, int64_t* pLongLong, Boolean bBig); #define PANO_DEFAULT_PIXELS_PER_RESOLUTION 150.0 #define PANO_DEFAULT_TIFF_RESOLUTION_UNITS RESUNIT_INCH // this is the best compression available in all systems // better than PACKBITS #define PANO_DEFAULT_TIFF_COMPRESSION COMPRESSION_DEFLATE PANO13_IMPEX void panoMetadataFree(pano_ImageMetadata* metadata); PANO13_IMPEX int panoMetadataCopy(pano_ImageMetadata* to, pano_ImageMetadata* from); PANO13_IMPEX int panoROIRowInside(pano_CropInfo* cropInfo, int row); PANO13_IMPEX void panoMetadataSetCompression(pano_ImageMetadata* metadata, char* compressionName); PANO13_IMPEX int panoMetadataCopy(pano_ImageMetadata* to, pano_ImageMetadata* from); PANO13_IMPEX void panoMetadataFree(pano_ImageMetadata* metadata); PANO13_IMPEX void panoMetadataSetAsCropped(pano_ImageMetadata* metadata, int croppedWidth, int croppedHeight, int roiLeft, int roiRight); PANO13_IMPEX void panoMetadataResetSize(pano_ImageMetadata* metadata, int width, int height); PANO13_IMPEX int panoReadJPEG(Image* im, fullPath* sfile); #ifndef PAN_DEBUG_METADATA PANO13_IMPEX void panoDumpMetadata(pano_ImageMetadata* metadata, char* message); #else #define panoDumpMetadata(a,b) ; #endif // number of different temporary files #define MAX_TEMP_TRY 1000000 #endif /* #ifndef FILTER_H */ //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- void makePathForResult(fullPath* path) { StrcpyN(path->name, "//ptool_result", MAX_PATH_LENGTH); } int makePathToHost(fullPath* path) { StrcpyN(path->name, "./", MAX_PATH_LENGTH); return 0; } void SetSizeDefaults(sPrefs* pref) { pref->magic = 70; // File validity check; must be 70 pref->displayPart = TRUE; // Display cropped/framed image ? pref->saveFile = FALSE; // Save to tempfile? pref->launchApp = FALSE; // Open sFile ? pref->interpolator = _spline36; // makePathForResult(&(pref->sFile)); makePathToHost(&(pref->lApp)); pref->gamma = 1.0; pref->noAlpha = FALSE; // Check only for Photoshop LE pref->optCreatePano = TRUE; pref->fastStep = FAST_TRANSFORM_STEP_NONE; // the value will be changed in parser.c } enum { PSD_NORMAL, PSD_COLOR, PSD_DARKEN, PSD_DIFFERENCE, PSD_DISSOLVE, PSD_HARD_LIGHT, PSD_HUE, PSD_LIGHTEN, PSD_LUMINOSITY, PSD_MULTIPLY, PSD_OVERLAY, PSD_SOFT_LIGHT, PSD_SATURATION, PSD_SCREEN, PSD_NUMBER_BLENDING_MODES, // This Is Not Really a mode, it is the counter of number of modes }; void SetStitchDefaults(struct stitchBuffer* sBuf) { *sBuf->srcName = 0; *sBuf->destName = 0; sBuf->feather = 10; sBuf->colcorrect = 0; sBuf->seam = _middle; sBuf->psdOpacity = 255; sBuf->psdBlendingMode = PSD_NORMAL; } //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- void SetOptDefaults(optVars* opt) { opt->hfov = opt->yaw = opt->pitch = opt->roll = 0; opt->a = opt->b = opt->c = opt->d = opt->e = 0; opt->shear_x = opt->shear_y = 0; opt->tiltXopt = opt->tiltYopt = opt->tiltZopt = opt->tiltScaleOpt = 0; opt->transXopt = opt->transYopt = opt->transZopt = opt->transYawOpt = opt->transPitchOpt = 0; opt->testP0opt = opt->testP1opt = opt->testP2opt = opt->testP3opt = 0; #ifdef CAN_READ_HUGIN_FILES opt->Va = opt->Vb = opt->Vc = opt->Vd = 0; opt->Vx = opt->Vy = 0; opt->Ra = opt->Rb = opt->Rc = opt->Rd = opt->Re = 0; opt->Eev = opt->Er = opt->Eb = 0; #endif opt->nhfov = opt->nyaw = opt->npitch = opt->nroll = -1; opt->na = opt->nb = opt->nc = opt->nd = opt->ne = -1; opt->nshear_x = opt->nshear_y = -1; opt->ntiltXopt = opt->ntiltYopt = opt->ntiltZopt = opt->ntiltScaleOpt = -1; opt->ntransXopt = opt->ntransYopt = opt->ntransZopt = opt->ntransYawOpt = opt->ntransPitchOpt = -1; opt->ntestP0opt = opt->ntestP1opt = opt->ntestP2opt = opt->ntestP3opt = -1; opt->shfov = opt->syaw = opt->spitch = opt->sroll = -1; opt->sa = opt->sb = opt->sc = opt->sd = opt->se = -1; opt->sshear_x = opt->sshear_y = -1; opt->stiltXopt = opt->stiltYopt = opt->stiltZopt = opt->stiltScaleOpt = -1; opt->stransXopt = opt->stransYopt = opt->stransZopt = opt->stransYawOpt = opt->stransPitchOpt = -1; opt->stestP0opt = opt->stestP1opt = opt->stestP2opt = opt->stestP3opt = -1; #ifdef CAN_READ_HUGIN_FILES opt->sVa = opt->sVb = opt->sVc = opt->sVd = -1; opt->sVx = opt->sVy = -1; opt->sRa = opt->sRb = opt->sRc = opt->sRd = opt->sRe = -1; opt->sEev = opt->sEr = opt->sEb = -1; #endif opt->whfov = opt->wyaw = opt->wpitch = opt->wroll = -1; opt->wa = opt->wb = opt->wc = opt->wd = opt->we = -1; opt->wshear_x = opt->wshear_y = -1; opt->wtiltXopt = opt->wtiltYopt = opt->wtiltZopt = opt->wtiltScaleOpt = -1; opt->wtransXopt = opt->wtransYopt = opt->wtransZopt = opt->wtransYawOpt = opt->wtransPitchOpt = -1; opt->wtestP0opt = opt->wtestP1opt = opt->wtestP2opt = opt->wtestP3opt = -1; #ifdef CAN_READ_HUGIN_FILES opt->wVa = opt->wVb = opt->wVc = opt->wVd = -1; opt->wVx = opt->wVy = -1; opt->wRa = opt->wRb = opt->wRc = opt->wRd = opt->wRe = -1; opt->wEev = opt->wEr = opt->wEb = -1; #endif opt->minhfov = opt->minyaw = opt->minpitch = opt->minroll = -DBL_MAX; opt->mina = opt->minb = opt->minc = opt->mind = opt->mine = -DBL_MAX; opt->minshear_x = opt->minshear_y = -DBL_MAX; opt->mintiltXopt = opt->mintiltYopt = opt->mintiltZopt = opt->mintiltScaleOpt = -DBL_MAX; opt->mintransXopt = opt->mintransYopt = opt->mintransZopt = opt->mintransYawOpt = opt->mintransPitchOpt = -DBL_MAX; opt->mintestP0opt = opt->mintestP1opt = opt->mintestP2opt = opt->mintestP3opt = -DBL_MAX; #ifdef CAN_READ_HUGIN_FILES opt->minVa = opt->minVb = opt->minVc = opt->minVd = -DBL_MAX; opt->minVx = opt->minVy = -DBL_MAX; opt->minRa = opt->minRb = opt->minRc = opt->minRd = opt->minRe = -DBL_MAX; opt->minEev = opt->minEr = opt->minEb = -DBL_MAX; #endif opt->maxhfov = opt->maxyaw = opt->maxpitch = opt->maxroll = DBL_MAX; opt->maxa = opt->maxb = opt->maxc = opt->maxd = opt->maxe = DBL_MAX; opt->maxshear_x = opt->maxshear_y = DBL_MAX; opt->maxtiltXopt = opt->maxtiltYopt = opt->maxtiltZopt = opt->maxtiltScaleOpt = DBL_MAX; opt->maxtransXopt = opt->maxtransYopt = opt->maxtransZopt = opt->maxtransYawOpt = opt->maxtransPitchOpt = DBL_MAX; opt->maxtestP0opt = opt->maxtestP1opt = opt->maxtestP2opt = opt->maxtestP3opt = DBL_MAX; #ifdef CAN_READ_HUGIN_FILES opt->maxVa = opt->maxVb = opt->maxVc = opt->maxVd = DBL_MAX; opt->maxVx = opt->maxVy = DBL_MAX; opt->maxRa = opt->maxRb = opt->maxRc = opt->maxRd = opt->maxRe = DBL_MAX; opt->maxEev = opt->maxEr = opt->maxEb = DBL_MAX; #endif } //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- /* Configuration defines for installed libtiff. This file maintained for backward compatibility. Do not use definitions from this file in your programs. */ #ifndef _TIFFCONF_ #define _TIFFCONF_ /* The size of a `int', as computed by sizeof. */ #define SIZEOF_INT 4 /* The size of a `long', as computed by sizeof. */ #include #if (LONG_MAX == +9223372036854775807L) #define SIZEOF_LONG 8 #define SIZEOF_UNSIGNED_LONG 8 #elif (LONG_MAX == +2147483647) #define SIZEOF_LONG 4 #define SIZEOF_UNSIGNED_LONG 4 #else #error "Cannot detect SIZEOF_LONG" #endif /* Signed 8-bit type */ #define TIFF_INT8_T signed char /* Unsigned 8-bit type */ #define TIFF_UINT8_T unsigned char /* Signed 16-bit type */ #define TIFF_INT16_T signed short /* Unsigned 16-bit type */ #define TIFF_UINT16_T unsigned short /* Signed 32-bit type */ #define TIFF_INT32_T signed int /* Unsigned 32-bit type */ #define TIFF_UINT32_T unsigned int /* Signed / Unsigned 64-bit type */ #ifdef _MSC_VER #define TIFF_INT64_T signed __int64 #define TIFF_UINT64_T unsigned __int64 #else #include #define TIFF_INT64_T int64_t #define TIFF_UINT64_T uint64_t #endif // _MSC_VER /* Signed 64-bit type */ #if defined(_WIN64) #define TIFF_SSIZE_T signed __int64 #else #define TIFF_SSIZE_T signed long #endif /* Pointer difference type */ #define TIFF_PTRDIFF_T ptrdiff_t /* Compatibility stuff. */ /* Define as 0 or 1 according to the floating point format suported by the machine */ #define HAVE_IEEEFP 1 /* ----------------------------------------------------------------------- Byte order ----------------------------------------------------------------------- */ /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). Some versions of gcc may have BYTE_ORDER or __BYTE_ORDER defined If your big endian system isn't being detected, add an OS specific check */ #if (defined(BYTE_ORDER) && BYTE_ORDER==BIG_ENDIAN) || \ (defined(__BYTE_ORDER) && __BYTE_ORDER==__BIG_ENDIAN) || \ defined(__BIG_ENDIAN__) /* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ #define HOST_FILLORDER FILLORDER_MSB2LSB /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ #define WORDS_BIGENDIAN 1 /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ #define HOST_BIGENDIAN 1 #else /* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */ #define HOST_FILLORDER FILLORDER_LSB2MSB /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ #undef WORDS_BIGENDIAN /* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian (Intel) */ #undef HOST_BIGENDIAN #endif // BYTE_ORDER /* Support CCITT Group 3 & 4 algorithms */ #define CCITT_SUPPORT 1 /* Support JPEG compression (requires IJG JPEG library) */ #define JPEG_SUPPORT 1 /* Support JBIG compression (requires JBIG-KIT library) */ /* #undef JBIG_SUPPORT */ /* Support LogLuv high dynamic range encoding */ #define LOGLUV_SUPPORT 1 /* Support LZW algorithm */ #define LZW_SUPPORT 1 /* Support NeXT 2-bit RLE algorithm */ #define NEXT_SUPPORT 1 /* Support Old JPEG compresson (read contrib/ojpeg/README first! Compilation fails with unpatched IJG JPEG library) */ #define OJPEG_SUPPORT 1 /* Support Macintosh PackBits algorithm */ #define PACKBITS_SUPPORT 1 /* Support Pixar log-format algorithm (requires Zlib) */ #define PIXARLOG_SUPPORT 1 /* Support ThunderScan 4-bit RLE algorithm */ #define THUNDER_SUPPORT 1 /* Support Deflate compression */ #define ZIP_SUPPORT 1 /* Support LZMA2 compression */ #undef LZMA_SUPPORT /* Support Microsoft Document Imaging format */ #undef MDI_SUPPORT /* Support strip chopping (whether or not to convert single-strip uncompressed images to mutiple strips of ~8Kb to reduce memory usage) */ #define STRIPCHOP_DEFAULT TIFF_STRIPCHOP /* Enable SubIFD tag (330) support */ #define SUBIFD_SUPPORT 1 /* Treat extra sample as alpha (default enabled). The RGBA interface will treat a fourth sample with no EXTRASAMPLE_ value as being ASSOCALPHA. Many packages produce RGBA files but don't mark the alpha properly. */ #define DEFAULT_EXTRASAMPLE_AS_ALPHA 1 /* Pick up YCbCr subsampling info from the JPEG data stream to support files lacking the tag (default enabled). */ #define CHECK_JPEG_YCBCR_SUBSAMPLING 1 /* Support MS MDI magic number files as TIFF */ /* #undef MDI_SUPPORT */ /* * Feature support definitions. * XXX: These macros are obsoleted. Don't use them in your apps! * Macros stays here for backward compatibility and should be always defined. */ #define COLORIMETRY_SUPPORT #define YCBCR_SUPPORT #define CMYK_SUPPORT #define ICC_SUPPORT #define PHOTOSHOP_SUPPORT #define IPTC_SUPPORT #endif /* _TIFFCONF_ */ //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- void SetCorrectDefaults(cPrefs* prefs) { int i, k; prefs->magic = 20L; // from ANSI-version prefs->radial = FALSE; prefs->vertical = prefs->horizontal = FALSE; for (i = 0; i < 3; i++) { prefs->radial_params[i][0] = 1.0; prefs->radial_params[i][4] = 1000.0; // Correction radius prefs->vertical_params[i] = 0.0; prefs->horizontal_params[i] = 0.0; for (k = 1; k < 4; k++) prefs->radial_params[i][k] = 0.0; prefs->lum_params[i] = 0.0; } prefs->tilt = FALSE; prefs->tilt_x = 0; prefs->tilt_y = 0; prefs->tilt_z = 0; prefs->tilt_scale = 1; prefs->trans = FALSE; prefs->trans_x = 0; prefs->trans_y = 0; prefs->trans_z = 0; prefs->trans_yaw = 0; prefs->trans_pitch = 0; prefs->test = FALSE; prefs->test_p0 = 0; prefs->test_p1 = 0; prefs->test_p2 = 0; prefs->test_p3 = 0; prefs->shear = prefs->resize = FALSE; prefs->shear_x = prefs->shear_y = 0.0; prefs->width = prefs->height = 0; prefs->luminance = FALSE; prefs->correction_mode = correction_mode_radial; prefs->cutFrame = FALSE; prefs->fwidth = 100; prefs->fheight = 100; prefs->frame = 0; prefs->fourier = 0; prefs->fourier_mode = _fremoveBlurr; prefs->fourier_nf = _nf_internal; memset(&(prefs->psf), 0, sizeof(fullPath)); memset(&(prefs->nff), 0, sizeof(fullPath)); prefs->filterfactor = 1.0; prefs->fourier_frame = 0.0; } //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // sys_common.c #define PrintError printf /*void PrintError(const char* fmt, ...) { va_list ap; va_start(ap, fmt); if (g_printErrorFcn == NULL) { PrintErrorIntern(fmt, ap); } else { (*g_printErrorFcn)(fmt, ap); } va_end(ap); }*/ /* * Copyright (c) 1988-1997 Sam Leffler * Copyright (c) 1991-1997 Silicon Graphics, Inc. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation for any purpose is hereby granted without fee, provided * that (i) the above copyright notices and this permission notice appear in * all copies of the software and related documentation, and (ii) the names of * Sam Leffler and Silicon Graphics may not be used in any advertising or * publicity relating to the software without the specific, prior written * permission of Sam Leffler and Silicon Graphics. * * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. * * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. */ //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- #ifndef _TIFF_ #define _TIFF_ //#include "tiffconf.h" /* * Tag Image File Format (TIFF) * * Based on Rev 6.0 from: * Developer's Desk * Aldus Corporation * 411 First Ave. South * Suite 200 * Seattle, WA 98104 * 206-622-5500 * * (http://partners.adobe.com/asn/developer/PDFS/TN/TIFF6.pdf) * * For BigTIFF design notes see the following links * http://www.remotesensing.org/libtiff/bigtiffdesign.html * http://www.awaresystems.be/imaging/tiff/bigtiff.html */ #define TIFF_VERSION_CLASSIC 42 #define TIFF_VERSION_BIG 43 #define TIFF_BIGENDIAN 0x4d4d #define TIFF_LITTLEENDIAN 0x4949 #define MDI_LITTLEENDIAN 0x5045 #define MDI_BIGENDIAN 0x4550 /* * Intrinsic data types required by the file format: * * 8-bit quantities int8/uint8 * 16-bit quantities int16/uint16 * 32-bit quantities int32/uint32 * 64-bit quantities int64/uint64 * strings unsigned char* */ typedef TIFF_INT8_T int8; typedef TIFF_UINT8_T uint8; typedef TIFF_INT16_T int16; typedef TIFF_UINT16_T uint16; typedef TIFF_INT32_T int32; typedef TIFF_UINT32_T uint32; typedef TIFF_INT64_T int64; typedef TIFF_UINT64_T uint64; /* * Some types as promoted in a variable argument list * We use uint16_vap rather then directly using int, because this way * we document the type we actually want to pass through, conceptually, * rather then confusing the issue by merely stating the type it gets * promoted to */ typedef int uint16_vap; /* * TIFF header. */ typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ } TIFFHeaderCommon; typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ uint32 tiff_diroff; /* byte offset to first directory */ } TIFFHeaderClassic; typedef struct { uint16 tiff_magic; /* magic number (defines byte order) */ uint16 tiff_version; /* TIFF version number */ uint16 tiff_offsetsize; /* size of offsets, should be 8 */ uint16 tiff_unused; /* unused word, should be 0 */ uint64 tiff_diroff; /* byte offset to first directory */ } TIFFHeaderBig; /* * NB: In the comments below, * - items marked with a + are obsoleted by revision 5.0, * - items marked with a ! are introduced in revision 6.0. * - items marked with a % are introduced post revision 6.0. * - items marked with a $ are obsoleted by revision 6.0. * - items marked with a & are introduced by Adobe DNG specification. */ /* * Tag data type information. * * Note: RATIONALs are the ratio of two 32-bit integer values. */ typedef enum { TIFF_NOTYPE = 0, /* placeholder */ TIFF_BYTE = 1, /* 8-bit unsigned integer */ TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ TIFF_SHORT = 3, /* 16-bit unsigned integer */ TIFF_LONG = 4, /* 32-bit unsigned integer */ TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ TIFF_SBYTE = 6, /* !8-bit signed integer */ TIFF_UNDEFINED = 7, /* !8-bit untyped data */ TIFF_SSHORT = 8, /* !16-bit signed integer */ TIFF_SLONG = 9, /* !32-bit signed integer */ TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ TIFF_DOUBLE = 12, /* !64-bit IEEE floating point */ TIFF_IFD = 13, /* %32-bit unsigned integer (offset) */ TIFF_LONG8 = 16, /* BigTIFF 64-bit unsigned integer */ TIFF_SLONG8 = 17, /* BigTIFF 64-bit signed integer */ TIFF_IFD8 = 18 /* BigTIFF 64-bit unsigned integer (offset) */ } TIFFDataType; /* * TIFF Tag Definitions. */ #define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ #define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ #define FILETYPE_PAGE 0x2 /* one page of many */ #define FILETYPE_MASK 0x4 /* transparency mask */ #define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ #define OFILETYPE_IMAGE 1 /* full resolution image data */ #define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ #define OFILETYPE_PAGE 3 /* one page of many */ #define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ #define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ #define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ #define TIFFTAG_COMPRESSION 259 /* data compression technique */ #define COMPRESSION_NONE 1 /* dump mode */ #define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ #define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ #define COMPRESSION_CCITT_T4 3 /* CCITT T.4 (TIFF 6 name) */ #define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ #define COMPRESSION_CCITT_T6 4 /* CCITT T.6 (TIFF 6 name) */ #define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ #define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ #define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ #define COMPRESSION_T85 9 /* !TIFF/FX T.85 JBIG compression */ #define COMPRESSION_T43 10 /* !TIFF/FX T.43 colour by layered JBIG compression */ #define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ #define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ #define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ #define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ /* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT */ #define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ #define COMPRESSION_JBIG 34661 /* ISO JBIG */ #define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ #define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ #define COMPRESSION_JP2000 34712 /* Leadtools JPEG2000 */ #define COMPRESSION_LZMA 34925 /* LZMA2 */ #define COMPRESSION_ZSTD 34926 /* ZSTD: WARNING not registered in Adobe-maintained registry */ #define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ #define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ #define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ #define PHOTOMETRIC_RGB 2 /* RGB color model */ #define PHOTOMETRIC_PALETTE 3 /* color map indexed */ #define PHOTOMETRIC_MASK 4 /* $holdout mask */ #define PHOTOMETRIC_SEPARATED 5 /* !color separations */ #define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ #define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ #define PHOTOMETRIC_ICCLAB 9 /* ICC L*a*b* [Adobe TIFF Technote 4] */ #define PHOTOMETRIC_ITULAB 10 /* ITU L*a*b* */ #define PHOTOMETRIC_CFA 32803 /* color filter array */ #define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ #define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ #define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ #define THRESHHOLD_BILEVEL 1 /* b&w art scan */ #define THRESHHOLD_HALFTONE 2 /* or dithered scan */ #define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ #define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ #define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ #define TIFFTAG_FILLORDER 266 /* data order within a byte */ #define FILLORDER_MSB2LSB 1 /* most significant -> least */ #define FILLORDER_LSB2MSB 2 /* least significant -> most */ #define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ #define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ #define TIFFTAG_MAKE 271 /* scanner manufacturer name */ #define TIFFTAG_MODEL 272 /* scanner model name/number */ #define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ #define TIFFTAG_ORIENTATION 274 /* +image orientation */ #define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ #define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ #define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ #define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ #define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ #define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ #define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ #define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ #define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ #define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ #define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ #define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ #define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ #define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ #define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ #define TIFFTAG_PLANARCONFIG 284 /* storage organization */ #define PLANARCONFIG_CONTIG 1 /* single image plane */ #define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ #define TIFFTAG_PAGENAME 285 /* page name image is from */ #define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ #define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ #define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ #define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ #define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ #define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ #define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ #define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ #define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ #define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ #define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ #define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ #define TIFFTAG_T4OPTIONS 292 /* TIFF 6.0 proper name alias */ #define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ #define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ #define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ #define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ #define TIFFTAG_T6OPTIONS 293 /* TIFF 6.0 proper name */ #define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ #define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ #define RESUNIT_NONE 1 /* no meaningful units */ #define RESUNIT_INCH 2 /* english */ #define RESUNIT_CENTIMETER 3 /* metric */ #define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ #define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ #define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ #define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ #define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ #define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ #define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ #define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ #define TIFFTAG_SOFTWARE 305 /* name & release */ #define TIFFTAG_DATETIME 306 /* creation date and time */ #define TIFFTAG_ARTIST 315 /* creator of image */ #define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ #define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ #define PREDICTOR_NONE 1 /* no prediction scheme used */ #define PREDICTOR_HORIZONTAL 2 /* horizontal differencing */ #define PREDICTOR_FLOATINGPOINT 3 /* floating point predictor */ #define TIFFTAG_WHITEPOINT 318 /* image white point */ #define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ #define TIFFTAG_COLORMAP 320 /* RGB map for palette image */ #define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ #define TIFFTAG_TILEWIDTH 322 /* !tile width in pixels */ #define TIFFTAG_TILELENGTH 323 /* !tile height in pixels */ #define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ #define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ #define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ #define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ #define CLEANFAXDATA_CLEAN 0 /* no errors detected */ #define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ #define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ #define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ #define TIFFTAG_SUBIFD 330 /* subimage descriptors */ #define TIFFTAG_INKSET 332 /* !inks in separated image */ #define INKSET_CMYK 1 /* !cyan-magenta-yellow-black color */ #define INKSET_MULTIINK 2 /* !multi-ink or hi-fi color */ #define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ #define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ #define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ #define TIFFTAG_TARGETPRINTER 337 /* !separation target */ #define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ #define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ #define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ #define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ #define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ #define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ #define SAMPLEFORMAT_INT 2 /* !signed integer data */ #define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ #define SAMPLEFORMAT_VOID 4 /* !untyped data */ #define SAMPLEFORMAT_COMPLEXINT 5 /* !complex signed int */ #define SAMPLEFORMAT_COMPLEXIEEEFP 6 /* !complex ieee floating */ #define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ #define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ #define TIFFTAG_CLIPPATH 343 /* %ClipPath [Adobe TIFF technote 2] */ #define TIFFTAG_XCLIPPATHUNITS 344 /* %XClipPathUnits [Adobe TIFF technote 2] */ #define TIFFTAG_YCLIPPATHUNITS 345 /* %YClipPathUnits [Adobe TIFF technote 2] */ #define TIFFTAG_INDEXED 346 /* %Indexed [Adobe TIFF Technote 3] */ #define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ #define TIFFTAG_OPIPROXY 351 /* %OPI Proxy [Adobe TIFF technote] */ /* Tags 400-435 are from the TIFF/FX spec */ #define TIFFTAG_GLOBALPARAMETERSIFD 400 /* ! */ #define TIFFTAG_PROFILETYPE 401 /* ! */ #define PROFILETYPE_UNSPECIFIED 0 /* ! */ #define PROFILETYPE_G3_FAX 1 /* ! */ #define TIFFTAG_FAXPROFILE 402 /* ! */ #define FAXPROFILE_S 1 /* !TIFF/FX FAX profile S */ #define FAXPROFILE_F 2 /* !TIFF/FX FAX profile F */ #define FAXPROFILE_J 3 /* !TIFF/FX FAX profile J */ #define FAXPROFILE_C 4 /* !TIFF/FX FAX profile C */ #define FAXPROFILE_L 5 /* !TIFF/FX FAX profile L */ #define FAXPROFILE_M 6 /* !TIFF/FX FAX profile LM */ #define TIFFTAG_CODINGMETHODS 403 /* !TIFF/FX coding methods */ #define CODINGMETHODS_T4_1D (1 << 1) /* !T.4 1D */ #define CODINGMETHODS_T4_2D (1 << 2) /* !T.4 2D */ #define CODINGMETHODS_T6 (1 << 3) /* !T.6 */ #define CODINGMETHODS_T85 (1 << 4) /* !T.85 JBIG */ #define CODINGMETHODS_T42 (1 << 5) /* !T.42 JPEG */ #define CODINGMETHODS_T43 (1 << 6) /* !T.43 colour by layered JBIG */ #define TIFFTAG_VERSIONYEAR 404 /* !TIFF/FX version year */ #define TIFFTAG_MODENUMBER 405 /* !TIFF/FX mode number */ #define TIFFTAG_DECODE 433 /* !TIFF/FX decode */ #define TIFFTAG_IMAGEBASECOLOR 434 /* !TIFF/FX image base colour */ #define TIFFTAG_T82OPTIONS 435 /* !TIFF/FX T.82 options */ /* * Tags 512-521 are obsoleted by Technical Note #2 which specifies a * revised JPEG-in-TIFF scheme. */ #define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ #define JPEGPROC_BASELINE 1 /* !baseline sequential */ #define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ #define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ #define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ #define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ #define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ #define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ #define TIFFTAG_JPEGQTABLES 519 /* !Q matrix offsets */ #define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ #define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ #define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ #define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ #define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ #define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ #define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ #define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ #define TIFFTAG_STRIPROWCOUNTS 559 /* !TIFF/FX strip row counts */ #define TIFFTAG_XMLPACKET 700 /* %XML packet [Adobe XMP Specification, January 2004 */ #define TIFFTAG_OPIIMAGEID 32781 /* %OPI ImageID [Adobe TIFF technote] */ /* tags 32952-32956 are private tags registered to Island Graphics */ #define TIFFTAG_REFPTS 32953 /* image reference points */ #define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ #define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ #define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ /* tags 32995-32999 are private tags registered to SGI */ #define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ #define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ #define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ #define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ /* tags 33300-33309 are private tags registered to Pixar */ /* * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH * are set when an image has been cropped out of a larger image. * They reflect the size of the original uncropped image. * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used * to determine the position of the smaller image in the larger one. */ #define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ #define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ /* Tags 33302-33306 are used to identify special image modes and data * used by Pixar's texture formats. */ #define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ #define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ #define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ #define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 #define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 /* tag 33405 is a private tag registered to Eastman Kodak */ #define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ #define TIFFTAG_CFAREPEATPATTERNDIM 33421 /* dimensions of CFA pattern */ #define TIFFTAG_CFAPATTERN 33422 /* color filter array pattern */ /* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ #define TIFFTAG_COPYRIGHT 33432 /* copyright string */ /* IPTC TAG from RichTIFF specifications */ #define TIFFTAG_RICHTIFFIPTC 33723 /* 34016-34029 are reserved for ANSI IT8 TIFF/IT */ #define TIFFTAG_STONITS 37439 /* Sample value to Nits */ /* tag 34929 is a private tag registered to FedEx */ #define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ #define TIFFTAG_INTEROPERABILITYIFD 40965 /* Pointer to Interoperability private directory */ /* Adobe Digital Negative (DNG) format tags */ #define TIFFTAG_DNGVERSION 50706 /* &DNG version number */ #define TIFFTAG_DNGBACKWARDVERSION 50707 /* &DNG compatibility version */ #define TIFFTAG_UNIQUECAMERAMODEL 50708 /* &name for the camera model */ #define TIFFTAG_LOCALIZEDCAMERAMODEL 50709 /* &localized camera model name */ #define TIFFTAG_CFAPLANECOLOR 50710 /* &CFAPattern->LinearRaw space mapping */ #define TIFFTAG_CFALAYOUT 50711 /* &spatial layout of the CFA */ #define TIFFTAG_LINEARIZATIONTABLE 50712 /* &lookup table description */ #define TIFFTAG_BLACKLEVELREPEATDIM 50713 /* &repeat pattern size for the BlackLevel tag */ #define TIFFTAG_BLACKLEVEL 50714 /* &zero light encoding level */ #define TIFFTAG_BLACKLEVELDELTAH 50715 /* &zero light encoding level differences (columns) */ #define TIFFTAG_BLACKLEVELDELTAV 50716 /* &zero light encoding level differences (rows) */ #define TIFFTAG_WHITELEVEL 50717 /* &fully saturated encoding level */ #define TIFFTAG_DEFAULTSCALE 50718 /* &default scale factors */ #define TIFFTAG_DEFAULTCROPORIGIN 50719 /* &origin of the final image area */ #define TIFFTAG_DEFAULTCROPSIZE 50720 /* &size of the final image area */ #define TIFFTAG_COLORMATRIX1 50721 /* &XYZ->reference color space transformation matrix 1 */ #define TIFFTAG_COLORMATRIX2 50722 /* &XYZ->reference color space transformation matrix 2 */ #define TIFFTAG_CAMERACALIBRATION1 50723 /* &calibration matrix 1 */ #define TIFFTAG_CAMERACALIBRATION2 50724 /* &calibration matrix 2 */ #define TIFFTAG_REDUCTIONMATRIX1 50725 /* &dimensionality reduction matrix 1 */ #define TIFFTAG_REDUCTIONMATRIX2 50726 /* &dimensionality reduction matrix 2 */ #define TIFFTAG_ANALOGBALANCE 50727 /* &gain applied the stored raw values*/ #define TIFFTAG_ASSHOTNEUTRAL 50728 /* &selected white balance in linear reference space */ #define TIFFTAG_ASSHOTWHITEXY 50729 /* &selected white balance in x-y chromaticity coordinates */ #define TIFFTAG_BASELINEEXPOSURE 50730 /* &how much to move the zero point */ #define TIFFTAG_BASELINENOISE 50731 /* &relative noise level */ #define TIFFTAG_BASELINESHARPNESS 50732 /* &relative amount of sharpening */ #define TIFFTAG_BAYERGREENSPLIT 50733 /* &how closely the values of the green pixels in the blue/green rows track the values of the green pixels in the red/green rows */ #define TIFFTAG_LINEARRESPONSELIMIT 50734 /* &non-linear encoding range */ #define TIFFTAG_CAMERASERIALNUMBER 50735 /* &camera's serial number */ #define TIFFTAG_LENSINFO 50736 /* info about the lens */ #define TIFFTAG_CHROMABLURRADIUS 50737 /* &chroma blur radius */ #define TIFFTAG_ANTIALIASSTRENGTH 50738 /* &relative strength of the camera's anti-alias filter */ #define TIFFTAG_SHADOWSCALE 50739 /* &used by Adobe Camera Raw */ #define TIFFTAG_DNGPRIVATEDATA 50740 /* &manufacturer's private data */ #define TIFFTAG_MAKERNOTESAFETY 50741 /* &whether the EXIF MakerNote tag is safe to preserve along with the rest of the EXIF data */ #define TIFFTAG_CALIBRATIONILLUMINANT1 50778 /* &illuminant 1 */ #define TIFFTAG_CALIBRATIONILLUMINANT2 50779 /* &illuminant 2 */ #define TIFFTAG_BESTQUALITYSCALE 50780 /* &best quality multiplier */ #define TIFFTAG_RAWDATAUNIQUEID 50781 /* &unique identifier for the raw image data */ #define TIFFTAG_ORIGINALRAWFILENAME 50827 /* &file name of the original raw file */ #define TIFFTAG_ORIGINALRAWFILEDATA 50828 /* &contents of the original raw file */ #define TIFFTAG_ACTIVEAREA 50829 /* &active (non-masked) pixels of the sensor */ #define TIFFTAG_MASKEDAREAS 50830 /* &list of coordinates of fully masked pixels */ #define TIFFTAG_ASSHOTICCPROFILE 50831 /* &these two tags used to */ #define TIFFTAG_ASSHOTPREPROFILEMATRIX 50832 /* map cameras's color space into ICC profile space */ #define TIFFTAG_CURRENTICCPROFILE 50833 /* & */ #define TIFFTAG_CURRENTPREPROFILEMATRIX 50834 /* & */ /* tag 65535 is an undefined tag used by Eastman Kodak */ #define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ /* * The following are ``pseudo tags'' that can be used to control * codec-specific functionality. These tags are not written to file. * Note that these values start at 0xffff+1 so that they'll never * collide with Aldus-assigned tags. * * If you want your private pseudo tags ``registered'' (i.e. added to * this file), please post a bug report via the tracking system at * http://www.remotesensing.org/libtiff/bugs.html with the appropriate * C definitions to add. */ #define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ #define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ #define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ #define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ #define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ #define FAXMODE_WORDALIGN 0x0008 /* word align row */ #define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ #define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ /* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ #define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ #define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ #define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ #define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ #define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ #define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ /* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ #define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ #define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ #define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ #define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ #define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ #define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ #define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ #define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ /* 65550-65556 are allocated to Oceana Matrix */ #define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ #define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ #define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ #define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ #define DCSIMAGERFILTER_IR 0 /* infrared filter */ #define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ #define DCSIMAGERFILTER_CFA 2 /* color filter array */ #define DCSIMAGERFILTER_OTHER 3 /* other filter */ #define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ #define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ #define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ #define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ #define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ #define TIFFTAG_DCSGAMMA 65554 /* gamma value */ #define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ #define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ /* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ #define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ #define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ /* 65559 is allocated to Oceana Matrix */ #define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ #define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ #define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ #define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ #define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ #define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ #define TIFFTAG_SGILOGENCODE 65561 /* SGILog data encoding control*/ #define SGILOGENCODE_NODITHER 0 /* do not dither encoded values*/ #define SGILOGENCODE_RANDITHER 1 /* randomly dither encd values */ #define TIFFTAG_LZMAPRESET 65562 /* LZMA2 preset (compression level) */ #define TIFFTAG_PERSAMPLE 65563 /* interface for per sample tags */ #define PERSAMPLE_MERGED 0 /* present as a single value */ #define PERSAMPLE_MULTI 1 /* present as multiple values */ #define TIFFTAG_ZSTD_LEVEL 65564 /* ZSTD compression level */ /* * EXIF tags */ #define EXIFTAG_EXPOSURETIME 33434 /* Exposure time */ #define EXIFTAG_FNUMBER 33437 /* F number */ #define EXIFTAG_EXPOSUREPROGRAM 34850 /* Exposure program */ #define EXIFTAG_SPECTRALSENSITIVITY 34852 /* Spectral sensitivity */ #define EXIFTAG_ISOSPEEDRATINGS 34855 /* ISO speed rating */ #define EXIFTAG_OECF 34856 /* Optoelectric conversion factor */ #define EXIFTAG_EXIFVERSION 36864 /* Exif version */ #define EXIFTAG_DATETIMEORIGINAL 36867 /* Date and time of original data generation */ #define EXIFTAG_DATETIMEDIGITIZED 36868 /* Date and time of digital data generation */ #define EXIFTAG_COMPONENTSCONFIGURATION 37121 /* Meaning of each component */ #define EXIFTAG_COMPRESSEDBITSPERPIXEL 37122 /* Image compression mode */ #define EXIFTAG_SHUTTERSPEEDVALUE 37377 /* Shutter speed */ #define EXIFTAG_APERTUREVALUE 37378 /* Aperture */ #define EXIFTAG_BRIGHTNESSVALUE 37379 /* Brightness */ #define EXIFTAG_EXPOSUREBIASVALUE 37380 /* Exposure bias */ #define EXIFTAG_MAXAPERTUREVALUE 37381 /* Maximum lens aperture */ #define EXIFTAG_SUBJECTDISTANCE 37382 /* Subject distance */ #define EXIFTAG_METERINGMODE 37383 /* Metering mode */ #define EXIFTAG_LIGHTSOURCE 37384 /* Light source */ #define EXIFTAG_FLASH 37385 /* Flash */ #define EXIFTAG_FOCALLENGTH 37386 /* Lens focal length */ #define EXIFTAG_SUBJECTAREA 37396 /* Subject area */ #define EXIFTAG_MAKERNOTE 37500 /* Manufacturer notes */ #define EXIFTAG_USERCOMMENT 37510 /* User comments */ #define EXIFTAG_SUBSECTIME 37520 /* DateTime subseconds */ #define EXIFTAG_SUBSECTIMEORIGINAL 37521 /* DateTimeOriginal subseconds */ #define EXIFTAG_SUBSECTIMEDIGITIZED 37522 /* DateTimeDigitized subseconds */ #define EXIFTAG_FLASHPIXVERSION 40960 /* Supported Flashpix version */ #define EXIFTAG_COLORSPACE 40961 /* Color space information */ #define EXIFTAG_PIXELXDIMENSION 40962 /* Valid image width */ #define EXIFTAG_PIXELYDIMENSION 40963 /* Valid image height */ #define EXIFTAG_RELATEDSOUNDFILE 40964 /* Related audio file */ #define EXIFTAG_FLASHENERGY 41483 /* Flash energy */ #define EXIFTAG_SPATIALFREQUENCYRESPONSE 41484 /* Spatial frequency response */ #define EXIFTAG_FOCALPLANEXRESOLUTION 41486 /* Focal plane X resolution */ #define EXIFTAG_FOCALPLANEYRESOLUTION 41487 /* Focal plane Y resolution */ #define EXIFTAG_FOCALPLANERESOLUTIONUNIT 41488 /* Focal plane resolution unit */ #define EXIFTAG_SUBJECTLOCATION 41492 /* Subject location */ #define EXIFTAG_EXPOSUREINDEX 41493 /* Exposure index */ #define EXIFTAG_SENSINGMETHOD 41495 /* Sensing method */ #define EXIFTAG_FILESOURCE 41728 /* File source */ #define EXIFTAG_SCENETYPE 41729 /* Scene type */ #define EXIFTAG_CFAPATTERN 41730 /* CFA pattern */ #define EXIFTAG_CUSTOMRENDERED 41985 /* Custom image processing */ #define EXIFTAG_EXPOSUREMODE 41986 /* Exposure mode */ #define EXIFTAG_WHITEBALANCE 41987 /* White balance */ #define EXIFTAG_DIGITALZOOMRATIO 41988 /* Digital zoom ratio */ #define EXIFTAG_FOCALLENGTHIN35MMFILM 41989 /* Focal length in 35 mm film */ #define EXIFTAG_SCENECAPTURETYPE 41990 /* Scene capture type */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_CONTRAST 41992 /* Contrast */ #define EXIFTAG_SATURATION 41993 /* Saturation */ #define EXIFTAG_SHARPNESS 41994 /* Sharpness */ #define EXIFTAG_DEVICESETTINGDESCRIPTION 41995 /* Device settings description */ #define EXIFTAG_SUBJECTDISTANCERANGE 41996 /* Subject distance range */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_GAINCONTROL 41991 /* Gain control */ #define EXIFTAG_IMAGEUNIQUEID 42016 /* Unique image ID */ #endif /* _TIFF_ */ /* vim: set ts=8 sts=8 sw=8 noet: */ /* * Local Variables: * mode: c * c-basic-offset: 8 * fill-column: 78 * End: */ //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- // parts of filter.c static void panoSetMetadataDefaults(pano_ImageMetadata* m) { bzero(m, sizeof(*m)); // These are "meaningful defaults m->xPixelsPerResolution = PANO_DEFAULT_PIXELS_PER_RESOLUTION; m->yPixelsPerResolution = PANO_DEFAULT_PIXELS_PER_RESOLUTION; m->resolutionUnits = PANO_DEFAULT_TIFF_RESOLUTION_UNITS; m->rowsPerStrip = 1; // THis will speed up processing of TIFFs as only one line // at a time needs to be read m->compression.type = PANO_DEFAULT_TIFF_COMPRESSION; } void SetImageDefaults(Image* im) { im->data = NULL; im->bytesPerLine = 0; im->width = 0; im->height = 0; im->dataSize = 0; im->bitsPerPixel = 0; im->format = 0; im->formatParamCount = 0; bzero(im->formatParam, sizeof(im->formatParam)); im->precomputedCount = 0; bzero(im->precomputedValue, sizeof(im->precomputedValue)); im->dataformat = _RGB; im->hfov = 0.0; im->yaw = 0.0; im->pitch = 0.0; im->roll = 0.0; SetCorrectDefaults(&(im->cP)); *(im->name) = 0; im->selection.top = 0; im->selection.bottom = 0; im->selection.left = 0; im->selection.right = 0; im->cropInformation.cropped_height = 0; im->cropInformation.cropped_width = 0; im->cropInformation.full_height = 0; im->cropInformation.full_width = 0; im->cropInformation.x_offset = 0; im->cropInformation.y_offset = 0; panoSetMetadataDefaults(&im->metadata); #ifdef CAN_READ_HUGIN_FILES im->Ra = 0; im->Rb = 0; im->Rc = 0; im->Rd = 0; im->Re = 0; im->Eev = 0; im->Er = 0; im->Eb = 0; im->Vm = 0; im->Va = 0; im->Vb = 0; im->Vc = 0; im->Vd = 0; im->Vx = 0; im->Vy = 0; im->Vfilename[0] = 0; im->jStackNr = 0; im->HuginImgInfoLine[0] = 0; im->HuginImgInfoLine[HuginImgInfoLineSize] = 0; #endif // CAN_READ_HUGIN_FILES } #ifdef CAN_READ_HUGIN_FILES void SetPanoImageInfoDefaults(PanoImageInfo* im) { im->pto_format = 0; im->k = -1; im->d = -1; im->b = -1; im->u = 0; im->SelLeft = 0; im->SelRight = 0; im->SelTop = 0; im->SelBottom = 0; im->TParam[0] = 0; im->TParam[PanoramaImageTParamSize] = 0; im->RParam = 0; im->EParam = 0; } #endif //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------------- #include #include "filter.h" #include //#include "ZComb.h" //#include "adjust.h" #include /* defined in adjust.c */ int AddEdgePoints(AlignInfo* gl); void setFcnPanoHuberSigma(double sigma); double getFcnPanoHuberSigma(); static int ReadControlPoint(controlPoint* cptr, char* line); static int ReadImageDescription(Image* imPtr, stBuf* sPtr, char* line); static int ReadModeDescription(sPrefs* sP, char* line); static int ReadCoordinates(CoordInfo* cp, char* line); #ifdef CAN_READ_HUGIN_FILES static int ReadPanoramaDescription(Image* imPtr, PanoImageInfo* iminfoPtr, stBuf* sPtr, char* line); #else static int ReadPanoramaDescription(Image* imPtr, stBuf* sPtr, char* line); #endif static int panoExternalToInternalInputProjection(int32_t input); #define nextWordBuf(char_ptr_ptr_ch) nextWord(buf, (char_ptr_ptr_ch), LINE_LENGTH) #define MY_SSCANF( str, format, ptr ) if( sscanf( str, format, ptr ) != 1 ) \ { \ PrintError( \ "Syntax error in script: Line %d\nCould not assign variable [%s]",\ lineNum, str); \ goto fail; \ } #define READ_VAR(format, ptr ) nextWordBuf(&li); \ MY_SSCANF( buf, format, ptr ); #define READ_OPT_VAR(var) if(0 != pstddev) \ { \ multiple_optvars_in_line = 1; \ } \ nextWordBuf(&li); \ MY_SSCANF( buf, "%d", &k); \ if( k<0 || k>= numIm ) \ { \ PrintError("Error in script: Line %d\n\nIllegal image number: %ld", lineNum, k); \ goto fail; \ } \ if(!inactive && gl->allopt[k].var) \ { \ PrintError("Conflict in script: Line %d. Multiple Instances of Variable %s Image number: %d (%d)", lineNum, #var, k, gl->allopt[k].var); \ goto fail; \ } \ gl->allopt[k].var = inactive ? -1 : 1; \ pstddev = &(gl->allopt[k].s##var); \ pweight = &(gl->allopt[k].w##var); \ pminval = &(gl->allopt[k].min##var); \ pmaxval = &(gl->allopt[k].max##var); \ n++; #define WRITE_OPT_VAR(var, symbol) \ if(1 == fabs(allopt->var)) \ { \ CHECK_MEM_ERROR(AppendFmtAdvancePtr("v %s" #symbol "%d", -1==allopt->var ? "-" : "", i)); \ if(allopt->s##var >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" s%.15g", allopt->s##var)); \ if(allopt->w##var >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" w%.15g", allopt->w##var)); \ if(allopt->min##var != -DBL_MAX) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" min%.15g", allopt->min##var)); \ if(allopt->max##var != DBL_MAX) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" max%.15g", allopt->max##var)); \ CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n")); \ } #define PROCESS_ALLOPT_ASSIGN_OPT(var, imvar, scriptvar) \ gl->opt[i].var = gl->allopt[i].var; \ gl->opt[i].s##var = -1; \ gl->opt[i].w##var = -1; \ gl->opt[i].min##var = -DBL_MAX; \ gl->opt[i].max##var = DBL_MAX; \ if(!k && 1 == gl->allopt[i].var && (gl->im[i].imvar < gl->allopt[i].min##var || gl->im[i].imvar > gl->allopt[i].max##var)) \ { \ PrintError("Conflict in script. Parameter %s for image %d (with value %.15g) defined in 'i' line is outside the min-max-interval [%.15g, %.15g].", \ #scriptvar, i, gl->im[i].imvar, gl->allopt[i].min##var, gl->allopt[i].max##var); \ goto fail; \ } \ if(!k && 1 == gl->allopt[i].var && (gl->im[i].imvar == gl->allopt[i].min##var || gl->im[i].imvar == gl->allopt[i].max##var))\ { \ PrintError("Warning in script. Parameter %s for image %d (with value %.15g) defined in 'i' line\n" \ "is on a boundary of the the min-max-interval [%.15g, %.15g].\n" \ "PTOptimizer will be unable to move the parameter away from the boundary.\n" \ "Consider widening the interval.\n\n", \ #scriptvar, i, gl->im[i].imvar, gl->allopt[i].min##var, gl->allopt[i].max##var); \ } \ else if(!k && 1 == gl->allopt[i].var && gl->allopt[i].min##var != -DBL_MIN && gl->allopt[i].max##var != DBL_MAX && \ gl->allopt[i].max##var > gl->allopt[i].min##var && \ (0.99*(gl->allopt[i].max##var - gl->allopt[i].min##var) < (gl->im[i].imvar - gl->allopt[i].min##var) || \ 0.01*(gl->allopt[i].max##var - gl->allopt[i].min##var) > (gl->im[i].imvar - gl->allopt[i].min##var))) \ { \ PrintError("Warning in script. Parameter %s for image %d (with value %.15g) defined in 'i' line\n" \ "is near a boundary of the the min-max-interval [%.15g, %.15g].\n" \ "PTOptimizer may be unable to move the parameter away from the boundary.\n" \ "PTOptimizer may need many iterations.\n" \ "Consider widening the interval.\n\n", \ #scriptvar, i, gl->im[i].imvar, gl->allopt[i].min##var, gl->allopt[i].max##var); \ } \ /* exclude from optimization if gl->allopt[i].min##var == gl->allopt[i].max##var or 0 == gl->allopt[i].s##var */ \ /* or -1 == gl->allopt[i].var (minus sign before opt var in script */ \ if (1 == gl->allopt[i].var && 0 != gl->allopt[i].s##var && gl->allopt[i].min##var < gl->allopt[i].max##var) \ { \ gl->opt[i].s##var = gl->allopt[i].s##var; \ gl->opt[i].w##var = gl->allopt[i].w##var; \ gl->opt[i].min##var = gl->allopt[i].min##var; \ gl->opt[i].max##var = gl->allopt[i].max##var; \ if (0 != gl->allopt[i].w##var && (gl->allopt[i].s##var > 0 || gl->allopt[i].w##var > 0)) { \ if (k) { \ gl->var_constraint_indices[nr_var_constraints] = n; \ gl->initial_cned_parameters[nr_var_constraints] = gl->im[i].imvar; \ gl->min_cned_parameters[nr_var_constraints] = gl->allopt[i].min##var; \ gl->max_cned_parameters[nr_var_constraints] = gl->allopt[i].max##var; \ gl->cned_parameters_weights[nr_var_constraints] = 1.0; \ if(gl->allopt[i].w##var > 0) gl->cned_parameters_weights[nr_var_constraints] = sqrt(gl->allopt[i].w##var); \ if(gl->allopt[i].s##var > 0) gl->cned_parameters_weights[nr_var_constraints] /= gl->allopt[i].s##var; \ } \ nr_var_constraints++; \ } \ n++; \ } //Increased so more params can be parsed/optimized (MRDL - March 2002) #define LINE_LENGTH 65536 #define panoLocaleSave char *oldLocale;oldLocale=Strdup(setlocale(LC_ALL, NULL));setlocale(LC_ALL, "C") #define panoLocaleRestore (oldLocale != NULL? (setlocale(LC_ALL,oldLocale),free(oldLocale)):0) #ifdef CAN_READ_HUGIN_FILES char LastHuginImgInfoLine[HuginImgInfoLineSize + 1]; char* WriteVarOrEqImgNr(int opt_var, double img_var) { static char WriteVarOrEqImgNrBuffer[1024]; static int WriteVarOrEqImgNrIndex = 0; char* WriteVarOrEqImgNrRet = &WriteVarOrEqImgNrBuffer[WriteVarOrEqImgNrIndex]; if (opt_var >= 2) { WriteVarOrEqImgNrIndex += snprintf(WriteVarOrEqImgNrRet, 512, "=%u", (opt_var)-2) + 1; } else { WriteVarOrEqImgNrIndex += snprintf(WriteVarOrEqImgNrRet, 512, "%.15g", img_var) + 1; } if (WriteVarOrEqImgNrIndex >= 512) { WriteVarOrEqImgNrIndex = 0; } return WriteVarOrEqImgNrRet; } char* WriteDoubleIfNotDefault(const char* prefix, double val, double default_val) { static char WriteVarOrEqImgNrBuffer[1024]; static int WriteVarOrEqImgNrIndex = 0; char* WriteVarOrEqImgNrRet = &WriteVarOrEqImgNrBuffer[WriteVarOrEqImgNrIndex]; if (val != default_val) { WriteVarOrEqImgNrIndex += snprintf(WriteVarOrEqImgNrRet, 512, "%s%.15g", prefix, val) + 1; } else { WriteVarOrEqImgNrRet[0] = 0; WriteVarOrEqImgNrIndex++; } if (WriteVarOrEqImgNrIndex >= 512) { WriteVarOrEqImgNrIndex = 0; } return WriteVarOrEqImgNrRet; } char* WriteIntegerIfNotDefault(const char* prefix, long long val, long long default_val) { static char WriteVarOrEqImgNrBuffer[1024]; static int WriteVarOrEqImgNrIndex = 0; char* WriteVarOrEqImgNrRet = &WriteVarOrEqImgNrBuffer[WriteVarOrEqImgNrIndex]; if (val != default_val) { WriteVarOrEqImgNrIndex += snprintf(WriteVarOrEqImgNrRet, 512, "%s%lld", prefix, val) + 1; } else { WriteVarOrEqImgNrRet[0] = 0; WriteVarOrEqImgNrIndex++; } if (WriteVarOrEqImgNrIndex >= 512) { WriteVarOrEqImgNrIndex = 0; } return WriteVarOrEqImgNrRet; } #endif // CAN_READ_HUGIN_FILES // Optimizer Script parser; fill global info structure char* panoParseVariable(char* buf, char* li, int lineNum, int* indirectVar, double* var) { if (*(li + 1) == '=') { li++; // point to next character nextWordBuf(&li); if (sscanf(buf, "%d", indirectVar) != 1) { PrintError("Syntax error in script: Line %d\nCould not assign variable %s", lineNum, li - 1); return NULL; } (*indirectVar) += 2; //its offset should be increased by 2... arghh } else { nextWordBuf(&li); if (sscanf(buf, " %lf", var) != 1) { PrintError("Syntax error in script: Line %d\nCould not assign variable %s", lineNum, li - 1); return NULL; } } return li; } void SetEquColor(cPrefs* cP) { int col, i; for (col = 1; col < 3; col++) { for (i = 0; i < 4; i++) cP->radial_params[col][i] = cP->radial_params[0][i]; cP->vertical_params[col] = cP->vertical_params[0]; cP->horizontal_params[col] = cP->horizontal_params[0]; } } void squareZero(double* a, int* n, double* root) { if (a[2] == 0.0) { // linear equation if (a[1] == 0.0) { // constant if (a[0] == 0.0) { *n = 1; root[0] = 0.0; } else { *n = 0; } } else { *n = 1; root[0] = -a[0] / a[1]; } } else { if (4.0 * a[2] * a[0] > a[1] * a[1]) { *n = 0; } else { *n = 2; root[0] = (-a[1] + sqrt(a[1] * a[1] - 4.0 * a[2] * a[0])) / (2.0 * a[2]); root[1] = (-a[1] - sqrt(a[1] * a[1] - 4.0 * a[2] * a[0])) / (2.0 * a[2]); } } } double cubeRoot(double x) { if (x == 0.0) return 0.0; else if (x > 0.0) return pow(x, 1.0 / 3.0); else return -pow(-x, 1.0 / 3.0); } void cubeZero(double* a, int* n, double* root) { if (a[3] == 0.0) { // second order polynomial squareZero(a, n, root); } else { double p = ((-1.0 / 3.0) * (a[2] / a[3]) * (a[2] / a[3]) + a[1] / a[3]) / 3.0; double q = ((2.0 / 27.0) * (a[2] / a[3]) * (a[2] / a[3]) * (a[2] / a[3]) - (1.0 / 3.0) * (a[2] / a[3]) * (a[1] / a[3]) + a[0] / a[3]) / 2.0; if (q * q + p * p * p >= 0.0) { *n = 1; root[0] = cubeRoot(-q + sqrt(q * q + p * p * p)) + cubeRoot(-q - sqrt(q * q + p * p * p)) - a[2] / (3.0 * a[3]); } else { double phi = acos(-q / sqrt(-p * p * p)); *n = 3; root[0] = 2.0 * sqrt(-p) * cos(phi / 3.0) - a[2] / (3.0 * a[3]); root[1] = -2.0 * sqrt(-p) * cos(phi / 3.0 + PI / 3.0) - a[2] / (3.0 * a[3]); root[2] = -2.0 * sqrt(-p) * cos(phi / 3.0 - PI / 3.0) - a[2] / (3.0 * a[3]); } } // PrintError("%lg, %lg, %lg, %lg root = %lg", a[3], a[2], a[1], a[0], root[0]); } double smallestRoot(double* p) { int n, i; double root[3], sroot = 1000.0; cubeZero(p, &n, root); for (i = 0; i < n; i++) { // PrintError("Root %d = %lg", i,root[i]); if (root[i] > 0.0 && root[i] < sroot) sroot = root[i]; } // PrintError("Smallest Root = %lg", sroot); return sroot; } // Restrict radial correction to monotonous interval void SetCorrectionRadius(cPrefs* cP) { double a[4]; int i, k; for (i = 0; i < 3; i++) { for (k = 0; k < 4; k++) { a[k] = 0.0;//1.0e-10; if (cP->radial_params[i][k] != 0.0) { a[k] = (k + 1) * cP->radial_params[i][k]; } } cP->radial_params[i][4] = smallestRoot(a); } } int ParseScript(char* script, AlignInfo* gl) { Image* im; optVars* allopt; CoordInfo* ci; #ifdef CAN_READ_HUGIN_FILES HuginImageMask* immask; char* HuginOptionsNextCharMem; int NrHuginOptions; #endif // CAN_READ_HUGIN_FILES // Variables used by parser char* li, line[LINE_LENGTH], * ch, * lineStart, buf[LINE_LENGTH], * b; int lineNum = 0; int i, k; int n = 0; // Number of parameters to optimize int numIm, numPts, nt; #ifdef CAN_READ_HUGIN_FILES int numhuginmasks; #endif // CAN_READ_HUGIN_FILES double stddev, weight, minval, maxval, * pstddev, * pweight, * pminval, * pmaxval; int multiple_optvars_in_line, minval_defined, maxval_defined; int nr_var_constraints; int inactive; panoLocaleSave; gl->im = NULL; gl->opt = NULL; gl->cpt = NULL; gl->t = NULL; gl->cim = NULL; #ifdef CAN_READ_HUGIN_FILES gl->HuginOptionsCharMem = NULL; gl->HuginOptions = NULL; #endif // CAN_READ_HUGIN_FILES gl->var_constraint_indices = NULL; gl->initial_cned_parameters = NULL; gl->cned_parameters_weights = NULL; gl->min_cned_parameters = NULL; gl->max_cned_parameters = NULL; // Determine number of images and control points gl->numIm = numLines(script, 'i'); gl->numPts = numLines(script, 'c'); gl->nt = numLines(script, 't'); #ifdef CAN_READ_HUGIN_FILES gl->numhuginmasks = numLines(script, 'k'); #endif // CAN_READ_HUGIN_FILES // Allocate Space for Pointers to images, preferences and control points gl->im = (Image*)malloc(gl->numIm * sizeof(Image)); gl->opt = (optVars*)malloc(gl->numIm * sizeof(optVars)); gl->allopt = (optVars*)malloc(gl->numIm * sizeof(optVars)); gl->cpt = (controlPoint*)malloc(gl->numPts * sizeof(controlPoint)); gl->t = (triangle*)malloc(gl->nt * sizeof(triangle)); gl->cim = (CoordInfo*)malloc(gl->numIm * sizeof(CoordInfo)); #ifdef CAN_READ_HUGIN_FILES gl->huginmasks = (HuginImageMask*)malloc(gl->numhuginmasks * sizeof(HuginImageMask)); gl->HuginOptions = (char**)malloc(sizeof(char*) * (MaxNrHuginOptions + 1)); HuginOptionsNextCharMem = gl->HuginOptionsCharMem = (char*)malloc(sizeof(char) * (MaxHuginOptionsCharMemSize + 1)); #endif // CAN_READ_HUGIN_FILES if (gl->im == NULL || gl->opt == NULL || gl->allopt == NULL || gl->cpt == NULL || gl->t == NULL || gl->cim == NULL) { PrintError("Not enough memory"); goto fail; } #ifdef CAN_READ_HUGIN_FILES if (gl->HuginOptionsCharMem == NULL || gl->huginmasks == NULL || gl->HuginOptions == NULL) { PrintError("Not enough memory"); goto fail; } for (i = 0; i < MaxNrHuginOptions; i++) gl->HuginOptions[i] = 0; NrHuginOptions = 0; #endif // CAN_READ_HUGIN_FILES // Rik's mask-from-focus hacking //ZCombSetDisabled(); // end mask-from-focus Rik's hacking SetImageDefaults(&(gl->pano)); #ifdef CAN_READ_HUGIN_FILES SetPanoImageInfoDefaults(&(gl->panoinfo)); #endif SetSizeDefaults(&(gl->sP)); SetStitchDefaults(&(gl->st)); StrcpyN(gl->st.srcName, "buf", 256); // Default: Use buffer 'buf' for stitching // printf("Number of images %d\n",gl-> numIm); for (i = 0; i < gl->numIm; i++) { SetImageDefaults(&(gl->im[i])); SetOptDefaults(&(gl->opt[i])); SetOptDefaults(&(gl->allopt[i])); SetCoordDefaults(&(gl->cim[i]), i); } numIm = 0; numPts = 0; nt = 0; // reused as indices #ifdef CAN_READ_HUGIN_FILES numhuginmasks = 0; #endif // CAN_READ_HUGIN_FILES // Parse script #ifdef CAN_READ_HUGIN_FILES LastHuginImgInfoLine[0] = 0; LastHuginImgInfoLine[HuginImgInfoLineSize] = 0; #endif // CAN_READ_HUGIN_FILES for (ch = script; 0 != *ch; ('\r' == *ch) ? ch++ : ch, ('\n' == *ch) ? ch++ : ch, ('\r' == *ch) ? ch++ : ch ) { lineNum++; while (*ch == '\n') { ch++; lineNum++; } lineStart = ch; lineNum += nextLine(line, &ch); // parse line; use only if first character is i,p,v,c,m switch (line[0]) { #ifdef CAN_READ_HUGIN_FILES case '#': if (0 == strncmp(line, "#-hugin ", 8)) { StrcpyN(LastHuginImgInfoLine, &line[0], HuginImgInfoLineSize + 1); } else if (0 == strncmp(line, "#hugin_", 7) && 0 != strncmp(line, "#hugin_ptoversion", 17)) { if (NrHuginOptions >= MaxNrHuginOptions) { PrintError("Error in script. Too many hugin options (#hugin_). Maximum is %d. Line %d\n", MaxNrHuginOptions, lineNum); goto fail; } if (strlen(line) + 1 >= MaxHuginOptionsCharMemSize - (HuginOptionsNextCharMem - gl->HuginOptionsCharMem)) { PrintError("Error in script. No more memory to store hugin option (#hugin_). Line %d\n", lineNum); goto fail; } gl->HuginOptions[NrHuginOptions] = HuginOptionsNextCharMem; strcpy_unsecure(gl->HuginOptions[NrHuginOptions], &line[0]); // buffer size already checked HuginOptionsNextCharMem += strlen(line) + 1; NrHuginOptions++; } break; #endif // CAN_READ_HUGIN_FILES case 'i': // Image description im = &(gl->im[numIm]); // This image is being set allopt = &(gl->allopt[numIm]); ci = &(gl->cim[numIm]); li = &(line[1]); #ifdef CAN_READ_HUGIN_FILES StrcpyN(&im->HuginImgInfoLine[0], LastHuginImgInfoLine, HuginImgInfoLineSize + 1); im->HuginImgInfoLine[HuginImgInfoLineSize] = 0; // for case that not all has been copied #endif // CAN_READ_HUGIN_FILES while (*li != 0) { switch (*li) { case 'w': READ_VAR("%u", &(im->width)); break; case 'h': READ_VAR("%u", &(im->height)); break; case 'v': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->hfov)); allopt->hfov += 2; } else { READ_VAR("%lf", &(im->hfov)); } break; case 'a': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->a)); allopt->a += 2; } else { READ_VAR("%lf", &(im->cP.radial_params[0][3])); } im->cP.radial = TRUE; break; case 'b': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->b)); allopt->b += 2; } else { READ_VAR("%lf", &(im->cP.radial_params[0][2])); } im->cP.radial = TRUE; break; case 'c': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->c)); allopt->c += 2; } else { READ_VAR("%lf", &(im->cP.radial_params[0][1])); } im->cP.radial = TRUE; break; case 'f': READ_VAR("%d", &k); switch (k) { case IMAGE_FORMAT_RECTILINEAR: im->format = _rectilinear; break; case IMAGE_FORMAT_PANORAMA: im->format = _panorama; im->cP.correction_mode |= correction_mode_vertical; break; case IMAGE_FORMAT_FISHEYE_EQUIDISTANCECIRC: im->format = _fisheye_circ; break; case IMAGE_FORMAT_FISHEYE_EQUIDISTANCEFF: im->format = _fisheye_ff; break; case IMAGE_FORMAT_EQUIRECTANGULAR: im->format = _equirectangular; im->cP.correction_mode |= correction_mode_vertical; break; case IMAGE_FORMAT_MIRROR: im->format = _mirror; break; case IMAGE_FORMAT_FISHEYE_ORTHOGRAPHIC: im->format = _orthographic; break; case IMAGE_FORMAT_FISHEYE_STEREOGRAPHIC: im->format = _stereographic; break; case IMAGE_FORMAT_FISHEYE_EQUISOLID: im->format = _equisolid; break; case IMAGE_FORMAT_FISHEYE_THOBY: im->format = _thoby; break; break; default: PrintError("Syntax error in script. Projection not known: Line %d", lineNum); goto fail; break; } break; case 'o': li++; im->cP.correction_mode |= correction_mode_morph; break; case 'y': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->yaw)); allopt->yaw += 2; } else { READ_VAR("%lf", &(im->yaw)); } break; case 'p': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->pitch)); allopt->pitch += 2; } else { READ_VAR("%lf", &(im->pitch)); } break; case 'r': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->roll)); allopt->roll += 2; } else { READ_VAR("%lf", &(im->roll)); } break; case 'd': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->d)); allopt->d += 2; } else { READ_VAR("%lf", &(im->cP.horizontal_params[0])); } im->cP.horizontal = TRUE; break; case 'e': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->e)); allopt->e += 2; } else { READ_VAR("%lf", &(im->cP.vertical_params[0])); } im->cP.vertical = TRUE; break; case 'g': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->shear_x)); allopt->shear_x += 2; } else { READ_VAR("%lf", &(im->cP.shear_x)); } im->cP.shear = TRUE; break; case 't': if (*(li + 1) == '=') { li++; READ_VAR("%d", &(allopt->shear_y)); allopt->shear_y += 2; } else { READ_VAR("%lf", &(im->cP.shear_y)); } im->cP.shear = TRUE; break; case 'T': li++; switch (*li) { case 'i': // Tilt li++; switch (*li) { case 'X': li = panoParseVariable(buf, li, lineNum, &(allopt->tiltXopt), &(im->cP.tilt_x)); break; case 'Y': li = panoParseVariable(buf, li, lineNum, &(allopt->tiltYopt), &(im->cP.tilt_y)); break; case 'Z': li = panoParseVariable(buf, li, lineNum, &(allopt->tiltZopt), &(im->cP.tilt_z)); break; case 'S': li = panoParseVariable(buf, li, lineNum, &(allopt->tiltScaleOpt), &(im->cP.tilt_scale)); if (allopt->tiltScaleOpt > 1) { // it is an actual value to optimize, not a reference... check it if (im->cP.tilt_scale == 0) { PrintError("TiS parameter can't be zero. Error in script: Line %d", lineNum); goto fail; } } break; default: PrintError("Unkonwn parameter Ti%c in script: Line %d", *li, lineNum); goto fail; } if (li == NULL) goto fail; im->cP.tilt = TRUE; break; case 'r': // Translation li++; switch (*li) { case 'X': li = panoParseVariable(buf, li, lineNum, &(allopt->transXopt), &(im->cP.trans_x)); break; case 'Y': li = panoParseVariable(buf, li, lineNum, &(allopt->transYopt), &(im->cP.trans_y)); break; case 'Z': li = panoParseVariable(buf, li, lineNum, &(allopt->transZopt), &(im->cP.trans_z)); break; default: PrintError("Unknown translation parameter Tr%c in script: Line %d", *li, lineNum); goto fail; } if (li == NULL) goto fail; // Make sure that we only apply trans when these parameters are not zero // Otherwise images are not rendered beyond 180 degrees FOV if (im->cP.trans_x != 0.0 || im->cP.trans_y != 0.0 || im->cP.trans_z != 0.0) { im->cP.trans = TRUE; } break; case 'p': // Translation remap plane li++; switch (*li) { case 'y': li = panoParseVariable(buf, li, lineNum, &(allopt->transYawOpt), &(im->cP.trans_yaw)); break; case 'p': li = panoParseVariable(buf, li, lineNum, &(allopt->transPitchOpt), &(im->cP.trans_pitch)); break; default: PrintError("Unknown translation parameter Tp%c in script: Line %d", *li, lineNum); goto fail; } if (li == NULL) goto fail; break; case 'e': // test parameters li++; switch (*li) { case '0': li = panoParseVariable(buf, li, lineNum, &(allopt->testP0opt), &(im->cP.test_p0)); break; case '1': li = panoParseVariable(buf, li, lineNum, &(allopt->testP1opt), &(im->cP.test_p1)); break; case '2': li = panoParseVariable(buf, li, lineNum, &(allopt->testP2opt), &(im->cP.test_p2)); break; case '3': li = panoParseVariable(buf, li, lineNum, &(allopt->testP3opt), &(im->cP.test_p3)); break; default: PrintError("Unknown Test parameter Te%c in script: Line %d", *li, lineNum); goto fail; } if (li == NULL) goto fail; im->cP.test = TRUE; break; default: PrintError("Unkonwn parameter T%c in script: Line %d", *li, lineNum); goto fail; } break; #ifdef CAN_READ_HUGIN_FILES case 'R': // EMoR photometric model parameters li++; switch (*li) { case 'a': li = panoParseVariable(buf, li, lineNum, &(allopt->Ra), &(im->Ra)); break; case 'b': li = panoParseVariable(buf, li, lineNum, &(allopt->Rb), &(im->Rb)); break; case 'c': li = panoParseVariable(buf, li, lineNum, &(allopt->Rc), &(im->Rc)); break; case 'd': li = panoParseVariable(buf, li, lineNum, &(allopt->Rd), &(im->Rd)); break; case 'e': li = panoParseVariable(buf, li, lineNum, &(allopt->Re), &(im->Re)); break; default: PrintError("Unkonwn parameter R%c in script: Line %d", *li, lineNum); goto fail; } break; case 'E': li++; switch (*li) { case 'e': if (*(++li) != 'v') { PrintError("Unkonwn parameter Ee%c in script: Line %d", *li, lineNum); goto fail; } READ_VAR("%lf", &(im->Eev)); break; case 'r': READ_VAR("%lf", &(im->Er)); break; case 'b': READ_VAR("%lf", &(im->Eb)); break; default: PrintError("Unkonwn parameter R%c in script: Line %d", *li, lineNum); goto fail; } break; case 'j': READ_VAR("%d", &im->jStackNr); break; #endif // CAN_READ_HUGIN_FILES case 'n': // Set filename nextWordBuf(&li); StrcpyN(im->name, buf, MAX_PATH_LENGTH); break; case 'm': // Frame li++; switch (*li) { case 'x': READ_VAR("%d", &(im->cP.fwidth)); im->cP.cutFrame = TRUE; break; case 'y': READ_VAR("%d", &(im->cP.fheight)); im->cP.cutFrame = TRUE; break; default: li--; READ_VAR("%d", &(im->cP.frame)); im->cP.cutFrame = TRUE; break; } break; case 'X': READ_VAR("%lf", &ci->x[0]); break; case 'Y': READ_VAR("%lf", &ci->x[1]); break; case 'Z': READ_VAR("%lf", &ci->x[2]); break; case 'S': nextWordBuf(&li); sscanf(buf, "%d,%d,%d,%d", &im->selection.left, &im->selection.right, &im->selection.top, &im->selection.bottom); break; case 'C': nextWordBuf(&li); sscanf(buf, "%d,%d,%d,%d", &im->selection.left, &im->selection.right, &im->selection.top, &im->selection.bottom); im->cP.cutFrame = TRUE; break; case 'K': // Ignore K variables in i nextWordBuf(&li); break; #ifdef CAN_READ_HUGIN_FILES case 'V': li++; switch (*li) { case 'm': READ_VAR("%d", &(im->Vm)); break; case 'a': li = panoParseVariable(buf, li, lineNum, &(allopt->Va), &(im->Va)); break; case 'b': li = panoParseVariable(buf, li, lineNum, &(allopt->Vb), &(im->Vb)); break; case 'c': li = panoParseVariable(buf, li, lineNum, &(allopt->Vc), &(im->Vc)); break; case 'd': li = panoParseVariable(buf, li, lineNum, &(allopt->Vd), &(im->Vd)); break; case 'x': li = panoParseVariable(buf, li, lineNum, &(allopt->Vx), &(im->Vx)); break; case 'y': li = panoParseVariable(buf, li, lineNum, &(allopt->Vy), &(im->Vy)); break; case 'f': nextWordBuf(&li); StrcpyN(im->Vfilename, buf, MAX_PATH_LENGTH); break; default: PrintError("Unkonwn parameter V%c in script: Line %d", *li, lineNum); goto fail; } break; #endif // CAN_READ_HUGIN_FILES default: li++; break; } } numIm++; #ifdef CAN_READ_HUGIN_FILES LastHuginImgInfoLine[0] = 0; LastHuginImgInfoLine[HuginImgInfoLineSize] = 0; #endif // CAN_READ_HUGIN_FILES break; case 't': // Triangle li = &(line[1]); i = 0; while (*li != 0) { switch (*li) { case ' ': case '\t': li++; break; case 'i': READ_VAR("%d", &(gl->t[nt].nIm)); break; default: if (i < 3) { li--; READ_VAR("%d", &(gl->t[nt].vert[i])); i++; } else li++; break; } } nt++; break; case 'c': // Control Points gl->cpt[numPts].type = 0; // default : optimize r gl->cpt[numPts].stddev = -1; // default : no stddev gl->cpt[numPts].weight = -1; // default : no weight if (ReadControlPoint(&(gl->cpt[numPts]), &(line[1])) != 0) { PrintError("Syntax error in script in control point 'c': Line %d", lineNum); goto fail; } numPts++; break; case 'm': // Mode description if (ReadModeDescription(&gl->sP, &(line[1])) != 0) { PrintError("Syntax error in script in mode description 'm': line %d", lineNum); goto fail; } break; case 'v': // Variables to optimize li = &(line[1]); stddev = -1; weight = -1; pstddev = 0; pweight = 0; multiple_optvars_in_line = 0; minval_defined = maxval_defined = 0; minval = maxval = 0; pminval = pmaxval = 0; inactive = 0; while (*li != 0) { switch (*li) { case '-': inactive = 1; li++; continue; case 's': if (stddev >= 0) { PrintError("Error in script: Line %d\nparameter 's' (standard deviation) already defined in this line.", lineNum); goto fail; } READ_VAR("%lf", &stddev); if (stddev < 0) { PrintError("Warning in script: Line %d\nignoring negative 's' parameter (standard deviation).\n", lineNum); stddev = -1; } break; case 'w': if (weight >= 0) { PrintError("Error in script: Line %d\nparameter 'w' (weight) already defined in this line.", lineNum); goto fail; } READ_VAR("%lf", &weight); if (weight < 0) { PrintError("Warning in script: Line %d\nignoring negative 'w' parameter (weight).\n", lineNum); weight = -1; } break; case 'm': if (('i' != li[1] || 'n' != li[2]) && ('a' != li[1] || 'x' != li[2])) { if (0 == li[1]) PrintError("Error in script: Line %d\nUnknown option m", lineNum); else if (0 == li[2]) PrintError("Error in script: Line %d\nUnknown option m%c", lineNum, li[1]); else PrintError("Error in script: Line %d\nUnknown option m%c%c", lineNum, li[1], li[2]); goto fail; } if ('i' == *(++li)) { ++li; READ_VAR("%lf", &minval); minval_defined = 1; } else // 'a' == *li { ++li; READ_VAR("%lf", &maxval); maxval_defined = 1; } break; case 'y': READ_OPT_VAR(yaw); break; case 'p': READ_OPT_VAR(pitch); break; case 'r': READ_OPT_VAR(roll); break; case 'v': READ_OPT_VAR(hfov); break; case 'a': READ_OPT_VAR(a); break; case 'b': READ_OPT_VAR(b); break; case 'c': READ_OPT_VAR(c); break; case 'd': READ_OPT_VAR(d); break; case 'e': READ_OPT_VAR(e); break; case 'g': READ_OPT_VAR(shear_x); break; case 't': READ_OPT_VAR(shear_y); break; case 'T': li++; switch (*li) { case 'i': li++; switch (*li) { case 'X': READ_OPT_VAR(tiltXopt); break; case 'Y': READ_OPT_VAR(tiltYopt); break; case 'Z': READ_OPT_VAR(tiltZopt); break; case 'S': READ_OPT_VAR(tiltScaleOpt); break; default: PrintError("Unknown variable name variable to optimize Ti%c in script: Line %d", *li, lineNum); goto fail; } break; case 'r': li++; switch (*li) { case 'X': READ_OPT_VAR(transXopt); break; case 'Y': READ_OPT_VAR(transYopt); break; case 'Z': READ_OPT_VAR(transZopt); break; default: PrintError("Unknown variable name to optimize Tr%c in script: Line %d", *li, lineNum); goto fail; } break; case 'p': li++; switch (*li) { case 'y': READ_OPT_VAR(transYawOpt); break; case 'p': READ_OPT_VAR(transPitchOpt); break; default: PrintError("Unknown variable name to optimize Tp%c in script: Line %d", *li, lineNum); goto fail; } break; case 'e': li++; switch (*li) { case '0': READ_OPT_VAR(testP0opt); break; case '1': READ_OPT_VAR(testP1opt); break; case '2': READ_OPT_VAR(testP2opt); break; case '3': READ_OPT_VAR(testP3opt); break; default: PrintError("Unknown variable name to optimize Te%c in script: Line %d", *li, lineNum); goto fail; } break; default: PrintError("Unknown variable name to optimize T%c in script: Line %d", *li, lineNum); goto fail; } break; #ifdef CAN_READ_HUGIN_FILES case 'V': li++; switch (*li) { case 'a': READ_OPT_VAR(Va); break; case 'b': READ_OPT_VAR(Vb); break; case 'c': READ_OPT_VAR(Vc); break; case 'd': READ_OPT_VAR(Vd); break; case 'x': READ_OPT_VAR(Vx); break; case 'y': READ_OPT_VAR(Vy); break; default: PrintError("Unknown variable name to optimize V%c in script: Line %d", *li, lineNum); goto fail; } break; case 'R': li++; switch (*li) { case 'a': READ_OPT_VAR(Ra); break; case 'b': READ_OPT_VAR(Rb); break; case 'c': READ_OPT_VAR(Rc); break; case 'd': READ_OPT_VAR(Rd); break; case 'e': READ_OPT_VAR(Re); break; default: PrintError("Unknown variable name to optimize R%c in script: Line %d", *li, lineNum); goto fail; } break; case 'E': li++; switch (*li) { case 'e': if (*(++li) != 'v') { PrintError("Unknown variable name to optimize Re%c in script: Line %d", *li, lineNum); goto fail; } READ_OPT_VAR(Eev); break; case 'r': READ_OPT_VAR(Er); break; case 'b': READ_OPT_VAR(Eb); break; default: PrintError("Unknown variable name to optimize E%c in script: Line %d", *li, lineNum); goto fail; } break; #endif // CAN_READ_HUGIN_FILES case 'X': READ_VAR("%d", &k); if (k >= 0 && k < gl->numIm) gl->cim[k].set[0] = FALSE; break; case 'Y': READ_VAR("%d", &k); if (k >= 0 && k < gl->numIm) gl->cim[k].set[1] = FALSE; break; case 'Z': READ_VAR("%d", &k); if (k >= 0 && k < gl->numIm) gl->cim[k].set[2] = FALSE; break; default: if (inactive) { PrintError("Minus (-) character without valid variable name to optimize in script: Line %d", lineNum); goto fail; } if (!isspace(*li)) { PrintError("Unknown variable name to optimize %c in script: Line %d", *li, lineNum); goto fail; } li++; break; } inactive = 0; } if (pweight) *pweight = -1; if (pstddev) *pstddev = -1; if (pminval) *pminval = -DBL_MAX; if (pmaxval) *pmaxval = DBL_MAX; if (multiple_optvars_in_line && (weight >= 0 || stddev >= 0 || minval_defined || maxval_defined)) { PrintError("Error in script: Line %d\nIf 's', 'w', 'min' or 'max' parameters are defined, only one optimization variable per v line is allowed.", lineNum); goto fail; } if (0 == weight && 0 == stddev) { PrintError("Error in script: Line %d\nIf both 's' and 'w' parameters are defined, at least one of them must be nonzero.", lineNum); goto fail; } if (weight >= 0) { if (0 == pweight) { PrintError("Error in script line %d: 'w' parameter (weight) is given without optimization variable name", lineNum); goto fail; } *pweight = weight; } if (stddev >= 0) { if (0 == pstddev) { PrintError("Error in script line %d: 's' parameter (standard deviation) is given without optimization variable name", lineNum); goto fail; } *pstddev = stddev; } if (minval_defined) { if (0 == pminval) { PrintError("Error in script line %d: 'min' parameter is given without optimization variable name", lineNum); goto fail; } else if (maxval_defined && maxval < minval) { PrintError("Error in script line %d: 'max' bound is smaller than 'min' bound", lineNum); goto fail; } *pminval = minval; } if (maxval_defined) { if (0 == pmaxval) { PrintError("Error in script line %d: 'max' parameter is given without optimization variable name", lineNum); goto fail; } *pmaxval = maxval; } break; case 'p': // panorama gl->pano.format = 2; // _equirectangular by default gl->pano.hfov = 360.0; #ifdef CAN_READ_HUGIN_FILES if (ReadPanoramaDescription(&(gl->pano), &(gl->panoinfo), &(gl->st), &(line[1])) != 0) { PrintError("Syntax error in panorama description p line: %d (%s)", lineNum, line); goto fail; } #else if (ReadPanoramaDescription(&(gl->pano), &(gl->st), &(line[1])) != 0) { PrintError("Syntax error in panorama description p line: %d (%s)", lineNum, line); goto fail; } #endif switch (gl->pano.format) { case PANO_FORMAT_RECTILINEAR: gl->pano.format = _rectilinear; break; case PANO_FORMAT_PANORAMA: gl->pano.format = _panorama; break; case PANO_FORMAT_EQUIRECTANGULAR: gl->pano.format = _equirectangular; break; case PANO_FORMAT_FISHEYE_FF: gl->pano.format = _fisheye_ff; break; case PANO_FORMAT_STEREOGRAPHIC: gl->pano.format = _stereographic; break; case PANO_FORMAT_MERCATOR: gl->pano.format = _mercator; break; case PANO_FORMAT_TRANS_MERCATOR: gl->pano.format = _trans_mercator; break; case PANO_FORMAT_SINUSOIDAL: gl->pano.format = _sinusoidal; break; case PANO_FORMAT_LAMBERT_EQUAL_AREA_CONIC: gl->pano.format = _lambert; break; case PANO_FORMAT_LAMBERT_AZIMUTHAL: gl->pano.format = _lambertazimuthal; break; case PANO_FORMAT_HAMMER: gl->pano.format = _hammer; break; case PANO_FORMAT_ALBERS_EQUAL_AREA_CONIC: gl->pano.format = _albersequalareaconic; break; case PANO_FORMAT_MILLER_CYLINDRICAL: gl->pano.format = _millercylindrical; break; case PANO_FORMAT_PANINI: gl->pano.format = _panini; break; case PANO_FORMAT_EQUI_PANINI: gl->pano.format = _equipanini; break; case PANO_FORMAT_PANINI_GENERAL: gl->pano.format = _panini_general; break; case PANO_FORMAT_ARCHITECTURAL: gl->pano.format = _architectural; break; case PANO_FORMAT_ORTHOGRAPHIC: gl->pano.format = _orthographic; break; case PANO_FORMAT_THOBY: gl->pano.format = _thoby; break; case PANO_FORMAT_EQUISOLID: gl->pano.format = _equisolid; break; case PANO_FORMAT_BIPLANE: gl->pano.format = _biplane; break; case PANO_FORMAT_TRIPLANE: gl->pano.format = _triplane; break; default: PrintError("Unknown panorama projection: %d", gl->pano.format); goto fail; } if ((gl->pano.format == _rectilinear || gl->pano.format == _trans_mercator) && gl->pano.hfov >= 180.0) { PrintError("Destination image must have HFOV < 180"); goto fail; } break; // Rik's mask-from-focus hacking case 'z': // I was tempted to remove this code, but I am not sure how it will affect PToptimizer, until then.. it will remain //PrintError( "z option is no longer supported by PTmender and it is ignored. Use PTmasker instead\n" ); //ZCombSetEnabled(); li = &(line[1]); while (*li != 0) { switch (*li) { case 'm': { int mtype; READ_VAR("%d", &mtype); //ZCombSetMaskType(mtype); } break; case 'f': { int fwHalfwidth; READ_VAR("%d", &fwHalfwidth); //ZCombSetFocusWindowHalfwidth(fwHalfwidth); } break; case 's': { int swHalfwidth; READ_VAR("%d", &swHalfwidth); //ZCombSetSmoothingWindowHalfwidth(swHalfwidth); } break; default: li++; break; } } break; // end Rik's mask-from-focus hacking #ifdef CAN_READ_HUGIN_FILES case 'k': immask = &gl->huginmasks[numhuginmasks++]; immask->image_nr = 0; immask->type = 0; immask->coords = 0; immask->numcoords = 0; li = &(line[1]); while (*li != 0) { switch (*li) { case 'i': { READ_VAR("%d", &immask->image_nr); break; } case 't': { READ_VAR("%d", &immask->type); break; } case 'p': { if (immask->numcoords > 0) { PrintError("Option p already used. Line = ", lineNum); return -1; } nextWordBuf(&li); k = NrTokensSeparatedBy(buf, " ,"); if (0 != (k % 2)) { PrintError("Number of coordinates in mask polygon must be even (x,y per point)."); return -1; } if (k >= 2 && NULL != (immask->coords = (double*)malloc(k * sizeof(double)))) { immask->numcoords = k; for (i = 0, b = Strtok(buf, " ,"); i < k && b != NULL; i++, b = Strtok(NULL, " ,")) { if (sscanf(b, "%lf", &immask->coords[i]) != 1) { PrintError("Illegal value in S parameter %s", b); return -1; } } } break; } default: li++; break; } } break; #endif // CAN_READ_HUGIN_FILES case '*': // End of script-data *lineStart = 0; *ch = 0; break; default: break; } } // Set up Panorama description if (gl->pano.width == 0 && gl->im[0].hfov != 0.0) // Set default for panorama width based on first image { gl->pano.width = (uint32_t)((gl->pano.hfov / gl->im[0].hfov) * gl->im[0].width); gl->pano.width /= 10; gl->pano.width *= 10; // Round to multiple of 10 } if (gl->pano.height == 0) gl->pano.height = gl->pano.width / 2; for (k = 0; k < 2; k++) { if (k) { gl->var_constraint_indices = (int*)malloc(sizeof(int) * nr_var_constraints); gl->initial_cned_parameters = (double*)malloc(sizeof(double) * nr_var_constraints); gl->cned_parameters_weights = (double*)malloc(sizeof(double) * nr_var_constraints); gl->min_cned_parameters = (double*)malloc(sizeof(double) * nr_var_constraints); gl->max_cned_parameters = (double*)malloc(sizeof(double) * nr_var_constraints); } n = 0; nr_var_constraints = 0; for (i = 0; i < gl->numIm; i++) { PROCESS_ALLOPT_ASSIGN_OPT(yaw, yaw, y); PROCESS_ALLOPT_ASSIGN_OPT(pitch, pitch, p); PROCESS_ALLOPT_ASSIGN_OPT(roll, roll, r); PROCESS_ALLOPT_ASSIGN_OPT(hfov, hfov, v); PROCESS_ALLOPT_ASSIGN_OPT(a, cP.radial_params[0][3], a); PROCESS_ALLOPT_ASSIGN_OPT(b, cP.radial_params[0][2], b); PROCESS_ALLOPT_ASSIGN_OPT(c, cP.radial_params[0][1], c); PROCESS_ALLOPT_ASSIGN_OPT(d, cP.horizontal_params[0], d); PROCESS_ALLOPT_ASSIGN_OPT(e, cP.vertical_params[0], e); PROCESS_ALLOPT_ASSIGN_OPT(tiltXopt, cP.tilt_x, TiX); PROCESS_ALLOPT_ASSIGN_OPT(tiltYopt, cP.tilt_y, TiY); PROCESS_ALLOPT_ASSIGN_OPT(tiltZopt, cP.tilt_z, TiZ); PROCESS_ALLOPT_ASSIGN_OPT(tiltScaleOpt, cP.tilt_scale, TiS); PROCESS_ALLOPT_ASSIGN_OPT(transXopt, cP.trans_x, TrX); PROCESS_ALLOPT_ASSIGN_OPT(transYopt, cP.trans_y, TrY); PROCESS_ALLOPT_ASSIGN_OPT(transZopt, cP.trans_z, TrZ); PROCESS_ALLOPT_ASSIGN_OPT(transYawOpt, cP.trans_yaw, Tpy); PROCESS_ALLOPT_ASSIGN_OPT(transPitchOpt, cP.trans_pitch, Tpp); PROCESS_ALLOPT_ASSIGN_OPT(testP0opt, cP.test_p0, Te0); PROCESS_ALLOPT_ASSIGN_OPT(testP1opt, cP.test_p1, Te1); PROCESS_ALLOPT_ASSIGN_OPT(testP2opt, cP.test_p2, Te2); PROCESS_ALLOPT_ASSIGN_OPT(testP3opt, cP.test_p3, Te3); PROCESS_ALLOPT_ASSIGN_OPT(shear_x, cP.shear_x, g); PROCESS_ALLOPT_ASSIGN_OPT(shear_y, cP.shear_y, t); } } // Set up global information structure gl->numParam = n; gl->nr_var_constraints = nr_var_constraints; gl->data = NULL; // Set initial values for linked variables for (i = 0; i < gl->numIm; i++) { k = gl->opt[i].yaw - 2; if (k >= 0) gl->im[i].yaw = gl->im[k].yaw; k = gl->opt[i].pitch - 2; if (k >= 0) gl->im[i].pitch = gl->im[k].pitch; k = gl->opt[i].roll - 2; if (k >= 0) gl->im[i].roll = gl->im[k].roll; k = gl->opt[i].hfov - 2; if (k >= 0) gl->im[i].hfov = gl->im[k].hfov; k = gl->opt[i].a - 2; if (k >= 0) gl->im[i].cP.radial_params[0][3] = gl->im[k].cP.radial_params[0][3]; k = gl->opt[i].b - 2; if (k >= 0) gl->im[i].cP.radial_params[0][2] = gl->im[k].cP.radial_params[0][2]; k = gl->opt[i].c - 2; if (k >= 0) gl->im[i].cP.radial_params[0][1] = gl->im[k].cP.radial_params[0][1]; k = gl->opt[i].d - 2; if (k >= 0) gl->im[i].cP.horizontal_params[0] = gl->im[k].cP.horizontal_params[0]; k = gl->opt[i].e - 2; if (k >= 0) gl->im[i].cP.vertical_params[0] = gl->im[k].cP.vertical_params[0]; k = gl->opt[i].shear_x - 2; if (k >= 0) gl->im[i].cP.shear_x = gl->im[k].cP.shear_x; k = gl->opt[i].shear_y - 2; if (k >= 0) gl->im[i].cP.shear_y = gl->im[k].cP.shear_y; // tilt variables---------------------------------------------------------------- k = gl->opt[i].tiltXopt - 2; if (k >= 0) gl->im[i].cP.tilt_x = gl->im[k].cP.tilt_x; k = gl->opt[i].tiltYopt - 2; if (k >= 0) gl->im[i].cP.tilt_y = gl->im[k].cP.tilt_y; k = gl->opt[i].tiltZopt - 2; if (k >= 0) gl->im[i].cP.tilt_z = gl->im[k].cP.tilt_z; k = gl->opt[i].tiltScaleOpt - 2; if (k >= 0) gl->im[i].cP.tilt_scale = gl->im[k].cP.tilt_scale; // translation variables---------------------------------------------------------------- k = gl->opt[i].transXopt - 2; if (k >= 0) gl->im[i].cP.trans_x = gl->im[k].cP.trans_x; k = gl->opt[i].transYopt - 2; if (k >= 0) gl->im[i].cP.trans_y = gl->im[k].cP.trans_y; k = gl->opt[i].transZopt - 2; if (k >= 0) gl->im[i].cP.trans_z = gl->im[k].cP.trans_z; k = gl->opt[i].transYawOpt - 2; if (k >= 0) gl->im[i].cP.trans_yaw = gl->im[k].cP.trans_yaw; k = gl->opt[i].transPitchOpt - 2; if (k >= 0) gl->im[i].cP.trans_pitch = gl->im[k].cP.trans_pitch; // test variables ---------------------------------------------------------------------- k = gl->opt[i].testP0opt - 2; if (k >= 0) gl->im[i].cP.test_p0 = gl->im[k].cP.test_p0; k = gl->opt[i].testP1opt - 2; if (k >= 0) gl->im[i].cP.test_p1 = gl->im[k].cP.test_p1; k = gl->opt[i].testP2opt - 2; if (k >= 0) gl->im[i].cP.test_p2 = gl->im[k].cP.test_p2; k = gl->opt[i].testP3opt - 2; if (k >= 0) gl->im[i].cP.test_p3 = gl->im[k].cP.test_p3; //---------------------------------------------------------------------- gl->im[i].cP.radial_params[0][0] = 1.0 - (gl->im[i].cP.radial_params[0][3] + gl->im[i].cP.radial_params[0][2] + gl->im[i].cP.radial_params[0][1]); SetEquColor(&(gl->im[i].cP)); } panoLocaleRestore; return 0; fail: panoLocaleRestore; return -1; } char* LineMemoryCurrentPosition = 0; char* LineMemoryFirstInvalidPosition = 0; int AppendFmtAdvancePtr(const char* format, ...) { int nr_written; va_list args; if (LineMemoryCurrentPosition >= LineMemoryFirstInvalidPosition) { return -1; } va_start(args, format); nr_written = vsnprintf(LineMemoryCurrentPosition, (size_t)(LineMemoryFirstInvalidPosition - LineMemoryCurrentPosition), format, args); va_end(args); if (nr_written < 0 || nr_written >= (size_t)(LineMemoryFirstInvalidPosition - LineMemoryCurrentPosition)) { return -1; } else { LineMemoryCurrentPosition += nr_written; return 0; } } char* LoadScript(fullPath* scriptFile) { fullPath sfile; int i; file_spec fnum; size_t count; char* script = NULL, ch; memset(&sfile, 0, sizeof(fullPath)); if (memcmp(scriptFile, &sfile, sizeof(fullPath)) == 0) { PrintError("No Scriptfile selected"); goto _loadError; } if (myopen(scriptFile, read_text, fnum)) { PrintError("Error Opening Scriptfile: %s", scriptFile->name); goto _loadError; } count = 1; i = 0; // Get file length while (count == 1) { myread(fnum, count, &ch); if (count == 1) i++; } myclose(fnum); count = i; script = (char*)malloc(count + 1); if (script == NULL) { PrintError("Not enough memory to load scriptfile"); goto _loadError; } if (myopen(scriptFile, read_text, fnum)) { PrintError("Error Opening Scriptfile: %s", scriptFile->name); free(script); goto _loadError; } myread(fnum, count, script); script[count] = 0; myclose(fnum); return script; _loadError: return (char*)NULL; } int WriteScript(char* res, fullPath* scriptFile, int launch) { fullPath sfile; file_spec fnum; size_t count; memset(&sfile, 0, sizeof(fullPath)); if (memcmp(scriptFile, &sfile, sizeof(fullPath)) == 0) { PrintError("No Scriptfile selected"); goto _writeError; } memcpy(&sfile, scriptFile, sizeof(fullPath)); mydelete(&sfile); mycreate(&sfile, 'ttxt', 'TEXT'); if (myopen(&sfile, write_text, fnum)) { PrintError("Error Opening Scriptfile"); goto _writeError; } count = strlen(res); mywrite(fnum, count, res); myclose(fnum); if (launch == 1) { //showScript(&sfile); } return 0; _writeError: return -1; } void** mymalloc(size_t numBytes) // Memory allocation, use Handles { char** mem; mem = (char**)malloc(sizeof(char*)); // Allocate memory for pointer if (mem == NULL) return (void**)NULL; else { (*mem) = (char*)malloc(numBytes); // Allocate numBytes if (*mem == NULL) { free(mem); return (void**)NULL; } else return (void**)mem; } } void myfree(void** Hdl) // free Memory, use Handles { free((char*)*Hdl); free((char**)Hdl); } static double fcnPanoHuberSigma = 0; // sigma for Huber M-estimator. 0 disables M-estimator void setFcnPanoHuberSigma(double sigma) { fcnPanoHuberSigma = sigma; } double getFcnPanoHuberSigma() { return fcnPanoHuberSigma; } #define CHECK_MEM_ERROR(AppendFmtAdvancePtr_Call) do { if(AppendFmtAdvancePtr_Call) { PrintError("Internal error (insufficient memory for storing file)."); goto fail; } } while(0) #ifdef CAN_READ_HUGIN_FILES void WriteHuginPtoFile(char* script, fullPath* sfile, AlignInfo* g) { char* res, ** hres; int format; int i, k, memsize; Image* p = &(g->pano); PanoImageInfo* pi = &(g->panoinfo); Image* im; optVars* allopt; CoordInfo* ci; controlPoint* cpt; HuginImageMask* immask; panoLocaleSave; memsize = (int)strlen(script) + ((unsigned long long)g->numIm) * 600 + ((unsigned long long)g->numPts) * 200 + 10000; hres = (char**)mymalloc(memsize); // Do we ever need more? if (hres == NULL) { PrintError("Not enough memory to create result file"); goto fail; } LineMemoryCurrentPosition = res = *hres; LineMemoryFirstInvalidPosition = LineMemoryCurrentPosition + memsize; CHECK_MEM_ERROR(AppendFmtAdvancePtr("# hugin project file written by PTOptimizer\n#hugin_ptoversion 2\n")); CHECK_MEM_ERROR(AppendFmtAdvancePtr("p f%d w%u h%u v%.15g ", pi->pto_format, p->width, p->height, p->hfov)); if (pi->k >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("k%d ", pi->k)); if (pi->d >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("d%d ", pi->d)); if (pi->b >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("b%d ", pi->b)); CHECK_MEM_ERROR(AppendFmtAdvancePtr("E%.15g R%d ", pi->EParam, pi->RParam)); if (strlen(pi->TParam) > 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("T%s ", pi->TParam)); if (pi->SelLeft < pi->SelRight && pi->SelTop < pi->SelBottom) CHECK_MEM_ERROR(AppendFmtAdvancePtr("S%d,%d,%d,%d ", pi->SelLeft, pi->SelRight, pi->SelTop, pi->SelBottom)); if (p->formatParamCount > 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" P\"")); for (i = 0; i < p->formatParamCount; i++) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("%15g,", p->formatParam[i])); if (i + 1 < p->formatParamCount) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" ")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\" ")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("n\"%s\"\n", p->name)); CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%s i%d%s%s%s\n\n", WriteDoubleIfNotDefault(" g", g->sP.gamma, 1.0), g->sP.interpolator, WriteIntegerIfNotDefault(" f", g->sP.fastStep, 0), WriteDoubleIfNotDefault(" m", getFcnPanoHuberSigma(), 0), WriteIntegerIfNotDefault(" p", g->sP.optCreatePano, 1))); CHECK_MEM_ERROR(AppendFmtAdvancePtr("# image lines\n")); for (i = 0; i < g->numIm; i++) { im = &(g->im[i]); // This image is being set allopt = &(g->allopt[i]); ci = &(g->cim[i]); if (0 != im->HuginImgInfoLine[0]) CHECK_MEM_ERROR(AppendFmtAdvancePtr("%s\n", im->HuginImgInfoLine)); switch (im->format) { case _rectilinear: format = IMAGE_FORMAT_RECTILINEAR; break; case _panorama: format = IMAGE_FORMAT_PANORAMA; break; case _fisheye_circ: format = IMAGE_FORMAT_FISHEYE_EQUIDISTANCECIRC; break; case _fisheye_ff: format = IMAGE_FORMAT_FISHEYE_EQUIDISTANCEFF; break; case _equirectangular: format = IMAGE_FORMAT_EQUIRECTANGULAR; break; case _mirror: format = IMAGE_FORMAT_MIRROR; break; case _orthographic: format = IMAGE_FORMAT_FISHEYE_ORTHOGRAPHIC; break; case _stereographic: format = IMAGE_FORMAT_FISHEYE_STEREOGRAPHIC; break; case _equisolid: format = IMAGE_FORMAT_FISHEYE_EQUISOLID; break; case _thoby: format = IMAGE_FORMAT_FISHEYE_THOBY; break; default: format = -1; break; } CHECK_MEM_ERROR(AppendFmtAdvancePtr("i w%u h%u f%d v%s ", im->width, im->height, format, WriteVarOrEqImgNr(allopt->hfov, im->hfov))); CHECK_MEM_ERROR(AppendFmtAdvancePtr("Ra%s Rb%s Rc%s Rd%s Re%s Eev%.15g Er%.15g Eb%.15g ", WriteVarOrEqImgNr(allopt->Ra, im->Ra), WriteVarOrEqImgNr(allopt->Rb, im->Rb), WriteVarOrEqImgNr(allopt->Rc, im->Rc), WriteVarOrEqImgNr(allopt->Rd, im->Rd), WriteVarOrEqImgNr(allopt->Re, im->Re), im->Eev, im->Er, im->Eb)); CHECK_MEM_ERROR(AppendFmtAdvancePtr("r%.15g p%.15g y%.15g ", im->roll, im->pitch, im->yaw)); if (im->cP.tilt) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("TiX%s TiY%s TiZ%s TiS%s ", WriteVarOrEqImgNr(allopt->tiltXopt, im->cP.tilt_x), WriteVarOrEqImgNr(allopt->tiltYopt, im->cP.tilt_y), WriteVarOrEqImgNr(allopt->tiltZopt, im->cP.tilt_z), WriteVarOrEqImgNr(allopt->tiltScaleOpt, im->cP.tilt_scale))); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("TrX%s TrY%s TrZ%s Tpy%s Tpp%s ", WriteVarOrEqImgNr(allopt->transXopt, im->cP.trans_x), WriteVarOrEqImgNr(allopt->transYopt, im->cP.trans_y), WriteVarOrEqImgNr(allopt->transZopt, im->cP.trans_z), WriteVarOrEqImgNr(allopt->transYawOpt, im->cP.trans_yaw), WriteVarOrEqImgNr(allopt->transPitchOpt, im->cP.trans_pitch))); if (im->cP.test) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("Te0%.15g Te1%.15g Te2%.15g Te3%.15g ", im->cP.test_p0, im->cP.test_p1, im->cP.test_p2, im->cP.test_p3)); } if (im->cP.cutFrame && !(im->selection.bottom != 0 || im->selection.right != 0)) // im->format != _fisheye_circ && im->cP.cutFrame ) { if (im->cP.frame != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%d ", im->cP.frame)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("mx%d my%d ", im->cP.fwidth, im->cP.fheight)); } } CHECK_MEM_ERROR(AppendFmtAdvancePtr("j%d ", im->jStackNr)); if (im->cP.radial) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("a%s b%s c%s ", WriteVarOrEqImgNr(allopt->a, im->cP.radial_params[0][3]), WriteVarOrEqImgNr(allopt->b, im->cP.radial_params[0][2]), WriteVarOrEqImgNr(allopt->c, im->cP.radial_params[0][1]))); } if (im->cP.horizontal) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("d%s ", WriteVarOrEqImgNr(allopt->d, im->cP.horizontal_params[0]))); } if (im->cP.vertical) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("e%s ", WriteVarOrEqImgNr(allopt->e, im->cP.vertical_params[0]))); } if (im->cP.shear) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("g%s t%s ", WriteVarOrEqImgNr(allopt->shear_x, im->cP.shear_x), WriteVarOrEqImgNr(allopt->shear_y, im->cP.shear_y))); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("Va%s Vb%s Vc%s Vd%s Vx%s Vy%s ", WriteVarOrEqImgNr(allopt->Va, im->Va), WriteVarOrEqImgNr(allopt->Vb, im->Vb), WriteVarOrEqImgNr(allopt->Vc, im->Vc), WriteVarOrEqImgNr(allopt->Vd, im->Vd), WriteVarOrEqImgNr(allopt->Vx, im->Vx), WriteVarOrEqImgNr(allopt->Vy, im->Vy))); if (im->cP.cutFrame && !(im->selection.bottom != 0 || im->selection.right != 0)) // im->format != _fisheye_circ && im->cP.cutFrame ) { if (im->cP.frame != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%d ", im->cP.frame)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("mx%d my%d ", im->cP.fwidth, im->cP.fheight)); } } if (im->selection.bottom != 0 || im->selection.right != 0) { if (im->cP.cutFrame) { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" C%d,%d,%d,%d ", im->selection.left, im->selection.right, im->selection.top, im->selection.bottom)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" S%d,%d,%d,%d ", im->selection.left, im->selection.right, im->selection.top, im->selection.bottom)); } } CHECK_MEM_ERROR(AppendFmtAdvancePtr(" Vm%d ", im->Vm)); if (strlen(im->Vfilename) != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("Vf\"%s\" ", im->Vfilename)); } if (strlen(im->name) != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("n\"%s\"", im->name)); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n")); } // numIm CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n\n# specify variables that should be optimized\n")); for (i = 0; i < g->numIm; i++) { allopt = &g->allopt[i]; WRITE_OPT_VAR(hfov, v); WRITE_OPT_VAR(Ra, Ra); WRITE_OPT_VAR(Rb, Rb); WRITE_OPT_VAR(Rc, Rc); WRITE_OPT_VAR(Rd, Rd); WRITE_OPT_VAR(Re, Re); WRITE_OPT_VAR(Eev, Eev); WRITE_OPT_VAR(Er, Er); WRITE_OPT_VAR(Eb, Eb); WRITE_OPT_VAR(roll, r); WRITE_OPT_VAR(pitch, p); WRITE_OPT_VAR(yaw, y); WRITE_OPT_VAR(transXopt, TrX); WRITE_OPT_VAR(transYopt, TrY); WRITE_OPT_VAR(transZopt, TrZ); WRITE_OPT_VAR(transYawOpt, Tpy); WRITE_OPT_VAR(transPitchOpt, Tpp); WRITE_OPT_VAR(tiltXopt, TiX); WRITE_OPT_VAR(tiltYopt, TiY); WRITE_OPT_VAR(tiltZopt, TiZ); WRITE_OPT_VAR(tiltScaleOpt, TiS); WRITE_OPT_VAR(a, a); WRITE_OPT_VAR(b, b); WRITE_OPT_VAR(c, c); WRITE_OPT_VAR(d, d); WRITE_OPT_VAR(e, e); WRITE_OPT_VAR(shear_x, g); WRITE_OPT_VAR(shear_y, t); WRITE_OPT_VAR(Va, Va); WRITE_OPT_VAR(Vb, Vb); WRITE_OPT_VAR(Vc, Vc); WRITE_OPT_VAR(Vd, Vd); WRITE_OPT_VAR(Vx, Vx); WRITE_OPT_VAR(Vy, Vy); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("v\n")); CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n\n# control points\n")); for (i = 0; i < g->numPts; i++) { cpt = &g->cpt[i]; if (cpt->stddev >= 0) { if (cpt->weight >= 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d s%.15g w%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->stddev, cpt->weight)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d s%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->stddev)); } } else if (cpt->weight >= 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d w%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->weight)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type)); } } if (g->numhuginmasks > 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n# masks\n")); for (i = 0; i < g->numhuginmasks; i++) { immask = &g->huginmasks[i]; CHECK_MEM_ERROR(AppendFmtAdvancePtr("k i%d t%d", immask->image_nr, immask->type)); if (immask->numcoords > 0 && NULL != immask->coords) { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" p\"")); for (k = 0; k < immask->numcoords; k++) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("%.15g", immask->coords[k])); if (k + 1 < immask->numcoords) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" ")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\"")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n")); } } if (NULL != g->HuginOptions[0]) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n")); for (i = 0; NULL != g->HuginOptions[i]; i++) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("%s\n", g->HuginOptions[i])); } } if (WriteScript(res, sfile, 0) != 0) { PrintError("Could not write results to scriptfile"); } if (hres) myfree((void**)hres); panoLocaleRestore; return; fail: panoLocaleRestore; } #endif // CAN_READ_HUGIN_FILES void WritePTOptimizerFile(char* script, fullPath* sfile, AlignInfo* g) { char* res, ** hres; int format; int i, k, memsize; Image* p = &(g->pano); PanoImageInfo* pi = &(g->panoinfo); Image* im; optVars* allopt; CoordInfo* ci; controlPoint* cpt; HuginImageMask* immask; panoLocaleSave; memsize = (int)strlen(script) + ((unsigned long long)g->numIm) * 600 + ((unsigned long long)g->numPts) * 200 + 10000; hres = (char**)mymalloc(memsize); // Do we ever need more? if (hres == NULL) { PrintError("Not enough memory to create result file"); goto fail; } LineMemoryCurrentPosition = res = *hres; LineMemoryFirstInvalidPosition = LineMemoryCurrentPosition + memsize; CHECK_MEM_ERROR(AppendFmtAdvancePtr("# PTOptimizer project file written by PTOptimizer\n")); CHECK_MEM_ERROR(AppendFmtAdvancePtr("p f%d w%u h%u v%.15g ", pi->pto_format, p->width, p->height, p->hfov)); if (pi->k >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("k%d ", pi->k)); if (pi->d >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("d%d ", pi->d)); if (pi->b >= 0) CHECK_MEM_ERROR(AppendFmtAdvancePtr("b%d ", pi->b)); if (p->formatParamCount > 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" P\"")); for (i = 0; i < p->formatParamCount; i++) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("%15g,", p->formatParam[i])); if (i + 1 < p->formatParamCount) CHECK_MEM_ERROR(AppendFmtAdvancePtr(" ")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\" ")); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("n\"%s\"\n", p->name)); CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%s i%d%s%s%s\n\n", WriteDoubleIfNotDefault(" g", g->sP.gamma, 1.0), g->sP.interpolator, WriteIntegerIfNotDefault(" f", g->sP.fastStep, 0), WriteDoubleIfNotDefault(" m", getFcnPanoHuberSigma(), 0), WriteIntegerIfNotDefault(" p", g->sP.optCreatePano, 1))); CHECK_MEM_ERROR(AppendFmtAdvancePtr("# image lines\n")); for (i = 0; i < g->numIm; i++) { im = &(g->im[i]); // This image is being set allopt = &(g->allopt[i]); ci = &(g->cim[i]); if (0 != im->HuginImgInfoLine[0]) CHECK_MEM_ERROR(AppendFmtAdvancePtr("%s\n", im->HuginImgInfoLine)); switch (im->format) { case _rectilinear: format = IMAGE_FORMAT_RECTILINEAR; break; case _panorama: format = IMAGE_FORMAT_PANORAMA; break; case _fisheye_circ: format = IMAGE_FORMAT_FISHEYE_EQUIDISTANCECIRC; break; case _fisheye_ff: format = IMAGE_FORMAT_FISHEYE_EQUIDISTANCEFF; break; case _equirectangular: format = IMAGE_FORMAT_EQUIRECTANGULAR; break; case _mirror: format = IMAGE_FORMAT_MIRROR; break; case _orthographic: format = IMAGE_FORMAT_FISHEYE_ORTHOGRAPHIC; break; case _stereographic: format = IMAGE_FORMAT_FISHEYE_STEREOGRAPHIC; break; case _equisolid: format = IMAGE_FORMAT_FISHEYE_EQUISOLID; break; case _thoby: format = IMAGE_FORMAT_FISHEYE_THOBY; break; default: format = -1; break; } CHECK_MEM_ERROR(AppendFmtAdvancePtr("i w%u h%u f%d v%s ", im->width, im->height, format, WriteVarOrEqImgNr(allopt->hfov, im->hfov))); //CHECK_MEM_ERROR(AppendFmtAdvancePtr("Ra%s Rb%s Rc%s Rd%s Re%s Eev%.15g Er%.15g Eb%.15g ", WriteVarOrEqImgNr(allopt->Ra, im->Ra), WriteVarOrEqImgNr(allopt->Rb, im->Rb), WriteVarOrEqImgNr(allopt->Rc, im->Rc), // WriteVarOrEqImgNr(allopt->Rd, im->Rd), WriteVarOrEqImgNr(allopt->Re, im->Re), im->Eev, im->Er, im->Eb)); CHECK_MEM_ERROR(AppendFmtAdvancePtr("r%.15g p%.15g y%.15g ", im->roll, im->pitch, im->yaw)); if (im->cP.tilt) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("TiX%s TiY%s TiZ%s TiS%s ", WriteVarOrEqImgNr(allopt->tiltXopt, im->cP.tilt_x), WriteVarOrEqImgNr(allopt->tiltYopt, im->cP.tilt_y), WriteVarOrEqImgNr(allopt->tiltZopt, im->cP.tilt_z), WriteVarOrEqImgNr(allopt->tiltScaleOpt, im->cP.tilt_scale))); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("TrX%s TrY%s TrZ%s Tpy%s Tpp%s ", WriteVarOrEqImgNr(allopt->transXopt, im->cP.trans_x), WriteVarOrEqImgNr(allopt->transYopt, im->cP.trans_y), WriteVarOrEqImgNr(allopt->transZopt, im->cP.trans_z), WriteVarOrEqImgNr(allopt->transYawOpt, im->cP.trans_yaw), WriteVarOrEqImgNr(allopt->transPitchOpt, im->cP.trans_pitch))); if (im->cP.test) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("Te0%.15g Te1%.15g Te2%.15g Te3%.15g ", im->cP.test_p0, im->cP.test_p1, im->cP.test_p2, im->cP.test_p3)); } if (im->cP.cutFrame && !(im->selection.bottom != 0 || im->selection.right != 0)) // im->format != _fisheye_circ && im->cP.cutFrame ) { if (im->cP.frame != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%d ", im->cP.frame)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("mx%d my%d ", im->cP.fwidth, im->cP.fheight)); } } //CHECK_MEM_ERROR(AppendFmtAdvancePtr("j%d ", im->jStackNr)); if (im->cP.radial) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("a%s b%s c%s ", WriteVarOrEqImgNr(allopt->a, im->cP.radial_params[0][3]), WriteVarOrEqImgNr(allopt->b, im->cP.radial_params[0][2]), WriteVarOrEqImgNr(allopt->c, im->cP.radial_params[0][1]))); } if (im->cP.horizontal) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("d%s ", WriteVarOrEqImgNr(allopt->d, im->cP.horizontal_params[0]))); } if (im->cP.vertical) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("e%s ", WriteVarOrEqImgNr(allopt->e, im->cP.vertical_params[0]))); } if (im->cP.shear) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("g%s t%s ", WriteVarOrEqImgNr(allopt->shear_x, im->cP.shear_x), WriteVarOrEqImgNr(allopt->shear_y, im->cP.shear_y))); } if (im->cP.cutFrame && !(im->selection.bottom != 0 || im->selection.right != 0)) // im->format != _fisheye_circ && im->cP.cutFrame ) { if (im->cP.frame != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("m%d ", im->cP.frame)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("mx%d my%d ", im->cP.fwidth, im->cP.fheight)); } } if (im->selection.bottom != 0 || im->selection.right != 0) { if (im->cP.cutFrame) { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" C%d,%d,%d,%d ", im->selection.left, im->selection.right, im->selection.top, im->selection.bottom)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr(" S%d,%d,%d,%d ", im->selection.left, im->selection.right, im->selection.top, im->selection.bottom)); } } CHECK_MEM_ERROR(AppendFmtAdvancePtr(" Vm%d ", im->Vm)); if (strlen(im->Vfilename) != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("Vf\"%s\" ", im->Vfilename)); } if (strlen(im->name) != 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("n\"%s\"", im->name)); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n")); } // numIm CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n\n# specify variables that should be optimized\n")); for (i = 0; i < g->numIm; i++) { allopt = &g->allopt[i]; WRITE_OPT_VAR(hfov, v); WRITE_OPT_VAR(roll, r); WRITE_OPT_VAR(pitch, p); WRITE_OPT_VAR(yaw, y); WRITE_OPT_VAR(transXopt, TrX); WRITE_OPT_VAR(transYopt, TrY); WRITE_OPT_VAR(transZopt, TrZ); WRITE_OPT_VAR(transYawOpt, Tpy); WRITE_OPT_VAR(transPitchOpt, Tpp); WRITE_OPT_VAR(tiltXopt, TiX); WRITE_OPT_VAR(tiltYopt, TiY); WRITE_OPT_VAR(tiltZopt, TiZ); WRITE_OPT_VAR(tiltScaleOpt, TiS); WRITE_OPT_VAR(a, a); WRITE_OPT_VAR(b, b); WRITE_OPT_VAR(c, c); WRITE_OPT_VAR(d, d); WRITE_OPT_VAR(e, e); WRITE_OPT_VAR(shear_x, g); WRITE_OPT_VAR(shear_y, t); } CHECK_MEM_ERROR(AppendFmtAdvancePtr("v\n")); CHECK_MEM_ERROR(AppendFmtAdvancePtr("\n\n# control points\n")); for (i = 0; i < g->numPts; i++) { cpt = &g->cpt[i]; if (cpt->stddev >= 0) { if (cpt->weight >= 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d s%.15g w%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->stddev, cpt->weight)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d s%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->stddev)); } } else if (cpt->weight >= 0) { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d w%.15g\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type, cpt->weight)); } else { CHECK_MEM_ERROR(AppendFmtAdvancePtr("c n%d N%d x%.15g y%.15g X%.15g Y%.15g t%d\n", cpt->num[0], cpt->num[1], cpt->x[0], cpt->y[0], cpt->x[1], cpt->y[1], cpt->type)); } } if (WriteScript(res, sfile, 0) != 0) { PrintError("Could not write results to scriptfile"); } if (hres) myfree((void**)hres); panoLocaleRestore; return; fail: panoLocaleRestore; } void readControlPoints(char* script, controlPoint* cp) { struct controlPoint defCn; // Variables used by parser char line[LINE_LENGTH], * ch, * lineStart; int lineNum = 0; int i; int numPts; panoLocaleSave; defCn.num[0] = defCn.num[1] = -1; defCn.type = 0; defCn.x[0] = defCn.x[1] = defCn.y[0] = defCn.y[1] = 0; for (i = 0; i < NUMPTS; i++) memcpy(&(cp[i]), &defCn, sizeof(struct controlPoint)); numPts = 0; // reused as indices // Parse script for (ch = script; 0 != *ch; ('\r' == *ch) ? ch++ : ch, ('\n' == *ch) ? ch++ : ch, ('\r' == *ch) ? ch++ : ch ) { lineNum++; while (*ch == '\n') { ch++; lineNum++; } lineStart = ch; // read a line of text into line[]; lineNum += nextLine(line, &ch); // parse line; use only if first character is c switch (line[0]) { case 'c': // Control Points defCn.num[0] = defCn.num[1] = -1; defCn.type = 0; defCn.x[0] = defCn.x[1] = defCn.y[0] = defCn.y[1] = 0; defCn.stddev = -1; // default : no stddev defCn.weight = -1; // default : no weight if (ReadControlPoint(&defCn, &(line[1])) != 0) { PrintError("Error in line %d", lineNum); panoLocaleRestore; return; } if (defCn.num[1] == -1) // We found a partial controlpoint { *lineStart = 0; // script ends here memcpy(&(cp[numPts]), &defCn, sizeof(struct controlPoint)); numPts++; } break; case '*': // End of script-data *lineStart = 0; *ch = 0; break; default: break; } } panoLocaleRestore; } // Fill 'word' with word starting at (*ch). Advance *ch void nextWord(register char* word, char** ch, int max_word_length) { register char* c; c = *ch; c++; if (*c == '\"') { c++; while (*c != '\"' && *c != 0) { if (max_word_length-- <= 0) exit(1); *word++ = *c++; } if (*c != 0) c++; // to eat last character } else { while (!isspace(*c) && *c != 0) { *word++ = *c++; } } if (max_word_length-- <= 0) exit(1); *word = 0; *ch = c; } // Fill 'line' with line starting at (*ch). Advance *ch // Returns number of newlines read WITHOUT the last newline. int nextLine(register char* line, char** ch) { register char* c; register int i; register int n = 0; c = *ch; while (*c == '\n') { c++; n++; } // read a line of text into line[]; i = 0; //Increased by Max Lyons (January 12, 2003) to increase size of optimizer //lines that can be read (previously hard-coded to 255 characters). while (*c != 0 && *c != '\n' && ++i < LINE_LENGTH) // ++i not i++ because of terminating zero *line++ = *c++; *line = 0; *ch = c; return n; } // Number of lines in script starting with character 'first' int numLines(char* script, char first) { register char* ch; int result = 0; ch = script; while (*ch != 0) { // Advance to linestart while (*ch == '\n') ch++; if (*ch == first) result++; while (*ch != '\n' && *ch != 0) ch++; } return result; } #undef MY_SSCANF #define MY_SSCANF( str, format, ptr ) if( sscanf( str, format, ptr ) != 1 ) \ { \ PrintError("Syntax error in script: Could not read value for variable");\ return -1; \ } #undef READ_VAR #define READ_VAR(format, ptr ) nextWordBuf(&ch); \ MY_SSCANF( buf, format, ptr ); // Parse a line describing a single Controlpoint static int ReadControlPoint(controlPoint* cptr, char* line) { controlPoint cp; char* ch = line; int setn, setN, setx, setX, sety, setY; char buf[LINE_LENGTH]; setn = setN = setx = setX = sety = setY = FALSE; memcpy(&cp, cptr, sizeof(controlPoint)); while (*ch != 0) { switch (*ch) { case 't': READ_VAR("%d", &(cp.type)); break; case 'n': READ_VAR("%d", &(cp.num[0])); setn = TRUE; break; case 'N': READ_VAR("%d", &(cp.num[1])); setN = TRUE; break; case 'x': READ_VAR("%lf", &(cp.x[0])); setx = TRUE; break; case 'X': READ_VAR("%lf", &(cp.x[1])); setX = TRUE; break; case 'y': READ_VAR("%lf", &(cp.y[0])); sety = TRUE; break; case 'Y': READ_VAR("%lf", &(cp.y[1])); setY = TRUE; break; case 'i': READ_VAR("%d", &(cp.num[0])); cp.num[1] = cp.num[0]; setn = TRUE; setN = TRUE; case 's': READ_VAR("%lf", &(cp.stddev)); break; case 'w': READ_VAR("%lf", &(cp.weight)); break; default: ch++; break; } } // Check values if (setn == FALSE || setN == FALSE || setx == FALSE || setX == FALSE || sety == FALSE || setY == FALSE) { PrintError("Missing Control Point Parameter"); return -1; } else if (cp.type < 0) { PrintError("Control Point Type must be positive"); return -1; } else if (0 == cp.stddev && 0 == cp.weight) { PrintError("If both 's' and 'w' parameters are defined, at least one of them must be nonzero."); return -1; } // Joost: cp coordinates can be possible, no problem! // else if( cp.x[0] < 0 || cp.y[0] < 0 || cp.x[1] < 0 || cp.y[1] < 0) // { // PrintError("Pixel Coordinates must be positive"); // return -1; // } else // looks ok so far { memcpy(cptr, &cp, sizeof(controlPoint)); return 0; } } // Parse a line describing a single image static int ReadImageDescription(Image* imPtr, stBuf* sPtr, char* line) { // This function parses the i- and -o lines Image im; stBuf sBuf; char* ch = line; char buf[LINE_LENGTH]; int i; int cropping = 0; int tempInt; char typeParm; int32_t tempInt32; memcpy(&im, imPtr, sizeof(Image)); memcpy(&sBuf, sPtr, sizeof(stBuf)); while (*ch != 0) { switch (*ch) { case 'f': READ_VAR("%d", &tempInt32); tempInt = panoExternalToInternalInputProjection(tempInt32); if (tempInt < 0) { PrintError("Syntax error in script. Projection not known: %ud", tempInt32); return -1; } im.format = tempInt; if (im.format == _panorama || im.format == _equirectangular) im.cP.correction_mode |= correction_mode_vertical; break; case 'v': READ_VAR("%lf", &im.hfov); break; case 'y': READ_VAR("%lf", &im.yaw); break; case 'p': READ_VAR("%lf", &im.pitch); break; case 'r': READ_VAR("%lf", &im.roll); break; case 'a': READ_VAR("%lf", &(im.cP.radial_params[0][3])); im.cP.radial = TRUE; break; case 'b': READ_VAR("%lf", &(im.cP.radial_params[0][2])); im.cP.radial = TRUE; break; case 'c': READ_VAR("%lf", &(im.cP.radial_params[0][1])); im.cP.radial = TRUE; break; case 'd': READ_VAR("%lf", &(im.cP.horizontal_params[0])); im.cP.horizontal = TRUE; break; case 'e': READ_VAR("%lf", &(im.cP.vertical_params[0])); im.cP.vertical = TRUE; break; case 'g': READ_VAR("%lf", &(im.cP.shear_x)); im.cP.shear = TRUE; break; case 't': READ_VAR("%lf", &(im.cP.shear_y)); im.cP.shear = TRUE; break; case 'T': ch++; switch (*ch) { case 'i': ch++; switch (*ch) { case 'X': READ_VAR("%lf", &(im.cP.tilt_x)); break; case 'Y': READ_VAR("%lf", &(im.cP.tilt_y)); break; case 'Z': READ_VAR("%lf", &(im.cP.tilt_z)); break; case 'S': READ_VAR("%lf", &(im.cP.tilt_scale)); break; default: PrintError("Unknown variable name Ti%c in script", *ch); return -1; } im.cP.tilt = TRUE; break; case 'r': ch++; switch (*ch) { case 'X': READ_VAR("%lf", &(im.cP.trans_x)); break; case 'Y': READ_VAR("%lf", &(im.cP.trans_y)); break; case 'Z': READ_VAR("%lf", &(im.cP.trans_z)); break; default: PrintError("Unknown variable name Tr%c in script", *ch); return -1; } if (im.cP.trans_x != 0.0 || im.cP.trans_y != 0.0 || im.cP.trans_z != 0.0) { im.cP.trans = TRUE; } break; case 'p': ch++; switch (*ch) { case 'y': READ_VAR("%lf", &(im.cP.trans_yaw)); break; case 'p': READ_VAR("%lf", &(im.cP.trans_pitch)); break; default: PrintError("Unknown variable name Tp%c in script", *ch); return -1; } break; case 'e': ch++; switch (*ch) { case '0': READ_VAR("%lf", &(im.cP.test_p0)); break; case '1': READ_VAR("%lf", &(im.cP.test_p1)); break; case '2': READ_VAR("%lf", &(im.cP.test_p2)); break; case '3': READ_VAR("%lf", &(im.cP.test_p3)); break; default: PrintError("Unknown variable name Te%c in script", *ch); return -1; } im.cP.test = TRUE; break; default: PrintError("Unkonwn parameter T%c in script", *ch); return -1; } break; case '+': nextWordBuf(&ch); PrintError("Obsolete + parameter is ignored in image description"); snprintf(sBuf.srcName, 256, "%s", buf); break; case '-': nextWordBuf(&ch); PrintError("Obsolete - parameter is ignored in image description"); snprintf(sBuf.destName, 256, "%s", buf); break; case 'S': if (cropping) { PrintError("Contradictory cropping specified. S cropping ignored\n"); // Eat next token nextWordBuf(&ch); break; } cropping = 1; nextWordBuf(&ch); sscanf(buf, "%d,%d,%d,%d", &im.selection.left, &im.selection.right, &im.selection.top, &im.selection.bottom); break; case 'C': if (cropping) { PrintError("Contradictory cropping specified. C cropping ignored\n"); // Eat next token nextWordBuf(&ch); break; } cropping = 1; nextWordBuf(&ch); sscanf(buf, "%d,%d,%d,%d", &im.selection.left, &im.selection.right, &im.selection.top, &im.selection.bottom); im.cP.cutFrame = TRUE; break; case 'm': // Frame //THiS NEEDS A GOOD FIX... typeParm = *(ch + 1); // first consume the parameter if (typeParm == 'x' || typeParm == 'y') { // Consume next character, then read parm ch++; READ_VAR("%d", &tempInt); } else { READ_VAR("%d", &tempInt); } if (tempInt == 0) { // value of zero, just ignore break; } // Sometimes this is specified to force a zero. In this case // issue a warning and ignore if (cropping) { PrintError("Contradictory cropping specified. M cropping ignored\n"); break; } // Eat next token to avoid error cropping = 1; im.cP.cutFrame = TRUE; switch (typeParm) { case 'x': im.cP.fwidth = tempInt; //READ_VAR( "%d", &im.cP.fwidth ); break; case 'y': im.cP.fheight = tempInt; //READ_VAR( "%d", &im.cP.fheight ); //im.cP.cutFrame = TRUE; break; default: im.cP.frame = tempInt; READ_VAR("%d", &(im.cP.frame)); // im.cP.cutFrame = TRUE; break; } break; case 's': READ_VAR("%d", &sBuf.seam); PrintError("Obsolete s parameter ignored in image description"); break; case 'o': ch++; im.cP.correction_mode |= correction_mode_morph; break; case 'u': READ_VAR("%d", &i); break; case 'w': READ_VAR("%ud", &im.width); break; case 'h': READ_VAR("%ud", &im.height); break; case 'n': // Name string (used for input image name) nextWordBuf(&ch); StrcpyN(im.name, buf, MAX_PATH_LENGTH); break; case 'K': case 'V': // Used by Hugin. Silently ignore until next space. This way we can accept .pto files for processing nextWordBuf(&ch); break; case ' ': case '\t': case '\n': case '\r': // skip characters and tabs ch++; break; default: printf("Returning...........\n"); PrintError("Illegal token in adjust line [%c] rest of line [%s]", *ch, ch); return -1; } } // printf("************************************* A Cut Frame %d \n", im.cP.cutFrame); // Set 4th polynomial parameter im.cP.radial_params[0][0] = 1.0 - (im.cP.radial_params[0][3] + im.cP.radial_params[0][2] + im.cP.radial_params[0][1]); SetEquColor(&im.cP); SetCorrectionRadius(&im.cP); // Do checks // appears ok memcpy(imPtr, &im, sizeof(Image)); memcpy(sPtr, &sBuf, sizeof(stBuf)); // panoPrintImage("After read image", imPtr); return 0; } #ifdef CAN_READ_HUGIN_FILES static int ReadPanoramaDescription(Image* imPtr, PanoImageInfo* iminfoPtr, stBuf* sPtr, char* line) #else static int ReadPanoramaDescription(Image* imPtr, stBuf* sPtr, char* line) #endif { // This function parses the p- line Image im; stBuf sBuf; char* ch = line; char buf[LINE_LENGTH]; char* b; int i; double tempDbl; #ifdef CAN_READ_HUGIN_FILES PanoImageInfo imi; #endif memcpy(&im, imPtr, sizeof(Image)); memcpy(&sBuf, sPtr, sizeof(stBuf)); #ifdef CAN_READ_HUGIN_FILES if (0 != iminfoPtr) memcpy(&imi, iminfoPtr, sizeof(PanoImageInfo)); #endif while (*ch != 0) { switch (*ch) { case 'w': READ_VAR("%ud", &im.width); break; case 'h': READ_VAR("%ud", &im.height); break; case 'f': READ_VAR("%d", &im.format); if (im.format == _panorama || im.format == _equirectangular) im.cP.correction_mode |= correction_mode_vertical; #ifdef CAN_READ_HUGIN_FILES imi.pto_format = im.format; #endif break; case 'P': nextWordBuf(&ch); b = Strtok(buf, " \""); if (b != NULL) { while (b != NULL) { if (sscanf(b, "%lf", &tempDbl) == 1) { if (++im.formatParamCount > PANO_PROJECTION_MAX_PARMS) { PrintError("Illegal number of projection parameters. Maximum is %d", PANO_PROJECTION_MAX_PARMS); return -1; } im.formatParam[im.formatParamCount - 1] = tempDbl; b = Strtok(NULL, " \""); } else { PrintError("Illegal value in P parameter %s", b); return -1; } } } break; #ifdef CAN_READ_HUGIN_FILES case 'S': nextWordBuf(&ch); b = Strtok(buf, " ,"); i = 0; if (b != NULL) { while (b != NULL) { if (sscanf(b, "%lf", &tempDbl) == 1) { if (++i > 4) { PrintError("Illegal number of selection parameters. Required exactly 4."); return -1; } switch (i) { case 1: imi.SelLeft = (uint32_t)tempDbl; break; case 2: imi.SelRight = (uint32_t)tempDbl; break; case 3: imi.SelTop = (uint32_t)tempDbl; break; case 4: imi.SelBottom = (uint32_t)tempDbl; break; }; b = Strtok(NULL, " ,"); } else { PrintError("Illegal value in S parameter %s", b); return -1; } } if (i < 4) { PrintError("Too less selection parameters. Required exactly 4."); return -1; } } break; #endif // CAN_READ_HUGIN_FILES case 'v': READ_VAR("%lf", &im.hfov); break; case 'n': // Name string (used for panorama format) nextWordBuf(&ch); StrcpyN(im.name, buf, MAX_PATH_LENGTH); break; #ifdef CAN_READ_HUGIN_FILES case 'T': // Name string (used for panorama format) nextWordBuf(&ch); StrcpyN(imi.TParam, buf, PanoramaImageTParamSize + 1); break; case 'R': // Name string (used for panorama format) READ_VAR("%d", &i); imi.RParam = i; break; case 'E': //Exposure READ_VAR("%lf", &imi.EParam); break; #endif // CAN_READ_HUGIN_FILES #ifdef CAN_READ_HUGIN_FILES case 'u': //Feather READ_VAR("%d", &imi.u); break; case 'k': // Colour correction READ_VAR("%d", &imi.k); break; case 'd': // Colour correction READ_VAR("%d", &imi.d); break; case 'b': // Colour correction READ_VAR("%d", &imi.b); break; #else case 'u': //Feather READ_VAR("%d", &i); PrintError("Feathering is ignored. Use PTmasker"); break; case 'k': // Colour correction READ_VAR("%d", &i); PrintError("Colour correction ignored (k). Use PTblender"); break; case 'd': // Colour correction READ_VAR("%d", &i); PrintError("Colour correction ignored (d). Use PTblender"); break; case 'b': // Colour correction READ_VAR("%d", &i); PrintError("Colour correction ignored parameter ignored (b). Use PTblender"); break; #endif case ' ': case '\t': case '\n': case '\r': // skip characters and tabs ch++; break; default: PrintError("Illegal token in 'p'-line [%d] [%c] [%s]", *ch, *ch, ch); ch++; break; } } // I am not sure this is needed, but I am not sure it is not :) // code inherited from ReadImageDescription im.cP.radial_params[0][0] = 1.0 - (im.cP.radial_params[0][3] + im.cP.radial_params[0][2] + im.cP.radial_params[0][1]); SetEquColor(&im.cP); SetCorrectionRadius(&im.cP); memcpy(imPtr, &im, sizeof(Image)); memcpy(sPtr, &sBuf, sizeof(stBuf)); #ifdef CAN_READ_HUGIN_FILES if (0 != iminfoPtr) memcpy(iminfoPtr, &imi, sizeof(PanoImageInfo)); #endif return 0; } // Parse a line describing modes static int ReadModeDescription(sPrefs* sP, char* line) { sPrefs theSprefs; char* ch = line; char buf[LINE_LENGTH]; double sigma = 0; int n; memcpy(&theSprefs, sP, sizeof(sPrefs)); // set some default values setFcnPanoHuberSigma(0); while (*ch != 0) { switch (*ch) { case 'g': READ_VAR("%lf", &theSprefs.gamma); if (theSprefs.gamma <= 0.0) return -1; break; case 'i': READ_VAR("%d", &theSprefs.interpolator); if (theSprefs.interpolator < 0 || theSprefs.interpolator > 23) theSprefs.interpolator = 0; break; case 'p': READ_VAR("%d", &theSprefs.optCreatePano); if (theSprefs.optCreatePano != 0) theSprefs.optCreatePano = TRUE; break; case 'f': READ_VAR("%d", &n); if (n == 0) theSprefs.fastStep = FAST_TRANSFORM_STEP_NORMAL; else if (n == 1) theSprefs.fastStep = FAST_TRANSFORM_STEP_MORPH; else theSprefs.fastStep = FAST_TRANSFORM_STEP_NONE; break; case 'm': READ_VAR("%lf", &sigma); setFcnPanoHuberSigma(sigma); break; default: ch++; break; } } // appears ok memcpy(sP, &theSprefs, sizeof(sPrefs)); return 0; } // Parse a string desscribing VRPanoOptions int getVRPanoOptions(VRPanoOptions* v, char* line) { char* ch = line; char buf[LINE_LENGTH]; VRPanoOptions VRopt; panoLocaleSave; memcpy(&VRopt, v, sizeof(VRPanoOptions)); while (*ch != 0) { switch (*ch) { case 'w': READ_VAR("%d", &VRopt.width); break; case 'h': READ_VAR("%d", &VRopt.height); break; case 'p': READ_VAR("%lf", &VRopt.pan); break; case 't': READ_VAR("%lf", &VRopt.tilt); break; case 'v': READ_VAR("%lf", &VRopt.fov); break; case 'c': READ_VAR("%d", &VRopt.codec); break; case 'q': READ_VAR("%d", &VRopt.cquality); break; case 'g': READ_VAR("%d", &VRopt.progressive); break; default: ch++; break; } } memcpy(v, &VRopt, sizeof(VRPanoOptions)); panoLocaleRestore; return 0; } // Read coordinates of positions int readPositions(char* script, transformCoord* tP) { // Variables used by parser char line[LINE_LENGTH], * ch; int lineNum = 0; int nr = 0, np = 0; panoLocaleSave; // Determine number of images and control points tP->nump = numLines(script, 'P'); tP->numr = numLines(script, 'R'); // Allocate Space for Pointers to images, preferences and control points tP->r = (CoordInfo*)malloc(tP->numr * sizeof(CoordInfo)); tP->p = (CoordInfo*)malloc(tP->nump * sizeof(CoordInfo)); if (tP->r == NULL || tP->p == NULL) { PrintError("Not enough memory"); goto fail; } // Parse script for (ch = script; 0 != *ch; ('\r' == *ch) ? ch++ : ch, ('\n' == *ch) ? ch++ : ch, ('\r' == *ch) ? ch++ : ch ) { lineNum++; while (*ch == '\n') { ch++; lineNum++; } // read a line of text into line[]; lineNum += nextLine(line, &ch); // parse line; use only if first character is p,o,m switch (line[0]) { case 'P': // Coordinates as is if (ReadCoordinates(&tP->p[np++], &(line[1])) != 0) { PrintError("Syntax error in line %d", lineNum); goto fail; } break; case 'R': // Coordinate values requested if (ReadCoordinates(&tP->r[nr++], &(line[1])) != 0) { PrintError("Syntax error in line %d", lineNum); goto fail; } break; default: break; } } panoLocaleRestore; return 0; fail: panoLocaleRestore; return -1; } static int ReadCoordinates(CoordInfo* cp, char* line) { CoordInfo ci; char* ch = line; char buf[LINE_LENGTH]; ci.num = ci.set[0] = ci.set[1] = ci.set[2] = 0; ci.x[0] = ci.x[1] = ci.x[2] = 1.0; while (*ch != 0) { switch (*ch) { case 'c': READ_VAR("%d", &ci.num); break; case 'i': READ_VAR("%d", &ci.num); ci.num -= 2; break; case 'X': READ_VAR("%lf", &ci.x[0]); ci.set[0] = TRUE; break; case 'Y': READ_VAR("%lf", &ci.x[1]); ci.set[1] = TRUE; break; case 'Z': READ_VAR("%lf", &ci.x[2]); ci.set[2] = TRUE; break; default: ch++; break; } } // appears ok memcpy(cp, &ci, sizeof(CoordInfo)); return 0; } int ReadMorphPoints(char* script, AlignInfo* gl, int nIm) { // Variables used by parser char line[LINE_LENGTH], * ch; int lineNum = 0; int np = 0; controlPoint cp; void* tmp; panoLocaleSave; // Determine number of morph control points gl->numPts = numLines(script, 'C'); if (gl->numPts == 0) goto success; // Allocate Space for Pointers to images, preferences and control points gl->cpt = (controlPoint*)malloc(gl->numPts * sizeof(controlPoint)); if (gl->cpt == NULL) { PrintError("Not enough memory"); goto fail; } // Parse script for (ch = script; 0 != *ch; ('\r' == *ch) ? ch++ : ch, ('\n' == *ch) ? ch++ : ch, ('\r' == *ch) ? ch++ : ch ) { lineNum++; while (*ch == '\n') { ch++; lineNum++; } // read a line of text into line[]; lineNum += nextLine(line, &ch); // parse line; use only if first character is p,o,m switch (line[0]) { case 'C': // Coordinates as is cp.type = 0; cp.stddev = -1; // default : no stddev cp.weight = -1; // default : no weight if (ReadControlPoint(&cp, &(line[1])) != 0) { PrintError("Syntax error in line %d", lineNum); goto fail; } if (cp.num[0] == nIm) { cp.num[0] = 0; cp.num[1] = 1; memcpy(&gl->cpt[np], &cp, sizeof(controlPoint)); np++; } default: break; } } tmp = realloc(gl->cpt, np * sizeof(controlPoint)); if (tmp == NULL) goto fail; gl->numPts = np; gl->cpt = (controlPoint*)tmp; success: panoLocaleRestore; return np; fail: panoLocaleRestore; return -1; } void SetCoordDefaults(CoordInfo* c, int num) { c->num = num; c->x[0] = (double)num; c->x[1] = c->x[2] = 0.0; c->set[0] = c->set[1] = c->set[2] = TRUE; } int panoExternalToInternalInputProjection(int input) { // Internal and external projection do not match, unfortunately. // So this code does the remapping switch (input) { case IMAGE_FORMAT_RECTILINEAR: return(_rectilinear); case IMAGE_FORMAT_PANORAMA: return(_panorama); case IMAGE_FORMAT_FISHEYE_EQUIDISTANCECIRC: return(_fisheye_circ); case IMAGE_FORMAT_FISHEYE_EQUIDISTANCEFF: return(_fisheye_ff); case IMAGE_FORMAT_EQUIRECTANGULAR: return(_equirectangular); case IMAGE_FORMAT_MIRROR: return(_mirror); case IMAGE_FORMAT_FISHEYE_ORTHOGRAPHIC: return(_orthographic); case IMAGE_FORMAT_FISHEYE_STEREOGRAPHIC: return(_stereographic); case IMAGE_FORMAT_FISHEYE_EQUISOLID: return(_equisolid); case IMAGE_FORMAT_FISHEYE_THOBY: return(_thoby); default: return -1; } } int StringtoFullPath(fullPath* path, char* filename) { if (strlen(filename) < 256) { strcpy(path->name, filename); return 0; } else { return -1; } } void DisposeAlignInfo(struct AlignInfo* g) { int64_t i; if (g->im != NULL) free(g->im); if (g->opt != NULL) free(g->opt); if (g->allopt != NULL) free(g->allopt); if (g->cpt != NULL) free(g->cpt); if (g->t != NULL) free(g->t); if (g->cim != NULL) free(g->cim); #ifdef CAN_READ_HUGIN_FILES if (g->HuginOptions != NULL) free(g->HuginOptions); if (g->HuginOptionsCharMem != NULL) free(g->HuginOptionsCharMem); if (g->huginmasks != NULL) { for (i = 0; i < g->numhuginmasks; i++) if (g->huginmasks[i].coords != NULL) free(g->huginmasks[i].coords); free(g->huginmasks); } #endif // CAN_READ_HUGIN_FILES if (g->var_constraint_indices) free(g->var_constraint_indices); if (g->initial_cned_parameters) free(g->initial_cned_parameters); if (g->cned_parameters_weights) free(g->cned_parameters_weights); if (g->min_cned_parameters) free(g->min_cned_parameters); if (g->max_cned_parameters) free(g->max_cned_parameters); } int main(int argc, char* argv[]) { aPrefs aP; AlignInfo ainf; fullPath infile; fullPath outfile; //SetAdjustDefaults(&aP); if (argc != 3) { printf("Usage: %s /path/to/hugin/script.pto /path/to/PTOptimizer/script.pto\n", argv[0]); return 1; } StringtoFullPath(&infile, argv[1]); StringtoFullPath(&outfile, argv[2]); char *script = LoadScript(&infile); if (script != NULL) { if (ParseScript(script, &ainf) == 0) { //if (CheckParams(&ainf) == 0) { ainf.fcn = 0; ainf.data = 0; printf("Writing file for PTOptimizer.\n"); WritePTOptimizerFile(script, &outfile, &ainf); } /*else { DisposeAlignInfo(&ainf); return 1; }*/ DisposeAlignInfo(&ainf); } else { return 1; } free(script); } return 0; }