Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

Diff of /adjust.c [fd99ad] .. [9b59c0] Maximize Restore

  Switch to side-by-side view

--- a/adjust.c
+++ b/adjust.c
@@ -1,4 +1,4 @@
-/* Panorama_Tools	-	Generate, Edit and Convert Panoramic Images
+/* 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
@@ -36,13 +36,16 @@
                   panorama size (feature change)
                6) Report rms error during optimization (bug fix)
 */
+#include <math.h>
 #include "filter.h"
 #include "f2c.h"
 #include <float.h>
-
-#define C_FACTOR	100.0
-
-static  AlignInfo	*g;	// This struct holds all informations for the optimization
+#include <assert.h>
+#include <PTcommon.h>
+
+#define C_FACTOR        100.0
+
+static  AlignInfo       *optInfo;       // This struct holds all informations for the optimization
 
 static double initialAvgFov;   // these three for fov stabilization
 static double avgfovFromSAP;
@@ -51,397 +54,428 @@
 #define ADJUST_LOG_FILENAME "PToolsLog.txt"  // file name for logging, if enabled
 #define ADJUST_LOGGING_ENABLED 0
 
-// enable mosaic with X,Y,Z camera positions instead of tilt
-//#define MOSAIC_XYZ 1
-
 FILE* adjustLogFile = 0;
 
 
-void 			ColCorrect( Image *im, double ColCoeff[3][2] );
-void 			GetColCoeff( Image *src, Image *buf, double ColCoeff[3][2] );
-void 			getControlPoints( Image *im, struct controlPoint *cp );
-void 			writeControlPoints( struct controlPoint *cp,char* cdesc );
-int 			CheckParams( AlignInfo *g );
-static int		CheckMakeParams( aPrefs *aP);
-//static int		GetOverlapRect( PTRect *OvRect, PTRect *r1, PTRect *r2 );
-int 			AddEdgePoints( AlignInfo *gl );
-int 			pt_average( UCHAR* pixel, int BytesPerLine, double rgb[3], int bytesPerChannel );
-double 			distsqLine(int N0, int N1);
+void                    ColCorrect( Image *im, double ColCoeff[3][2] );
+void                    GetColCoeff( Image *src, Image *buf, double ColCoeff[3][2] );
+void                    getControlPoints( Image *im, struct controlPoint *cp );
+void                    writeControlPoints( struct controlPoint *cp,char* cdesc );
+int                     CheckParams( AlignInfo *g );
+static int              CheckMakeParams( aPrefs *aP);
+//static int            GetOverlapRect( PTRect *OvRect, PTRect *r1, PTRect *r2 );
+int                     AddEdgePoints( AlignInfo *gl );
+int                     pt_average( UCHAR* pixel, int BytesPerLine, double rgb[3], int bytesPerChannel );
+double                  distsqLine(int N0, int N1);
+
+
+
+void panoAdjustPrintMakeParams(char *msg, struct MakeParams *mp, Image *im)
+{
+    printf("-------------%s\n", msg);
+    if (mp != NULL) {
+        printf("distnace %f\n", mp->distance);
+        printf("shear[0] %f\n", mp->shear[0]);
+        printf("shear[1] %f\n", mp->shear[1]);
+        printf("rot[0] %f\n", mp->rot[0]);
+        printf("rot[1] %f\n", mp->rot[1]);
+        printf("tilt[0] %f\n", mp->tilt[0]);
+        printf("tilt[1] %f\n", mp->tilt[1]);
+        printf("tilt[2] %f\n", mp->tilt[2]);
+        printf("tilt[3] %f\n", mp->tilt[3]);
+        
+        printf("trans[0] %f\n", mp->trans[0]);
+        printf("trans[1] %f\n", mp->trans[1]);
+        printf("trans[2] %f\n", mp->trans[2]);
+        
+        printf("test[0] %f\n", mp->test[0]);
+        printf("test[1] %f\n", mp->test[1]);
+        printf("test[2] %f\n", mp->test[2]);
+        printf("test[3] %f\n", mp->test[3]);
+        
+        
+        printf("mp->horizontal %f\n", mp->horizontal);
+        printf("mp->vertical %f\n", mp->vertical);
+    }
+    panoPrintImage(msg, im);
+    printf("\n\n");
+
+}
 
 
 void adjust(TrformStr *TrPtr, aPrefs *prefs)
 {
-	int	 	destwidth, destheight;
-	aPrefs		aP, *aPtr=NULL;
+        int             destwidth, destheight;
+        aPrefs          aP, *aPtr=NULL;
 #if 0
-	int 		nt = 0;		// Morph  parameters
-	PTTriangle 	*ts=NULL; 
-	PTTriangle 	*td=NULL; 
+        int             nt = 0;         // Morph  parameters
+        PTTriangle      *ts=NULL; 
+        PTTriangle      *td=NULL; 
 #endif
-	SetAdjustDefaults(&aP);
-
-	switch( prefs->mode & 7 )// Should we use prefs, or read from script?
-	{
-		case _insert:
-		case _extract:
-			if( prefs->mode & _useScript ){
-				aPtr = readAdjustLine( &(prefs->scriptFile) );
-				if(aPtr==NULL){
-					PrintError("Error processing script file" );
-					TrPtr->success = 0;
-					return;
-				}
-				memcpy(&aP, aPtr, sizeof(aPrefs));
-				free(aPtr); aPtr = &aP;
-
-				if( (TrPtr->mode & 7) == _usedata ){ // Report panorama format and stitching info back to calling app.
-					memcpy( &prefs->pano, &aP.pano, sizeof( Image ) );
-					memcpy( &prefs->sBuf, &aP.sBuf, sizeof( stBuf ) );
-				}
-
-				TrPtr->interpolator = aP.interpolator;
-				TrPtr->gamma	    = aP.gamma;
+        SetAdjustDefaults(&aP);
+
+        switch( prefs->mode & 7 )// Should we use prefs, or read from script?
+        {
+                case _insert:
+                case _extract:
+                        if( prefs->mode & _useScript ){
+                                aPtr = readAdjustLine( &(prefs->scriptFile) );
+                                if(aPtr==NULL){
+                                        PrintError("Error processing script file" );
+                                        TrPtr->success = 0;
+                                        return;
+                                }
+                                memcpy(&aP, aPtr, sizeof(aPrefs));
+                                free(aPtr); aPtr = &aP;
+
+                                if( (TrPtr->mode & 7) == _usedata ){ // Report panorama format and stitching info back to calling app.
+                                        memcpy( &prefs->pano, &aP.pano, sizeof( Image ) );
+                                        memcpy( &prefs->sBuf, &aP.sBuf, sizeof( stBuf ) );
+                                }
+
+                                TrPtr->interpolator = aP.interpolator;
+                                TrPtr->gamma        = aP.gamma;
                 TrPtr->fastStep     = aP.fastStep;
-					
+                                        
 #if 0
-				int readmode = 1;
-				aPtr = &aP;
-				gsPrPtr->interpolator 	= TrPtr->interpolator;
-				gsPrPtr->gamma			= TrPtr->gamma;
-                gsPrPtr->fastStep	    = TrPtr->fastStep;
-				if( TrPtr->mode & _destSupplied ){
-					PTRect* p = &TrPtr->dest->selection;
-					if( !(p->bottom == 0 && p->right == 0) &&
-					    !(p->right == TrPtr->dest->width &&
-					     p->bottom == TrPtr->dest->height) )
-						readmode = 0;
-				}
-				if( readAdjust( aPtr, &(prefs->scriptFile), readmode, gsPrPtr ) != 0 )
-				{
-					PrintError("Error processing script file" );
-					TrPtr->success = 0;
-					return;
-				}
-				if( (TrPtr->mode & 7) == _usedata ) // Report panorama format and stitching info back to calling app.
-				{
-					memcpy( &prefs->pano, &aP.pano, sizeof( Image ) );
-					memcpy( &prefs->sBuf, &aP.sBuf, sizeof( stBuf ) );
-				}
-				// Use modevalues read from script
-				TrPtr->interpolator = gsPrPtr->interpolator;
-				TrPtr->gamma		= gsPrPtr->gamma;
+                                int readmode = 1;
+                                aPtr = &aP;
+                                gsPrPtr->interpolator   = TrPtr->interpolator;
+                                gsPrPtr->gamma                  = TrPtr->gamma;
+                gsPrPtr->fastStep           = TrPtr->fastStep;
+                                if( TrPtr->mode & _destSupplied ){
+                                        PTRect* p = &TrPtr->dest->selection;
+                                        if( !(p->bottom == 0 && p->right == 0) &&
+                                            !(p->right == TrPtr->dest->width &&
+                                             p->bottom == TrPtr->dest->height) )
+                                                readmode = 0;
+                                }
+                                if( readAdjust( aPtr, &(prefs->scriptFile), readmode, gsPrPtr ) != 0 )
+                                {
+                                        PrintError("Error processing script file" );
+                                        TrPtr->success = 0;
+                                        return;
+                                }
+                                if( (TrPtr->mode & 7) == _usedata ) // Report panorama format and stitching info back to calling app.
+                                {
+                                        memcpy( &prefs->pano, &aP.pano, sizeof( Image ) );
+                                        memcpy( &prefs->sBuf, &aP.sBuf, sizeof( stBuf ) );
+                                }
+                                // Use modevalues read from script
+                                TrPtr->interpolator = gsPrPtr->interpolator;
+                                TrPtr->gamma            = gsPrPtr->gamma;
                 TrPtr->fastStep     = gsPrPtr->fastStep;
-				
-				// Parse script again, now reading triangles if morphing requested
-				if( aPtr->im.cP.correction_mode & correction_mode_morph )
-				{
-					char*				script;
-					AlignInfo			ainf;
-					int					nIm, nPts; // Number of image being processed
-					Image				im[2];
-					
-					script = LoadScript( &(prefs->scriptFile) );
-					if( script != NULL ) 					// We can read the scriptfile
-					{	
-						nIm = numLines( script, '!' ) - 1;
-						
-						if( nIm < 0)
-							nIm = numLines( script, 'o' ) - 1;
-					
-						// Set ainf
-						ainf.nt 	= 0;
-						ainf.t		= NULL;
-						ainf.numIm 	= 2;
-						ainf.im		= im;
-						memcpy( &ainf.pano, &aP.pano, sizeof( Image ));
-						memcpy( &ainf.im[0], &aP.pano, sizeof( Image ));
-						memcpy( &ainf.im[1], &aP.pano, sizeof( Image ));
-						
-						nPts = ReadMorphPoints( script, &ainf, nIm );
-						if(nPts > 0) // Found Points
-						{
-							AddEdgePoints( &ainf );
-							TriangulatePoints( &ainf, 1 );
-							nt = ainf.nt;
-							if(nt > 0)
-							{
-								SortControlPoints	( &ainf, 1 );
-								SetSourceTriangles	( &ainf, 1, &td  );
-								SetDestTriangles    ( &ainf, 1, &ts  );
-							}
-						}
-						if(ainf.numPts > 0) free(ainf.cpt);
-						free( script );
-					}
-				}
+                                
+                                // Parse script again, now reading triangles if morphing requested
+                                if( aPtr->im.cP.correction_mode & correction_mode_morph )
+                                {
+                                        char*                           script;
+                                        AlignInfo                       ainf;
+                                        int                                     nIm, nPts; // Number of image being processed
+                                        Image                           im[2];
+                                        
+                                        script = LoadScript( &(prefs->scriptFile) );
+                                        if( script != NULL )                                    // We can read the scriptfile
+                                        {       
+                                                nIm = numLines( script, '!' ) - 1;
+                                                
+                                                if( nIm < 0)
+                                                        nIm = numLines( script, 'o' ) - 1;
+                                        
+                                                // Set ainf
+                                                ainf.nt         = 0;
+                                                ainf.t          = NULL;
+                                                ainf.numIm      = 2;
+                                                ainf.im         = im;
+                                                memcpy( &ainf.pano, &aP.pano, sizeof( Image ));
+                                                memcpy( &ainf.im[0], &aP.pano, sizeof( Image ));
+                                                memcpy( &ainf.im[1], &aP.pano, sizeof( Image ));
+                                                
+                                                nPts = ReadMorphPoints( script, &ainf, nIm );
+                                                if(nPts > 0) // Found Points
+                                                {
+                                                        AddEdgePoints( &ainf );
+                                                        TriangulatePoints( &ainf, 1 );
+                                                        nt = ainf.nt;
+                                                        if(nt > 0)
+                                                        {
+                                                                SortControlPoints       ( &ainf, 1 );
+                                                                SetSourceTriangles      ( &ainf, 1, &td  );
+                                                                SetDestTriangles    ( &ainf, 1, &ts  );
+                                                        }
+                                                }
+                                                if(ainf.numPts > 0) free(ainf.cpt);
+                                                free( script );
+                                        }
+                                }
 #endif
-			}else{
-			 	aPtr = prefs;
-			}
-			 break;
-		default:
-			break;
-	}
-	switch( prefs->mode & 7)
-	{
-		case _insert:			// Create a panoramic image using src; merge with buffer if required
-			// Find brightest rectangle if this is a circular fisheye image
-			{
-			Image ImCrop, *theSrc=NULL;
-			// Initialise at least the data pointer since cutTheFrame may not do it
-			ImCrop.data = NULL;
-			
-			if( aPtr->im.format ==_fisheye_circ	&& aPtr->im.cP.cutFrame )
-			{
-				int fwidth = TrPtr->src->width, fheight = TrPtr->src->height;
-				
-				if( aPtr->im.cP.frame ) // subtract framewidth from width/height
-				{
-					fwidth = TrPtr->src->width - aPtr->im.cP.frame;
-					if( aPtr->im.cP.frame < fwidth ) fwidth -= aPtr->im.cP.frame;
-					if( aPtr->im.cP.frame < fheight) fheight-= aPtr->im.cP.frame;
-				}
-				else
-				{
-					if( aPtr->im.cP.fwidth > 0)
-						fwidth = aPtr->im.cP.fwidth;
-					if( aPtr->im.cP.fheight > 0)
-						fheight = aPtr->im.cP.fheight;
-				}
-					
-				if( cutTheFrame( &ImCrop, TrPtr->src, fwidth, fheight, TrPtr->mode & _show_progress ) != 0 )
-				{
-					PrintError("Error Cropping Image");
-					TrPtr->success = 0;
-					return;
-				}
-				theSrc = TrPtr->src;
-				TrPtr->src = &ImCrop;
-				
-			}
-			// Image params are set as src 
-			aPtr->im.width	= TrPtr->src->width;
-			aPtr->im.height	= TrPtr->src->height;
-			
-			// Pano is set to buffer, if merging requested; else as prefs
-			if( *aPtr->sBuf.srcName != 0 )
-			{
-				if (LoadBufImage( &(aPtr->pano), aPtr->sBuf.srcName, 0) != 0 )
-				{
-					PrintError( "Error loading Buffer; trying without" );
-				}
-			}
-						
-			if( aPtr->pano.width == 0 && aPtr->im.hfov != 0.0)
-			{
-				aPtr->pano.width = (pt_int32)(aPtr->im.width * aPtr->pano.hfov / aPtr->im.hfov);
-				aPtr->pano.width/=10; aPtr->pano.width*=10;
-			}
-			if( aPtr->pano.height == 0 )
-				aPtr->pano.height = aPtr->pano.width/2;
-
-			destheight 				= aPtr->pano.height;
-			destwidth 				= aPtr->pano.width;
-			
-			if( destheight == 0 || destwidth == 0 )
-			{
-				PrintError("Please set Panorama width/height" );
-				TrPtr->success = 0;
-				goto _insert_exit;
-			}
-			
-		
-			if( SetDestImage( TrPtr, destwidth, destheight) != 0)
-			{
-				PrintError("Could not allocate %ld bytes",TrPtr->dest->dataSize );
-				TrPtr->success = 0;
-				goto _insert_exit;
-			}
-			TrPtr->mode				|= _honor_valid;
-			CopyPosition( TrPtr->src,  &(aPtr->im) );
-			CopyPosition( TrPtr->dest, &(aPtr->pano) );
+                        }else{
+                                aPtr = prefs;
+                        }
+                         break;
+                default:
+                        break;
+        }
+        switch( prefs->mode & 7)
+        {
+                case _insert:                   // Create a panoramic image using src; merge with buffer if required
+                        // Find brightest rectangle if this is a circular fisheye image
+                        {
+                        Image ImCrop, *theSrc=NULL;
+                        // Initialise at least the data pointer since cutTheFrame may not do it
+                        ImCrop.data = NULL;
+                        
+                        if( aPtr->im.format ==_fisheye_circ     && aPtr->im.cP.cutFrame )
+                        {
+                                int fwidth = TrPtr->src->width, fheight = TrPtr->src->height;
+                                
+                                if( aPtr->im.cP.frame ) // subtract framewidth from width/height
+                                {
+                                        fwidth = TrPtr->src->width - aPtr->im.cP.frame;
+                                        if( aPtr->im.cP.frame < fwidth ) fwidth -= aPtr->im.cP.frame;
+                                        if( aPtr->im.cP.frame < fheight) fheight-= aPtr->im.cP.frame;
+                                }
+                                else
+                                {
+                                        if( aPtr->im.cP.fwidth > 0)
+                                                fwidth = aPtr->im.cP.fwidth;
+                                        if( aPtr->im.cP.fheight > 0)
+                                                fheight = aPtr->im.cP.fheight;
+                                }
+                                        
+                                if( cutTheFrame( &ImCrop, TrPtr->src, fwidth, fheight, TrPtr->mode & _show_progress ) != 0 )
+                                {
+                                        PrintError("Error Cropping Image");
+                                        TrPtr->success = 0;
+                                        return;
+                                }
+                                theSrc = TrPtr->src;
+                                TrPtr->src = &ImCrop;
+                                
+                        }
+                        // Image params are set as src 
+                        aPtr->im.width  = TrPtr->src->width;
+                        aPtr->im.height = TrPtr->src->height;
+                        
+                        // Pano is set to buffer, if merging requested; else as prefs
+                        if( *aPtr->sBuf.srcName != 0 )
+                        {
+                                if (LoadBufImage( &(aPtr->pano), aPtr->sBuf.srcName, 0) != 0 )
+                                {
+                                        PrintError( "Error loading Buffer; trying without" );
+                                }
+                        }
+                                                
+                        if( aPtr->pano.width == 0 && aPtr->im.hfov != 0.0)
+                        {
+                                aPtr->pano.width = (pt_int32)(aPtr->im.width * aPtr->pano.hfov / aPtr->im.hfov);
+                                aPtr->pano.width/=10; aPtr->pano.width*=10;
+                        }
+                        if( aPtr->pano.height == 0 )
+                                aPtr->pano.height = aPtr->pano.width/2;
+
+                        destheight                              = aPtr->pano.height;
+                        destwidth                               = aPtr->pano.width;
+                        
+                        if( destheight == 0 || destwidth == 0 )
+                        {
+                                PrintError("Please set Panorama width/height" );
+                                TrPtr->success = 0;
+                                goto _insert_exit;
+                        }
+                        
+                
+                        if( SetDestImage( TrPtr, destwidth, destheight) != 0)
+                        {
+                                PrintError("Could not allocate %ld bytes",TrPtr->dest->dataSize );
+                                TrPtr->success = 0;
+                                goto _insert_exit;
+                        }
+                        TrPtr->mode                             |= _honor_valid;
+                        CopyPosition( TrPtr->src,  &(aPtr->im) );
+                        CopyPosition( TrPtr->dest, &(aPtr->pano) );
       // JMW 2008/01/07 Alpha is valid data don't override it with blank data
-//			addAlpha( TrPtr->src ); // Add alpha channel to indicate valid data
-			
-			aPtr->mode = prefs->mode; // For checkparam
-			MakePano( TrPtr,  aPtr );
-			
-			if(aPtr->ts) free(aPtr->ts);
-			if(aPtr->td) free(aPtr->td);
-
-			// Stitch images; Proceed only if panoramic image valid
-
-			if( TrPtr->success )
-			{
-				if( *(aPtr->sBuf.srcName) != 0 ){ // We have to merge in one images
-					// Load the bufferimage
-					if( LoadBufImage( &aPtr->pano, aPtr->sBuf.srcName, 1 ) != 0 )
-					{
-						PrintError( "Could not load buffer %s; Keeping Source",aPtr->sBuf.srcName );
-						goto _insert_exit;
-					}
-
-					if( HaveEqualSize( &aPtr->pano, TrPtr->dest ))
-					{
-	
-						// At this point we have two valid, equally sized images						
-						// Do Colour Correction on one or both  images
-						DoColorCorrection( TrPtr->dest, &aPtr->pano, aPtr->sBuf.colcorrect & 3);
-						
-						if( merge( TrPtr->dest , &aPtr->pano, aPtr->sBuf.feather, TrPtr->mode & _show_progress, aPtr->sBuf.seam ) != 0 )
-						{
-							PrintError( "Error merging images. Keeping Source" );
-						}
-					}
-					myfree( (void**)aPtr->pano.data );
-				} // src != 0
-					
-				if( *(aPtr->sBuf.destName) != 0 ) // save buffer image
-				{
-					if( SaveBufImage( TrPtr->dest, aPtr->sBuf.destName ) != 0 )
-						PrintError( "Could not save to Buffer. Most likely your disk is full");
-				}
-			} // Tr.success 
-				
-
-			if( TrPtr->success == 0  && ! (TrPtr->mode & _destSupplied) )	
-				myfree( (void**)TrPtr->dest->data );
-				
-		_insert_exit:
-			if( aPtr->im.format ==_fisheye_circ	&& aPtr->im.cP.cutFrame )	// There is a cropped source image;
-			{
-				if( ImCrop.data != NULL )
-					myfree( (void**) ImCrop.data );
-				TrPtr->src = theSrc;
-			}
-			
-			}
-			break;
-		
-		case _extract:
-				
-			if( aPtr->im.width == 0 )
-			{
-				aPtr->im.width = 500 ;
-			}
-			if(  aPtr->im.height == 0 )
-			{
-				aPtr->im.height = aPtr->im.width * 4 / 5;
-			}
-				
-			// Set pano-params to src-image irrespective of prefs
-			aPtr->pano.width	= TrPtr->src->width;				//	width of panorama
-			aPtr->pano.height	= TrPtr->src->height;				//  height of panorama
-			
-			CopyPosition( TrPtr->src, &(aPtr->pano) );
-//			addAlpha( TrPtr->src ); 
-				
-			if( *(aPtr->sBuf.destName) != 0 ) // save buffer image
-			{
-				if( SaveBufImage( TrPtr->src, aPtr->sBuf.destName ) != 0 )
-					PrintError( "Could not save Buffer Image. Most likely your disk is full");
-			} 
-			
-			// Set up Image Structure in TrPtr struct
-
-
-			destheight 			= aPtr->im.height;
-			destwidth 			= aPtr->im.width;
-
-
-			if( SetDestImage( TrPtr, destwidth, destheight) != 0)
-			{
-				PrintError("Could not allocate %ld bytes",TrPtr->dest->dataSize );
-				TrPtr->success = 0;
-				return;
-			}
-
-			CopyPosition( TrPtr->dest, &(aPtr->im) );
-
-			TrPtr->mode					|= _honor_valid;
-			if( aPtr->pano.hfov == 360.0 )
-				TrPtr->mode				|= _wrapX;
-			
-			aPtr->mode = prefs->mode; // For checkparam
-			ExtractStill( TrPtr,  aPtr );
-				
-				
-			if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied))	
-				myfree( (void**)TrPtr->dest->data );
-			break;
-		
-		case _readControlPoints:
-			{
-				char			*script, *newscript, cdesc[1000];
-				controlPoint 	cp[NUMPTS];			// List of Control points
-
-				script = LoadScript( &(prefs->scriptFile) );
-				if( script != NULL ) 					// We can read the scriptfile
-				{
-					newscript = (char*) malloc( strlen(script) + NUMPTS * 60 ); // One line per pair of points
-					if( newscript != NULL )
-					{
-						readControlPoints( script, cp );		// If this is the second image: get coordinates in first
-						getControlPoints( TrPtr->src, cp );		// Scan image and find control points
-						writeControlPoints( cp, cdesc );		// format control point coordinates
-						
-						sprintf( newscript, "%s\n%s", script, cdesc );
-						
-						if( WriteScript( newscript,&( prefs->scriptFile), 0 ) != 0 )
-										PrintError( "Could not write Scriptfile" );
-						free( newscript );
-					}
-					free( script );
-				}
-
-			}
-			TrPtr->success = 0;							// Don't destroy image!
-			break;
-
-
-		case _runOptimizer:
-			// Run Optimizer; Dummy image needed but not changed
-			{
-				char*				script;
-				OptInfo				opt;
-				AlignInfo			ainf;
-
-				script = LoadScript( &(prefs->scriptFile) );
-				if( script != NULL ) 					// We can read the scriptfile
-				{
-					if (ParseScript( script, &ainf ) == 0)
-					{
-						if( CheckParams( &ainf ) == 0 ) 				// and it seems to make sense
-						{
-							ainf.fcn	= fcnPano;
-							
-							SetGlobalPtr( &ainf ); 
-							
-							opt.numVars 		= g->numParam;
-							opt.numData 		= g->numPts;
-							opt.SetVarsToX		= SetLMParams;
-							opt.SetXToVars		= SetAlignParams;
-							opt.fcn				= g->fcn;
-							*opt.message		= 0;
-
-							RunLMOptimizer( &opt );
-							g->data				= opt.message;
-							WriteResults( script, &(prefs->scriptFile), g, distSquared ,
-							            ( TrPtr->mode & 7 ) != _usedata );
-						}
-						DisposeAlignInfo( &ainf );					// These were allocated by 'ParseScript()'
-					}
-					free( script );
-				}
-			}
-				
-			TrPtr->success = 0;							// Don't destroy Dummy image!
-			break;
-		default:
-			TrPtr->success = 0;							
-			break;
-
-	}
+//                      addAlpha( TrPtr->src ); // Add alpha channel to indicate valid data
+                        
+                        aPtr->mode = prefs->mode; // For checkparam
+                        MakePano( TrPtr,  aPtr );
+                        
+                        if(aPtr->ts) free(aPtr->ts);
+                        if(aPtr->td) free(aPtr->td);
+
+                        // Stitch images; Proceed only if panoramic image valid
+
+                        if( TrPtr->success )
+                        {
+                                if( *(aPtr->sBuf.srcName) != 0 ){ // We have to merge in one images
+                                        // Load the bufferimage
+                                        if( LoadBufImage( &aPtr->pano, aPtr->sBuf.srcName, 1 ) != 0 )
+                                        {
+                                                PrintError( "Could not load buffer %s; Keeping Source",aPtr->sBuf.srcName );
+                                                goto _insert_exit;
+                                        }
+
+                                        if( HaveEqualSize( &aPtr->pano, TrPtr->dest ))
+                                        {
+        
+                                                // At this point we have two valid, equally sized images                                                
+                                                // Do Colour Correction on one or both  images
+                                                DoColorCorrection( TrPtr->dest, &aPtr->pano, aPtr->sBuf.colcorrect & 3);
+                                                
+                                                if( merge( TrPtr->dest , &aPtr->pano, aPtr->sBuf.feather, TrPtr->mode & _show_progress, aPtr->sBuf.seam ) != 0 )
+                                                {
+                                                        PrintError( "Error merging images. Keeping Source" );
+                                                }
+                                        }
+                                        myfree( (void**)aPtr->pano.data );
+                                } // src != 0
+                                        
+                                if( *(aPtr->sBuf.destName) != 0 ) // save buffer image
+                                {
+                                        if( SaveBufImage( TrPtr->dest, aPtr->sBuf.destName ) != 0 )
+                                                PrintError( "Could not save to Buffer. Most likely your disk is full");
+                                }
+                        } // Tr.success 
+                                
+
+                        if( TrPtr->success == 0  && ! (TrPtr->mode & _destSupplied) )   
+                                myfree( (void**)TrPtr->dest->data );
+                                
+                _insert_exit:
+                        if( aPtr->im.format ==_fisheye_circ     && aPtr->im.cP.cutFrame )       // There is a cropped source image;
+                        {
+                                if( ImCrop.data != NULL )
+                                        myfree( (void**) ImCrop.data );
+                                TrPtr->src = theSrc;
+                        }
+                        
+                        }
+                        break;
+                
+                case _extract:
+                                
+                        if( aPtr->im.width == 0 )
+                        {
+                                aPtr->im.width = 500 ;
+                        }
+                        if(  aPtr->im.height == 0 )
+                        {
+                                aPtr->im.height = aPtr->im.width * 4 / 5;
+                        }
+                                
+                        // Set pano-params to src-image irrespective of prefs
+                        aPtr->pano.width        = TrPtr->src->width;                            //      width of panorama
+                        aPtr->pano.height       = TrPtr->src->height;                           //  height of panorama
+                        
+                        CopyPosition( TrPtr->src, &(aPtr->pano) );
+//                      addAlpha( TrPtr->src ); 
+                                
+                        if( *(aPtr->sBuf.destName) != 0 ) // save buffer image
+                        {
+                                if( SaveBufImage( TrPtr->src, aPtr->sBuf.destName ) != 0 )
+                                        PrintError( "Could not save Buffer Image. Most likely your disk is full");
+                        } 
+                        
+                        // Set up Image Structure in TrPtr struct
+
+
+                        destheight                      = aPtr->im.height;
+                        destwidth                       = aPtr->im.width;
+
+
+                        if( SetDestImage( TrPtr, destwidth, destheight) != 0)
+                        {
+                                PrintError("Could not allocate %ld bytes",TrPtr->dest->dataSize );
+                                TrPtr->success = 0;
+                                return;
+                        }
+
+                        CopyPosition( TrPtr->dest, &(aPtr->im) );
+
+                        TrPtr->mode                                     |= _honor_valid;
+                        if( aPtr->pano.hfov == 360.0 )
+                                TrPtr->mode                             |= _wrapX;
+                        
+                        aPtr->mode = prefs->mode; // For checkparam
+                        ExtractStill( TrPtr,  aPtr );
+                                
+                                
+                        if( TrPtr->success == 0 && ! (TrPtr->mode & _destSupplied))     
+                                myfree( (void**)TrPtr->dest->data );
+                        break;
+                
+                case _readControlPoints:
+                        {
+                                char                    *script, *newscript, cdesc[1000];
+                                controlPoint    cp[NUMPTS];                     // List of Control points
+
+                                script = LoadScript( &(prefs->scriptFile) );
+                                if( script != NULL )                                    // We can read the scriptfile
+                                {
+                                        newscript = (char*) malloc( strlen(script) + NUMPTS * 60 ); // One line per pair of points
+                                        if( newscript != NULL )
+                                        {
+                                                readControlPoints( script, cp );                // If this is the second image: get coordinates in first
+                                                getControlPoints( TrPtr->src, cp );             // Scan image and find control points
+                                                writeControlPoints( cp, cdesc );                // format control point coordinates
+                                                
+                                                sprintf( newscript, "%s\n%s", script, cdesc );
+                                                
+                                                if( WriteScript( newscript,&( prefs->scriptFile), 0 ) != 0 )
+                                                                                PrintError( "Could not write Scriptfile" );
+                                                free( newscript );
+                                        }
+                                        free( script );
+                                }
+
+                        }
+                        TrPtr->success = 0;                                                     // Don't destroy image!
+                        break;
+
+
+                case _runOptimizer:
+                        // Run Optimizer; Dummy image needed but not changed
+                        {
+                                char*                           script;
+                                OptInfo                         opt;
+                                AlignInfo                       ainf;
+
+                                script = LoadScript( &(prefs->scriptFile) );
+                                if( script != NULL )                                    // We can read the scriptfile
+                                {
+                                        if (ParseScript( script, &ainf ) == 0)
+                                        {
+                                                if( CheckParams( &ainf ) == 0 )                                 // and it seems to make sense
+                                                {
+                                                        ainf.fcn        = fcnPano;
+                                                        
+                                                        // optInfo is a static variable that is used in all optimizations
+                                                        SetGlobalPtr( &ainf ); // equivalent to optInfo = &ainf;
+                                                        
+                                                        opt.numVars             = optInfo->numParam;
+                                                        opt.numData             = optInfo->numPts;
+                                                        opt.SetVarsToX          = SetLMParams;
+                                                        opt.SetXToVars          = SetAlignParams;
+                                                        opt.fcn                 = optInfo->fcn;
+                                                        *opt.message            = 0;
+                                                        RunLMOptimizer( &opt );
+                                                        optInfo->data                           = opt.message;
+                                                        WriteResults( script, &(prefs->scriptFile), optInfo, distSquared ,
+                                                                    ( TrPtr->mode & 7 ) != _usedata );
+                                                }
+                                                DisposeAlignInfo( &ainf );                                      // These were allocated by 'ParseScript()'
+                                        }
+                                        free( script );
+                                }
+                        }
+                                
+                        TrPtr->success = 0;                                                     // Don't destroy Dummy image!
+                        break;
+                default:
+                        TrPtr->success = 0;                                                     
+                        break;
+
+        }
 }
 
 
@@ -450,7 +484,7 @@
 
 void MakePano( TrformStr *TrPtr, aPrefs *aP )
 {
-	MyMakePano( TrPtr, aP, 1 );
+        MyMakePano( TrPtr, aP, 1 );
 }
 
 
@@ -459,63 +493,63 @@
 of the image that has to be converted.*/
 void MyMakePano( TrformStr *TrPtr, aPrefs *aP, int imageNum )
 {
-	struct 	MakeParams	mp,mpinv;
-	fDesc        stack[15], fD;		// Parameters for execute 
-	fDesc        invstack[15], finvD;		// Invers Parameters for execute 
-	void	*morph[3];	
-
-	int 	i,k, kstart, kend, color;
-
-	TrPtr->success = 1;
-	
-	if( CheckMakeParams( aP) != 0)
-	{
-		TrPtr->success = 0;
-		return;
-	}
-
-
-	if(  isColorSpecific( &(aP->im.cP) ) )			// Color dependent
-	{
-		kstart 	= 1; kend	= 4;
-	}
-	else 											// Color independent
-	{
-		kstart	= 0; kend	= 1;
-	}
-				
-	for( k = kstart; k < kend; k++ )
-	{
-		color = k-1; if( color < 0 ) color = 0;
-		SetMakeParams( stack, &mp, &(aP->im) , &(aP->pano), color );
-		SetInvMakeParamsCorrect( invstack, &mpinv, &(aP->im) , &(aP->pano), color );
-		
-		if( aP->nt > 0 )	// Morphing requested
-		{
-			morph[0] = (void*)aP->td;
-			morph[1] = (void*)aP->ts;
-			morph[2] = (void*)&aP->nt;
-
-			i=0; while( stack[i].func != NULL && i<14 ) i++;
-			if( i!=14 )
-			{
-				for(i=14; i>0; i--)
-				{
-					memcpy( &stack[i], &stack[i-1], sizeof( fDesc ));
-				}
-				stack[0].func 		= tmorph;
-				stack[0].param 		= (void*)morph;
-			}
-		}
-
-		if( TrPtr->success != 0)
-		{
-			fD.func = execute_stack_new; fD.param = stack;
-			finvD.func = execute_stack_new; finvD.param = invstack;
-
-			transFormEx( TrPtr,  &fD , &finvD , k, imageNum );
-		}
-	}
+        struct  MakeParams      mp,mpinv;
+        fDesc        stack[15], fD;             // Parameters for execute 
+        fDesc        invstack[15], finvD;               // Invers Parameters for execute 
+        void    *morph[3];      
+
+        int     i,k, kstart, kend, color;
+
+        TrPtr->success = 1;
+        
+        if( CheckMakeParams( aP) != 0)
+        {
+                TrPtr->success = 0;
+                return;
+        }
+
+
+        if(  isColorSpecific( &(aP->im.cP) ) )                  // Color dependent
+        {
+                kstart  = 1; kend       = 4;
+        }
+        else                                                                                    // Color independent
+        {
+                kstart  = 0; kend       = 1;
+        }
+                                
+        for( k = kstart; k < kend; k++ )
+        {
+                color = k-1; if( color < 0 ) color = 0;
+                SetMakeParams( stack, &mp, &(aP->im) , &(aP->pano), color );
+                SetInvMakeParamsCorrect( invstack, &mpinv, &(aP->im) , &(aP->pano), color );
+                
+                if( aP->nt > 0 )        // Morphing requested
+                {
+                        morph[0] = (void*)aP->td;
+                        morph[1] = (void*)aP->ts;
+                        morph[2] = (void*)&aP->nt;
+
+                        i=0; while( stack[i].func != NULL && i<14 ) i++;
+                        if( i!=14 )
+                        {
+                                for(i=14; i>0; i--)
+                                {
+                                        memcpy( &stack[i], &stack[i-1], sizeof( fDesc ));
+                                }
+                                stack[0].func           = tmorph;
+                                stack[0].param          = (void*)morph;
+                        }
+                }
+
+                if( TrPtr->success != 0)
+                {
+                        fD.func = execute_stack_new; fD.param = stack;
+                        finvD.func = execute_stack_new; finvD.param = invstack;
+
+                        transFormEx( TrPtr,  &fD , &finvD , k, imageNum );
+                }
+        }
 }
 
 // Extract image from pano in TrPtr->src 
@@ -524,43 +558,43 @@
 
 void ExtractStill( TrformStr *TrPtr , aPrefs *aP )
 {
-	struct 	MakeParams	mp,mpinv;
-	fDesc 	stack[15], fD;		// Parameters for execute 
-	fDesc 	stackinv[15], fDinv;		// Invers Parameters for execute 
-
-	int 	k, kstart, kend, color;
-
-	TrPtr->success = 1;
-
-	if( CheckMakeParams( aP) != 0)
-	{
-		TrPtr->success = 0;
-		return;
-	}
-		
-
-	if( isColorSpecific( &(aP->im.cP) ) )			// Color dependent
-	{
-		kstart 	= 1; kend	= 4;
-	}
-	else 															// Color independent
-	{
-		kstart	= 0; kend	= 1;
-	}
-				
-	for( k = kstart; k < kend; k++ )
-	{
-		color = k-1; if( color < 0 ) color = 0;
-		SetInvMakeParamsCorrect( stack, &mp, &(aP->im), &(aP->pano), color );
-		SetMakeParams( stackinv, &mpinv, &(aP->im), &(aP->pano), color );
-		
-		if( TrPtr->success != 0)
-		{
-			fD.func = execute_stack_new; fD.param = stack;
-			fDinv.func = execute_stack_new; fDinv.param = stackinv;
-			transFormEx( TrPtr, &fD, &fDinv, k, 1 );
-		}
-	}
+        struct  MakeParams      mp,mpinv;
+        fDesc   stack[15], fD;          // Parameters for execute 
+        fDesc   stackinv[15], fDinv;            // Invers Parameters for execute 
+
+        int     k, kstart, kend, color;
+
+        TrPtr->success = 1;
+
+        if( CheckMakeParams( aP) != 0)
+        {
+                TrPtr->success = 0;
+                return;
+        }
+                
+
+        if( isColorSpecific( &(aP->im.cP) ) )                   // Color dependent
+        {
+                kstart  = 1; kend       = 4;
+        }
+        else                                                                                                                    // Color independent
+        {
+                kstart  = 0; kend       = 1;
+        }
+                                
+        for( k = kstart; k < kend; k++ )
+        {
+                color = k-1; if( color < 0 ) color = 0;
+                SetInvMakeParamsCorrect( stack, &mp, &(aP->im), &(aP->pano), color );
+                SetMakeParams( stackinv, &mpinv, &(aP->im), &(aP->pano), color );
+                
+                if( TrPtr->success != 0)
+                {
+                        fD.func = execute_stack_new; fD.param = stack;
+                        fDinv.func = execute_stack_new; fDinv.param = stackinv;
+                        transFormEx( TrPtr, &fD, &fDinv, k, 1 );
+                }
+        }
 }
 
 
@@ -734,12 +768,12 @@
     case _orthographic:
       mp->distance  = (double) pn->width / (2.0 * sin(b/2.0));
        break;
-	case _biplane:
-	  biplane_distance(pn->width,b,mp);
-	  break;
-	case _triplane:
-	  triplane_distance(pn->width,b,mp);
-	  break;
+        case _biplane:
+          biplane_distance(pn->width,b,mp);
+          break;
+        case _triplane:
+          triplane_distance(pn->width,b,mp);
+          break;
     default:
       // unknown
       PrintError ("SetMakeParams: Unsupported panorama projection");
@@ -789,277 +823,235 @@
     mp->rot[0]      = mp->distance * PI;                                // 180 in screenpoints
     mp->rot[1]      = -im->yaw *  mp->distance * PI / 180.0;            // rotation angle in screenpoints
     
-#ifdef MOSAIC_XYZ
-    mp->tilt[0] = im->cP.tilt_x;
-    mp->tilt[1] = im->cP.tilt_y;
-    mp->tilt[2] = im->cP.tilt_z;
-    mp->tilt[3] = im->cP.tilt_scale;
-#else
     mp->tilt[0] = DEG_TO_RAD(im->cP.tilt_x);
     mp->tilt[1] = DEG_TO_RAD(im->cP.tilt_y);
     mp->tilt[2] = DEG_TO_RAD(im->cP.tilt_z);
     mp->tilt[3] = im->cP.tilt_scale;
-#endif
-
-    /*
-    printf("Image format %d\n", (int)(im->format));
-    printf("distnace %f\n", mp->distance);
-    printf("shear[0] %f\n", mp->shear[0]);
-    printf("shear[1] %f\n", mp->shear[1]);
-    printf("rot[0] %f\n", mp->rot[0]);
-    printf("rot[1] %f\n", mp->rot[1]);
-    printf("tilt[0] %f\n",    mp->tilt[0]);
-    printf("tilt[1] %f\n",    mp->tilt[1]);
-    printf("tilt[2] %f\n",    mp->tilt[2]);
-    printf("tilt[3] %f\n",    mp->tilt[3]);
-
-    printf("mp->horizontal %f\n", mp->horizontal);
-    printf("mp->vertical %f\n", mp->vertical);
-  printf(">>>im->cP.shear %d\n", im->cP.shear);
-  printf(">>>im->cP.tilt %d\n", im->cP.tilt);
-    */
+
+    mp->trans[0] = im->cP.trans_x;
+    mp->trans[1] = im->cP.trans_y;
+    mp->trans[2] = im->cP.trans_z;
+
+
+    mp->test[0] = im->cP.test_p0;
+    mp->test[1] = im->cP.test_p1;
+    mp->test[2] = im->cP.test_p2;
+    mp->test[3] = im->cP.test_p3;
+
+    //    panoAdjustPrintMakeParams("SetmakeParms", mp, im);
+
     mp->perspect[0] = (void*)(mp->mt);
     mp->perspect[1] = (void*)&(mp->distance);
             
     for(i=0; i<4; i++)
-      mp->rad[i]  = im->cP.radial_params[color][i];
+        mp->rad[i]  = im->cP.radial_params[color][i];
     mp->rad[5] = im->cP.radial_params[color][4];
 
     if( (im->cP.correction_mode & 3) == correction_mode_radial )
-      mp->rad[4]  = ( (double)( image_selection_width < image_selection_height ? image_selection_width : image_selection_height) ) / 2.0;
+        mp->rad[4]  = ( (double)( image_selection_width < image_selection_height ? image_selection_width : image_selection_height) ) / 2.0;
     else
-      mp->rad[4]  = ((double) image_selection_height) / 2.0;
-
-// Joost: removed, see above
-//  mp->horizontal  = im->cP.horizontal_params[color];
-//  mp->vertical  = im->cP.vertical_params[color];
+        mp->rad[4]  = ((double) image_selection_height) / 2.0;
+
+    // Joost: removed, see above
+    //  mp->horizontal  = im->cP.horizontal_params[color];
+    //  mp->vertical  = im->cP.vertical_params[color];
 
     i = 0;
 
     if(pn->format == _rectilinear)                                  // rectilinear panorama
-    {
-      SetDesc(stack[i],   erect_rect,             &(mp->distance) ); i++;   // Convert rectilinear to equirect
+        {
+            SetDesc(stack[i],   erect_rect,             &(mp->distance) ); i++;   // Convert rectilinear to equirect
+        }
+    else if(pn->format == _panorama)
+        {
+            SetDesc(stack[i],   erect_pano,             &(mp->distance) ); i++;   // Convert panoramic to equirect
+        }
+    else if(pn->format == _fisheye_circ || pn->format == _fisheye_ff)
+        {
+            SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert fisheye to equirect
+        }
+    else if(pn->format == _equisolid)
+        {
+            SetDesc(stack[i],   sphere_tp_equisolid,    &(mp->distance) ); i++; // Convert fisheye equisolid to spherical
+            SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert spherical to equirect
+        }
+    else if(pn->format == _mirror)
+        {
+            SetDesc(stack[i],   sphere_cp_mirror,       &(mp->distance) ); i++; // Convert mirror to spherical
+            SetDesc(stack[i],   erect_sphere_cp,        &(mp->distance) ); i++; // Convert spherical to equirect
+        }
+    else if(pn->format == _orthographic)
+        {
+            SetDesc(stack[i],   sphere_tp_orthographic, &(mp->distance) ); i++; // Convert fisheye orthographic to spherical
+            SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert spherical to equirect
+        }
+    else if(pn->format == _mercator)
+        {
+            SetDesc(stack[i],   erect_mercator,         &(mp->distance) ); i++; // Convert mercator to equirect
+        }
+    else if(pn->format == _millercylindrical)
+        {
+            SetDesc(stack[i],   erect_millercylindrical, &(mp->distance) ); i++; // Convert miller to equirect
+        }
+    else if(pn->format == _panini)
+        {
+            SetDesc(stack[i],     erect_panini,           &(mp->distance) ); i++; // Convert panini to sphere
+        }
+    else if(pn->format == _equipanini)
+        {
+            SetDesc(stack[i],     erect_equipanini,           &(mp->distance) ); i++; // Convert equipanini to sphere
+        }
+    else if(pn->format == _architectural)
+        {
+            SetDesc(stack[i],   erect_arch,             &(mp->distance) ); i++; // Convert arch to sphere
+        }
+    else if(pn->format == _lambert)
+        {
+            SetDesc(stack[i],   erect_lambert,          &(mp->distance) ); i++; // Convert lambert to equirect
+        }
+    else if(pn->format == _lambertazimuthal)
+        {
+            SetDesc(stack[i],   erect_lambertazimuthal, &(mp->distance) ); i++; // Convert lambert to equirect
+        }
+    else if(pn->format == _trans_mercator)
+        {
+            SetDesc(stack[i],   erect_transmercator,    &(mp->distance)  ); i++; // Convert transverse mercator to equirect
+        }
+    else if(pn->format == _stereographic)
+        {
+            SetDesc(stack[i],   erect_stereographic,    &(mp->distance) ); i++;  // Convert stereographic to equirect
+        }
+    else if(pn->format == _sinusoidal)
+        {
+            SetDesc(stack[i],   erect_sinusoidal,       &(mp->distance) ); i++; // Convert sinusoidal to equirect
+        }
+    else if(pn->format == _albersequalareaconic)
+        {
+            SetDesc(stack[i],   erect_albersequalareaconic,     mp  ); i++; // Convert albersequalareaconic to equirect
+        }
+    else if(pn->format == _biplane)
+        {
+            SetDesc(stack[i], erect_biplane, mp ); i++;  // Convert biplane to equirect
+        }
+    else if(pn->format == _triplane)
+        {
+            SetDesc(stack[i], erect_triplane, mp ); i++;  // Convert triplane to equirect
+        }
+    else if(pn->format == _equirectangular) 
+        {
+            // no conversion needed     
+        } else {
+        PrintError("Projection type %d not supported, using equirectangular", pn->format);
     }
-    else if(pn->format == _panorama)
-    {
-      SetDesc(stack[i],   erect_pano,             &(mp->distance) ); i++;   // Convert panoramic to equirect
-    }
-    else if(pn->format == _fisheye_circ || pn->format == _fisheye_ff)
-    {
-      SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert fisheye to equirect
-    }
-    else if(pn->format == _equisolid)
-    {
-      SetDesc(stack[i],   sphere_tp_equisolid,    &(mp->distance) ); i++; // Convert fisheye equisolid to spherical
-      SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert spherical to equirect
-    }
-    else if(pn->format == _mirror)
-    {
-      SetDesc(stack[i],   sphere_cp_mirror,       &(mp->distance) ); i++; // Convert mirror to spherical
-      SetDesc(stack[i],   erect_sphere_cp,        &(mp->distance) ); i++; // Convert spherical to equirect
-    }
-    else if(pn->format == _orthographic)
-    {
-      SetDesc(stack[i],   sphere_tp_orthographic, &(mp->distance) ); i++; // Convert fisheye orthographic to spherical
-      SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert spherical to equirect
-    }
-    else if(pn->format == _mercator)
-    {
-      SetDesc(stack[i],   erect_mercator,         &(mp->distance) ); i++; // Convert mercator to equirect
-    }
-    else if(pn->format == _millercylindrical)
-    {
-      SetDesc(stack[i],   erect_millercylindrical, &(mp->distance) ); i++; // Convert miller to equirect
-    }
-    else if(pn->format == _panini)
-    {
-    SetDesc(stack[i],     erect_panini,           &(mp->distance) ); i++; // Convert panini to sphere
-    }
-    else if(pn->format == _equipanini)
-    {
-    SetDesc(stack[i],     erect_equipanini,           &(mp->distance) ); i++; // Convert equipanini to sphere
-    }
-    else if(pn->format == _architectural)
-    {
-      SetDesc(stack[i],   erect_arch,             &(mp->distance) ); i++; // Convert arch to sphere
-    }
-    else if(pn->format == _lambert)
-    {
-      SetDesc(stack[i],   erect_lambert,          &(mp->distance) ); i++; // Convert lambert to equirect
-    }
-    else if(pn->format == _lambertazimuthal)
-    {
-      SetDesc(stack[i],   erect_lambertazimuthal, &(mp->distance) ); i++; // Convert lambert to equirect
-    }
-    else if(pn->format == _trans_mercator)
-    {
-      SetDesc(stack[i],   erect_transmercator,    &(mp->distance)  ); i++; // Convert transverse mercator to equirect
-    }
-    else if(pn->format == _stereographic)
-    {
-      SetDesc(stack[i],   erect_stereographic,    &(mp->distance) ); i++;  // Convert stereographic to equirect
-    }
-    else if(pn->format == _sinusoidal)
-    {
-      SetDesc(stack[i],   erect_sinusoidal,       &(mp->distance) ); i++; // Convert sinusoidal to equirect
-    }
-    else if(pn->format == _albersequalareaconic)
-    {
-      SetDesc(stack[i],   erect_albersequalareaconic,     mp  ); i++; // Convert albersequalareaconic to equirect
-    }
-    else if(pn->format == _biplane)
-    {
-      SetDesc(stack[i], erect_biplane, mp ); i++;  // Convert biplane to equirect
-    }
-    else if(pn->format == _triplane)
-    {
-      SetDesc(stack[i], erect_triplane, mp ); i++;  // Convert triplane to equirect
-    }
-    else if(pn->format == _equirectangular) 
-    {
-      // no conversion needed     
-    } else {
-      PrintError("Projection type %d not supported, using equirectangular", pn->format);
-    }
-
-#ifdef MOSAIC_XYZ
-    if (im->cP.tilt) {
-      SetDesc(stack[i], plane_transfer_to_camera, mp);   i++;
+
+    if (im->cP.trans) {
+        SetDesc(stack[i], plane_transfer_to_camera, mp);   i++;
     }    
-#endif
-    // 
 
     SetDesc(  stack[i],   rotate_erect,           mp->rot         ); i++; // Rotate equirect. image horizontally
     SetDesc(  stack[i],   sphere_tp_erect,        &(mp->distance) ); i++; // Convert spherical image to equirect.
     SetDesc(  stack[i],   persp_sphere,           mp->perspect    ); i++; // Perspective Control spherical Image
 
     if(im->format      == _rectilinear)                                    // rectilinear image
-    {
-      SetDesc(stack[i],   rect_sphere_tp,         &(mp->distance) ); i++; // Convert rectilinear to spherical
+        {
+            SetDesc(stack[i],   rect_sphere_tp,         &(mp->distance) ); i++; // Convert rectilinear to spherical
+        }
+    else if(im->format == _panorama)                                   //  pamoramic image
+        {
+            SetDesc(stack[i],   pano_sphere_tp,         &(mp->distance) ); i++; // Convert panoramic to spherical
+        }
+    else if(im->format == _equirectangular)                            //  equirectangular image
+        {
+            SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert equirectangular to spherical
+        }
+
+    SetDesc(  stack[i],   resize,                 mp->scale       ); i++; // Scale image
+
+    if( im->cP.radial )
+        {
+            switch( im->cP.correction_mode & 3 )
+                {
+                case correction_mode_radial:    SetDesc(stack[i],radial,mp->rad);     i++; break;
+                case correction_mode_vertical:  SetDesc(stack[i],vertical,mp->rad);   i++; break;
+                case correction_mode_deregister:SetDesc(stack[i],deregister,mp->rad); i++; break;
+                }
+        }
+    if (im->cP.tilt) {
+        SetDesc(stack[i],   tiltInverse,                   mp);   i++;
     }
-    else if(im->format == _panorama)                                   //  pamoramic image
-    {
-      SetDesc(stack[i],   pano_sphere_tp,         &(mp->distance) ); i++; // Convert panoramic to spherical
-    }
-    else if(im->format == _equirectangular)                            //  equirectangular image
-    {
-      SetDesc(stack[i],   erect_sphere_tp,        &(mp->distance) ); i++; // Convert equirectangular to spherical
-    }
-
-    SetDesc(  stack[i],   resize,                 mp->scale       ); i++; // Scale image
-
-    if( im->cP.radial )
-    {
-      switch( im->cP.correction_mode & 3 )
-      {
-        case correction_mode_radial:    SetDesc(stack[i],radial,mp->rad);     i++; break;
-        case correction_mode_vertical:  SetDesc(stack[i],vertical,mp->rad);   i++; break;
-        case correction_mode_deregister:SetDesc(stack[i],deregister,mp->rad); i++; break;
-      }
-    }
-#ifndef MOSAIC_XYZ
-    if (im->cP.tilt) {
-      SetDesc(stack[i],   tiltInverse,                   mp);   i++;
-    }
-#endif
 
     if (mp->vertical != 0.0)
-    {
-      SetDesc(stack[i],   vert,                   &(mp->vertical));   i++;
-    }
+        {
+            SetDesc(stack[i],   vert,                   &(mp->vertical));   i++;
+        }
     if (mp->horizontal != 0.0)
-    {
-      SetDesc(stack[i],   horiz,                  &(mp->horizontal)); i++;
-    }
+        {
+            SetDesc(stack[i],   horiz,                  &(mp->horizontal)); i++;
+        }
     if( im->cP.shear )
-    {
-      SetDesc( stack[i],  shear,                  mp->shear       ); i++;
-    }
+        {
+            SetDesc( stack[i],  shear,                  mp->shear       ); i++;
+        }
 
     stack[i].func  = (trfn)NULL;
 
-// print stack for debugging
+    // print stack for debugging
 #if 0
     printf( "Rotate params: %lg  %lg\n" , mp->rot[0], mp->rot[1]);
     printf( "Distance     : %lg\n" , mp->distance);
     printf( "Perspect params: %lg  %lg  %lg\n",a, beta , gammar );      
     if(aP->format       == _rectilinear)                                    // rectilinear image
-    {
-      printf( "Rectilinear\n" );      
-    }
+        {
+            printf( "Rectilinear\n" );      
+        }
     else if (aP->format     == _panorama)                                   //  pamoramic image
-    {
-      printf( "Panorama\n" );
-    }
+        {
+            printf( "Panorama\n" );
+        }
     else
-    {
-      printf( "Fisheye\n" );      
-    }
+        {
+            printf( "Fisheye\n" );      
+        }
 
     printf( "Scaling     : %lg\n" , mp->scale[0]);
 
     if(  aP->correct )
-    {
-      printf( "Correct:\n" );     
-      if( aP->c_prefs.tilt )
-      {
-        printf( "Tilt: %lg\n", mp->tilt );    
-      }
-      if( aP->c_prefs.shear )
-      {
-        printf( "Shear: %lg\n", mp->shear );    
-      }
-      if ( aP->c_prefs.horizontal )
-      {
-        printf( "horiz:%lg\n", mp->horizontal );  
-      }
-      if (  aP->c_prefs.vertical)
-      {
-        printf( "vert:%lg\n", mp->vertical );  
-      }
-      if( aP->c_prefs.radial )
-      {
-        printf( "Polynomial:\n" );      
-        if( aP->c_prefs.isScanningSlit )
-        {
-          printf( "Scanning Slit:\n" );   
-        }
-        else
-        {
-          printf( "Radial:\n" );      
-          printf( "Params: %lg %lg %lg %lg %lg\n", mp->rad[0],mp->rad[1],mp->rad[2],mp->rad[3],mp->rad[4] );      
-        }
-      }
-    }
+        {
+            printf( "Correct:\n" );     
+            if( aP->c_prefs.tilt )
+                {
+                    printf( "Tilt: %lg\n", mp->tilt );    
+                }
+            if( aP->c_prefs.shear )
+                {
+                    printf( "Shear: %lg\n", mp->shear );    
+                }
+            if ( aP->c_prefs.horizontal )
+                {
+                    printf( "horiz:%lg\n", mp->horizontal );  
+                }
+            if (  aP->c_prefs.vertical)
+                {
+                    printf( "vert:%lg\n", mp->vertical );  
+                }
+            if( aP->c_prefs.radial )
+                {
+                    printf( "Polynomial:\n" );      
+                    if( aP->c_prefs.isScanningSlit )
+                        {
+                            printf( "Scanning Slit:\n" );   
+                        }
+                    else
+                        {
+                            printf( "Radial:\n" );      
+                            printf( "Params: %lg %lg %lg %lg %lg\n", mp->rad[0],mp->rad[1],mp->rad[2],mp->rad[3],mp->rad[4] );      
+                        }
+                }
+        }
 
 #endif
 }
 
-void PrintMakeParams(char *msg, struct MakeParams *mp, Image *im)
-{
-  printf("-------------%s\n", msg);
-  printf("distnace %f\n", mp->distance);
-  printf("shear[0] %f\n", mp->shear[0]);
-  printf("shear[1] %f\n", mp->shear[1]);
-    printf("rot[0] %f\n", mp->rot[0]);
-    printf("rot[1] %f\n", mp->rot[1]);
-  printf("tilt[0] %f\n", mp->tilt[0]);
-  printf("tilt[1] %f\n", mp->tilt[1]);
-  printf("tilt[2] %f\n", mp->tilt[2]);
-  printf("tilt[3] %f\n", mp->tilt[3]);
-
-  printf("mp->horizontal %f\n", mp->horizontal);
-  printf("mp->vertical %f\n", mp->vertical);
-  printf(">>>Image format %d\n", (int)im->format);
-  printf(">>>im->cP.shear %d\n", im->cP.shear);
-  printf(">>>im->cP.tilt %d\n", im->cP.tilt);
-  printf(">>>im->cP.tilt_x %f\n", im->cP.tilt_x);
-  printf(">>>im->cP.tilt_y %f\n", im->cP.tilt_y);
-  printf(">>>im->cP.tilt_z %f\n", im->cP.tilt_z);
-  printf(">>>im->cP.tilt_scale %f\n", im->cP.tilt_scale);
-
-
-}
 
 
 // Set inverse Makeparameters depending on adjustprefs, color and source image
@@ -1067,146 +1059,148 @@
 void  SetInvMakeParams( struct fDesc *stack, struct MakeParams *mp, Image *im , Image *pn, int color )
 {
 
-  int     i;
-  double    a,b;              // field of view in rad
-  double      tx,ty,tpara;
-
-  a =  DEG_TO_RAD( im->hfov );  // field of view in rad   
-  b =  DEG_TO_RAD( pn->hfov );
-
-
-  mp->im = im;
-  mp->pn = pn;
-  SetMatrix( DEG_TO_RAD( im->pitch ), 
-             0.0, 
-             DEG_TO_RAD( im->roll ), 
-             mp->mt, 
-             1 );
-
-  // dangelo: added mercator, sinusoidal and stereographic projection
-  switch (pn->format)
-    {
-    case _rectilinear:
-      mp->distance        = (double) pn->width / (2.0 * tan(b/2.0));
-      break;
-    case _equirectangular:
-    case _fisheye_ff:
-    case _fisheye_circ:
-    case _panorama:
-    case _lambert:
-    case _mercator:
-    case _millercylindrical:
-    case _sinusoidal:
-    case _mirror:
-      // horizontal pixels per rads
-      mp->distance        = ((double) pn->width) / b;
-      break;
-    case _lambertazimuthal:
-      tpara = 1;
-      lambertazimuthal_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _panini:
-      tpara = 1;
-      panini_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _equipanini:
-      tpara = 1;
-      equipanini_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _architectural:
-      tpara = 1;
-      arch_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _stereographic:
-      tpara = 1;
-      stereographic_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _trans_mercator:
-      tpara = 1;
-      transmercator_erect(b/2.0, 0.0, &tx, &ty, & tpara);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _albersequalareaconic:
-      mp->distance = 1.0;
-      //albersequalareaconic_erect(1.924913116, -PI/2.0, &tx, &ty, mp);  //b/2.0
-      albersequalareaconic_distance(&tx, mp);
-      mp->distance = pn->width/(2.0*tx);
-      break;
-    case _equisolid:
-      mp->distance  = (double) pn->width / (4.0 * sin(b/4.0));
-      break;
-    case _orthographic:
-      mp->distance  = (double) pn->width / (2.0 * sin(b/2.0));
-      break;
-    case _biplane:
-      biplane_distance(pn->width,b,mp);
-      break;
-    case _triplane:
-      triplane_distance(pn->width,b,mp);
-      break;    default:
-      // unknown
-      PrintError ("SetInvMakeParams: Unsupported panorama projection");
-      // no way to report an error back to the caller...
-      mp->distance = 1;
-      break;
-    }
-
-  // calculate final scaling factor, that reverses the mp->distance
-  // scaling and applies the required output scaling factor
-  switch (im->format)
-    {
-    case _rectilinear:
-      // calculate distance for this projection
-      mp->scale[0] = (double) im->width / (2.0 * tan(a/2.0)) / mp->distance;
-      break;
-    case _equirectangular:
-    case _panorama:
-    case _fisheye_ff:
-    case _fisheye_circ:
-    case _mercator:
-    case _sinusoidal:
-      mp->scale[0] = ((double) im->width) / a / mp->distance;
-      break;
-    case _equisolid:
-    case _mirror:
-      mp->scale[0] = (double) im->width / (4.0 * sin(a/4.0)) / mp->distance;
-      break;
-    case _orthographic:
-      mp->scale[0] = (double) im->width / (2.0 * sin(a/2.0)) / mp->distance;
-      break;
-    case _stereographic:
-      mp->scale[0] = (double) im->width / (4.0 * tan(a/4.0)) / mp->distance;
-      break;
-    default:
-      PrintError ("SetInvMakeParams: Unsupported input image projection");
-      // no way to report an error back to the caller...
-      mp->scale[0] = 1;
-      break;
-    }
-  mp->scale[1]    = mp->scale[0];
-
-  mp->shear[0]  = im->cP.shear_x / im->height;
-  mp->shear[1]  = im->cP.shear_y / im->width;
+    int     i;
+    double    a,b;              // field of view in rad
+    double      tx,ty,tpara;
+
+    a =  DEG_TO_RAD( im->hfov );  // field of view in rad   
+    b =  DEG_TO_RAD( pn->hfov );
+
+    mp->im = im;
+    mp->pn = pn;
+
+    SetMatrix( DEG_TO_RAD( im->pitch ), 
+               0.0, 
+               DEG_TO_RAD( im->roll ), 
+               mp->mt, 
+               1 );
+
+    // dangelo: added mercator, sinusoidal and stereographic projection
+    switch (pn->format)
+        {
+        case _rectilinear:
+            mp->distance        = (double) pn->width / (2.0 * tan(b/2.0));
+            break;
+        case _equirectangular:
+        case _fisheye_ff:
+        case _fisheye_circ:
+        case _panorama:
+        case _lambert:
+        case _mercator:
+        case _millercylindrical:
+        case _sinusoidal:
+        case _mirror:
+            // horizontal pixels per rads
+            mp->distance        = ((double) pn->width) / b;
+            break;
+        case _lambertazimuthal:
+            tpara = 1;
+            lambertazimuthal_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _panini:
+            tpara = 1;
+            panini_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _equipanini:
+            tpara = 1;
+            equipanini_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _architectural:
+            tpara = 1;
+            arch_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _stereographic:
+            tpara = 1;
+            stereographic_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _trans_mercator:
+            tpara = 1;
+            transmercator_erect(b/2.0, 0.0, &tx, &ty, & tpara);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _albersequalareaconic:
+            mp->distance = 1.0;
+            //albersequalareaconic_erect(1.924913116, -PI/2.0, &tx, &ty, mp);  //b/2.0
+            albersequalareaconic_distance(&tx, mp);
+            mp->distance = pn->width/(2.0*tx);
+            break;
+        case _equisolid:
+            mp->distance  = (double) pn->width / (4.0 * sin(b/4.0));
+            break;
+        case _orthographic:
+            mp->distance  = (double) pn->width / (2.0 * sin(b/2.0));
+            break;
+        case _biplane:
+            biplane_distance(pn->width,b,mp);
+            break;
+        case _triplane:
+            triplane_distance(pn->width,b,mp);
+            break;    default:
+            // unknown
+            PrintError ("SetInvMakeParams: Unsupported panorama projection");
+            // no way to report an error back to the caller...
+            mp->distance = 1;
+            break;
+        }
+
+    // calculate final scaling factor, that reverses the mp->distance
+    // scaling and applies the required output scaling factor
+    switch (im->format)
+        {
+        case _rectilinear:
+            // calculate distance for this projection
+            mp->scale[0] = (double) im->width / (2.0 * tan(a/2.0)) / mp->distance;
+            break;
+        case _equirectangular:
+        case _panorama:
+        case _fisheye_ff:
+        case _fisheye_circ:
+        case _mercator:
+        case _sinusoidal:
+            mp->scale[0] = ((double) im->width) / a / mp->distance;
+            break;
+        case _equisolid:
+        case _mirror:
+            mp->scale[0] = (double) im->width / (4.0 * sin(a/4.0)) / mp->distance;
+            break;
+        case _orthographic:
+            mp->scale[0] = (double) im->width / (2.0 * sin(a/2.0)) / mp->distance;
+            break;
+        case _stereographic:
+            mp->scale[0] = (double) im->width / (4.0 * tan(a/4.0)) / mp->distance;
+            break;
+        default:
+            PrintError ("SetInvMakeParams: Unsupported input image projection");
+            // no way to report an error back to the caller...
+            mp->scale[0] = 1;
+            break;
+        }
+    mp->scale[1]    = mp->scale[0];
+
+    mp->shear[0]  = im->cP.shear_x / im->height;
+    mp->shear[1]  = im->cP.shear_y / im->width;
   
-  //PrintMakeParams("Inverse 10", mp,im);
-#ifdef MOSAIC_XYZ
-  mp->tilt[0] = im->cP.tilt_x;
-  mp->tilt[1] = im->cP.tilt_y;
-  mp->tilt[2] = im->cP.tilt_z;
-  mp->tilt[3] = im->cP.tilt_scale;
-#else
+
   mp->tilt[0] = DEG_TO_RAD(im->cP.tilt_x);
   mp->tilt[1] = DEG_TO_RAD(im->cP.tilt_y);
   mp->tilt[2] = DEG_TO_RAD(im->cP.tilt_z);
   mp->tilt[3] = im->cP.tilt_scale;
-#endif
-
-  //  PrintMakeParams("Inverse 20",mp,im);
+  
+  mp->trans[0] = im->cP.trans_x;
+  mp->trans[1] = im->cP.trans_y;
+  mp->trans[2] = im->cP.trans_z;
+
+  mp->test[0] = im->cP.test_p0;
+  mp->test[1] = im->cP.test_p1;
+  mp->test[2] = im->cP.test_p2;
+  mp->test[3] = im->cP.test_p3;
+
+  //  panoAdjustPrintMakeParams("Inverse 20",mp,im);
 
   mp->scale[0] = 1.0 / mp->scale[0];
   mp->scale[1]  = mp->scale[0];
@@ -1229,7 +1223,7 @@
   mp->perspect[0] = (void*)(mp->mt);
   mp->perspect[1] = (void*)&(mp->distance);
 
-  //  PrintMakeParams("Invert 30",mp,im);
+  //  panoAdjustPrintMakeParams("Invert 30",mp,im);
 
   i = 0;  // Stack counter
     
@@ -1249,12 +1243,10 @@
     SetDesc(stack[i],vert,        &(mp->vertical));   i++;
   }
 
-#ifndef MOSAIC_XYZ
   if( im->cP.tilt )
   {
     SetDesc( stack[i],tiltForward,      mp   ); i++;
   }
-#endif
 
   // Perform radial correction
 
@@ -1304,12 +1296,10 @@
   SetDesc(  stack[i], erect_sphere_tp,  &(mp->distance) ); i++; // Convert spherical image to equirect.
   SetDesc(  stack[i], rotate_erect,   mp->rot     ); i++; // Rotate equirect. image horizontally
 
-#ifdef MOSAIC_XYZ
-  if( im->cP.tilt )
+  if( im->cP.trans )
   {
     SetDesc( stack[i], plane_transfer_from_camera,      mp   ); i++;
   }
-#endif
 
   // THESE ARE ALL FORWARD transforms
   if(pn->format == _rectilinear)                  // rectilinear panorama
@@ -1419,7 +1409,7 @@
         mp->horizontal = 0;
     }
 
-	if(im->cP.vertical)
+        if(im->cP.vertical)
     {
         mp->vertical = im->cP.vertical_params[color];
     }
@@ -1428,164 +1418,164 @@
         mp->vertical = 0;
     }
 
-	if( (im->selection.left != 0) || (im->selection.top != 0) || (im->selection.bottom != 0) || (im->selection.right != 0) )
+        if( (im->selection.left != 0) || (im->selection.top != 0) || (im->selection.bottom != 0) || (im->selection.right != 0) )
     {
         if(im->cP.cutFrame)
         {
-			imSel.width = im->selection.right  - im->selection.left;
-			imSel.height = im->selection.bottom - im->selection.top;
-
-			mp->horizontal += (im->selection.right  + im->selection.left - im->width)/2.0;
-			mp->vertical   += (im->selection.bottom + im->selection.top  - im->height)/2.0;
-
-			imSel.cP.horizontal_params[color] = mp->horizontal;
-			imSel.cP.vertical_params[color]   = mp->vertical;
+                        imSel.width = im->selection.right  - im->selection.left;
+                        imSel.height = im->selection.bottom - im->selection.top;
+
+                        mp->horizontal += (im->selection.right  + im->selection.left - im->width)/2.0;
+                        mp->vertical   += (im->selection.bottom + im->selection.top  - im->height)/2.0;
+
+                        imSel.cP.horizontal_params[color] = mp->horizontal;
+                        imSel.cP.vertical_params[color]   = mp->vertical;
         }
     }
 
-	SetInvMakeParams( stack, mp, &imSel, pn, color );
-}
-	
+        SetInvMakeParams( stack, mp, &imSel, pn, color );
+}
+        
 
 
 // Add an alpha channel to the image, assuming rectangular or circular shape
 // subtract frame 
 
 void addAlpha( Image *im ){
-	register int 		x,y,c1;
-	int			framex, framey;
-	register unsigned char	*src;
-	
-	src = *(im->data);
-	framex = 0; framey = 0;
-	
-	if( im->cP.cutFrame ){
-		if( im->cP.frame < 0 || im->cP.fwidth < 0 || im->cP.fheight < 0 ){	// Use supplied alpha channel
-			return;
-		}
-		
-		if( im->cP.frame != 0 ){
-			framex = (im->width/2 	> im->cP.frame ? im->cP.frame : 0);
-			framey = (im->height/2 	> im->cP.frame ? im->cP.frame : 0);
-		}
-		else{
-			if( im->width > im->cP.fwidth )
-				framex = (im->width - im->cP.fwidth) / 2;
-			if( im->height > im->cP.fheight )
-				framey = (im->height - im->cP.fheight) / 2;
-		}
-	}
-
-
-	if( im->bitsPerPixel == 32 || im->bitsPerPixel == 64 ) // leave 24/48 bit images unchanged
-	{
-		if( im->format != _fisheye_circ )		// Rectangle valid
-		{
-			int yend = im->height - framey;
-			int xend = im->width  - framex;
-			
-			if( im->bitsPerPixel == 32 )
-			{
-				if( 0 != framey || 0 != framex )
-				{
-					for(y = 0; y < im->height; y++)
-					{
-						c1 = y * im->bytesPerLine;
-						for(x = 0; x < im->width; x++)
-							src[ c1 + 4 * x ] = 0;
-					}
-				}
-				for(y = framey; y < yend; y++)
-				{
-					c1 = y * im->bytesPerLine;
-					for(x = framex; x < xend; x++)
-						src[ c1 + 4 * x ] = UCHAR_MAX;
-				}
-			}
-			else // im->bitsPerPixel == 64
-			{
-				if( 0 != framey || 0 != framex )
-				{
-					for(y = 0; y < im->height; y++)
-					{
-						c1 = y * im->bytesPerLine;
-						for(x = 0; x < im->width; x++)
-							*((USHORT*)(src + c1 + 8 * x )) = 0;
-					}
-				}
-				for(y = framey; y < yend; y++)
-				{
-					c1 = y * im->bytesPerLine;
-					for(x = framex; x < xend; x++)
-						*((USHORT*)(src + c1 + 8 * x )) = USHRT_MAX;
-				}
-			}
-		}
-		else if( im->format == _fisheye_circ ) // Circle valid
-		{
-			int topCircle 	= ( im->height - im->width ) / 2; 	// top of circle
-			int botCircle 	= topCircle + im->width ;			// bottom of circle
-			int r			= ( im->width / 2 );				// radius of circle
-			int x1, x2, h;
-			
-			if( im->bitsPerPixel == 32 )
-			{
-				for(y = 0; y < im->height  ; y++) 
-				{
-					if( (y < topCircle) || (y > botCircle) )  // Always invalid
-					{
-						for(x = 0; x < im->width; x++)
-							src[y * im->bytesPerLine + 4 * x] = 0;
-					}
-					else
-					{
-						h 	=	y - im->height/2;
-						if( h*h > r*r ) h = r;
-
-						x1 = (int) (r - sqrt( r*r - h*h ));
-						if( x1 < 0 ) x1 = 0;
-						x2 = (int) (r + sqrt( r*r - h*h ));
-						if( x2 > im->width ) x2 = im->width;
-			
-						for(x = 0; x < x1; x++)
-							src[y * im->bytesPerLine + 4 * x] = 0;
-						for(x = x1; x < x2; x++)
-							src[y * im->bytesPerLine + 4 * x] = UCHAR_MAX;
-						for(x = x2; x < im->width; x++)
-							src[y * im->bytesPerLine + 4 * x] = 0;
-					}
-				}
-			}
-			else // im->bitsPerPixel == 64
-			{
-				for(y = 0; y < im->height  ; y++) 
-				{
-					if( (y < topCircle) || (y > botCircle) )  // Always invalid
-					{
-						for(x = 0; x < im->width; x++)
-							*((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
-					}
-					else
-					{
-						h 	=	y - im->height/2;
-						if( h*h > r*r ) h = r;
-
-						x1 = (int) (r - sqrt( r*r - h*h ));
-						if( x1 < 0 ) x1 = 0;
-						x2 = (int) (r + sqrt( r*r - h*h ));
-						if( x2 > im->width ) x2 = im->width;
-			
-						for(x = 0; x < x1; x++)
-							*((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
-						for(x = x1; x < x2; x++)
-							*((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = USHRT_MAX;
-						for(x = x2; x < im->width; x++)
-							*((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
-					}
-				}
-			}
-		} // mode
-	}	// pixelsize
+        register int            x,y,c1;
+        int                     framex, framey;
+        register unsigned char  *src;
+        
+        src = *(im->data);
+        framex = 0; framey = 0;
+        
+        if( im->cP.cutFrame ){
+                if( im->cP.frame < 0 || im->cP.fwidth < 0 || im->cP.fheight < 0 ){      // Use supplied alpha channel
+                        return;
+                }
+                
+                if( im->cP.frame != 0 ){
+                        framex = (im->width/2   > im->cP.frame ? im->cP.frame : 0);
+                        framey = (im->height/2  > im->cP.frame ? im->cP.frame : 0);
+                }
+                else{
+                        if( im->width > im->cP.fwidth )
+                                framex = (im->width - im->cP.fwidth) / 2;
+                        if( im->height > im->cP.fheight )
+                                framey = (im->height - im->cP.fheight) / 2;
+                }
+        }
+
+
+        if( im->bitsPerPixel == 32 || im->bitsPerPixel == 64 ) // leave 24/48 bit images unchanged
+        {
+                if( im->format != _fisheye_circ )               // Rectangle valid
+                {
+                        int yend = im->height - framey;
+                        int xend = im->width  - framex;
+                        
+                        if( im->bitsPerPixel == 32 )
+                        {
+                                if( 0 != framey || 0 != framex )
+                                {
+                                        for(y = 0; y < im->height; y++)
+                                        {
+                                                c1 = y * im->bytesPerLine;
+                                                for(x = 0; x < im->width; x++)
+                                                        src[ c1 + 4 * x ] = 0;
+                                        }
+                                }
+                                for(y = framey; y < yend; y++)
+                                {
+                                        c1 = y * im->bytesPerLine;
+                                        for(x = framex; x < xend; x++)
+                                                src[ c1 + 4 * x ] = UCHAR_MAX;
+                                }
+                        }
+                        else // im->bitsPerPixel == 64
+                        {
+                                if( 0 != framey || 0 != framex )
+                                {
+                                        for(y = 0; y < im->height; y++)
+                                        {
+                                                c1 = y * im->bytesPerLine;
+                                                for(x = 0; x < im->width; x++)
+                                                        *((USHORT*)(src + c1 + 8 * x )) = 0;
+                                        }
+                                }
+                                for(y = framey; y < yend; y++)
+                                {
+                                        c1 = y * im->bytesPerLine;
+                                        for(x = framex; x < xend; x++)
+                                                *((USHORT*)(src + c1 + 8 * x )) = USHRT_MAX;
+                                }
+                        }
+                }
+                else if( im->format == _fisheye_circ ) // Circle valid
+                {
+                        int topCircle   = ( im->height - im->width ) / 2;       // top of circle
+                        int botCircle   = topCircle + im->width ;                       // bottom of circle
+                        int r                   = ( im->width / 2 );                            // radius of circle
+                        int x1, x2, h;
+                        
+                        if( im->bitsPerPixel == 32 )
+                        {
+                                for(y = 0; y < im->height  ; y++) 
+                                {
+                                        if( (y < topCircle) || (y > botCircle) )  // Always invalid
+                                        {
+                                                for(x = 0; x < im->width; x++)
+                                                        src[y * im->bytesPerLine + 4 * x] = 0;
+                                        }
+                                        else
+                                        {
+                                                h       =       y - im->height/2;
+                                                if( h*h > r*r ) h = r;
+
+                                                x1 = (int) (r - sqrt( r*r - h*h ));
+                                                if( x1 < 0 ) x1 = 0;
+                                                x2 = (int) (r + sqrt( r*r - h*h ));
+                                                if( x2 > im->width ) x2 = im->width;
+                        
+                                                for(x = 0; x < x1; x++)
+                                                        src[y * im->bytesPerLine + 4 * x] = 0;
+                                                for(x = x1; x < x2; x++)
+                                                        src[y * im->bytesPerLine + 4 * x] = UCHAR_MAX;
+                                                for(x = x2; x < im->width; x++)
+                                                        src[y * im->bytesPerLine + 4 * x] = 0;
+                                        }
+                                }
+                        }
+                        else // im->bitsPerPixel == 64
+                        {
+                                for(y = 0; y < im->height  ; y++) 
+                                {
+                                        if( (y < topCircle) || (y > botCircle) )  // Always invalid
+                                        {
+                                                for(x = 0; x < im->width; x++)
+                                                        *((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
+                                        }
+                                        else
+                                        {
+                                                h       =       y - im->height/2;
+                                                if( h*h > r*r ) h = r;
+
+                                                x1 = (int) (r - sqrt( r*r - h*h ));
+                                                if( x1 < 0 ) x1 = 0;
+                                                x2 = (int) (r + sqrt( r*r - h*h ));
+                                                if( x2 > im->width ) x2 = im->width;
+                        
+                                                for(x = 0; x < x1; x++)
+                                                        *((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
+                                                for(x = x1; x < x2; x++)
+                                                        *((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = USHRT_MAX;
+                                                for(x = x2; x < im->width; x++)
+                                                        *((USHORT*)(src + y * im->bytesPerLine + 8 * x)) = 0;
+                                        }
+                                }
+                        }
+                } // mode
+        }       // pixelsize
 }
 
 
@@ -1600,158 +1590,158 @@
 double distanceComponents[2];
 
 double distSphere( int num ){
-	double 		x, y ; 	// Coordinates of control point in panorama
-	double		w2, h2;
-	int j;
-	Image sph;
-	int n[2];
-	struct 	MakeParams	mp;
-	struct  fDesc        	stack[15];
-	CoordInfo b[2];
-	CoordInfo cp;
-	double lat[2], lon[2];  // latitude & longitude
-	double dlon;
-	double dangle;
-	double dist;
-	double radiansToPixelsFactor;
-
-	// Factor to convert angular error in radians to equivalent in pixels
-	
-	radiansToPixelsFactor = g->pano.width / (g->pano.hfov * (PI/180.0));
-	
-	// Get image position in imaginary spherical image
-	
-	SetImageDefaults( &sph );
-	
-	sph.width 			= 360;
-	sph.height 			= 180;
-	sph.format			= _equirectangular;
-	sph.hfov			= 360.0;
-	
-	n[0] = g->cpt[num].num[0];
-	n[1] = g->cpt[num].num[1];
-	
-	// Calculate coordinates using equirectangular mapping to get longitude/latitude
-
-	for(j=0; j<2; j++){
-		SetInvMakeParams( stack, &mp, &g->im[ n[j] ], &sph, 0 );
-		
-		h2 	= (double)g->im[ n[j] ].height / 2.0 - 0.5;
-		w2	= (double)g->im[ n[j] ].width  / 2.0 - 0.5;
-		
-		
-		execute_stack_new( 	(double)g->cpt[num].x[j] - w2,		// cartesian x-coordinate src
-						(double)g->cpt[num].y[j] - h2,		// cartesian y-coordinate src
-						&x, &y, stack);
-
-		x = DEG_TO_RAD( x ); 
-		y = DEG_TO_RAD( y ) + PI/2.0;
-
-		// x is now in the range -PI to +PI, and y is 0 to PI
-		lat[j] = y;
-		lon[j] = x;
-
-		b[j].x[0] =   sin(x) * sin( y );
-		b[j].x[1] =   cos( y );
-		b[j].x[2] = - cos(x) * sin(y);
-	}
-
-	dlon = lon[0]-lon[1];
-	if (dlon < -PI) dlon += 2.0*PI;
-	if (dlon > PI) dlon -= 2.0*PI;
-	distanceComponents[0] = (dlon*sin(0.5*(lat[0]+lat[1]))) * radiansToPixelsFactor;
-	distanceComponents[1] = (lat[0]-lat[1]) * radiansToPixelsFactor;
-
-	// The original acos formulation (acos(SCALAR_PRODUCT(&b[0],&b[1]))
-	// is inaccurate for angles near 0, because it essentially requires finding eps
-	// based on the value of 1-eps^2/2.  The asin formulation is much more
-	// accurate under these conditions.
-
-	CROSS_PRODUCT(&b[0],&b[1],&cp);
-	dangle = asin(ABS_VECTOR(&cp));
-	if (SCALAR_PRODUCT(&b[0],&b[1]) < 0.0) dangle = PI - dangle;
-	dist = dangle * radiansToPixelsFactor;
-	
-	// Diagnostics to help debug various calculation errors.
-	// Do not delete this code --- it has been needed surprisingly often.
-#if 0	
-	{	double olddist;
-		olddist = acos( SCALAR_PRODUCT( &b[0], &b[1] ) ) * radiansToPixelsFactor;
-//		if (adjustLogFile != 0 && abs(dist-olddist) > 1.0) {
-		if (adjustLogFile != 0 && num < 5) {
-			fprintf(adjustLogFile,"***** DIST ***** dCoord = %g %g, lonlat0 = %g %g, lonlat1 = %g %g, dist=%g, olddist=%g, sumDcoordSq=%g, distSq=%g\n",
-								  distanceComponents[0],distanceComponents[1],lon[0],lat[0],lon[1],lat[1],dist,olddist,
-								  distanceComponents[0]*distanceComponents[0]+distanceComponents[1]*distanceComponents[1],dist*dist);
-		}
-	}
+        double          x, y ;  // Coordinates of control point in panorama
+        double          w2, h2;
+        int j;
+        Image sph;
+        int n[2];
+        struct  MakeParams      mp;
+        struct  fDesc           stack[15];
+        CoordInfo b[2];
+        CoordInfo cp;
+        double lat[2], lon[2];  // latitude & longitude
+        double dlon;
+        double dangle;
+        double dist;
+        double radiansToPixelsFactor;
+
+        // Factor to convert angular error in radians to equivalent in pixels
+        
+        radiansToPixelsFactor = optInfo->pano.width / (optInfo->pano.hfov * (PI/180.0));
+        
+        // Get image position in imaginary spherical image
+        
+        SetImageDefaults( &sph );
+        
+        sph.width                       = 360;
+        sph.height                      = 180;
+        sph.format                      = _equirectangular;
+        sph.hfov                        = 360.0;
+        
+        n[0] = optInfo->cpt[num].num[0];
+        n[1] = optInfo->cpt[num].num[1];
+        
+        // Calculate coordinates using equirectangular mapping to get longitude/latitude
+
+        for(j=0; j<2; j++){
+                SetInvMakeParams( stack, &mp, &optInfo->im[ n[j] ], &sph, 0 );
+                
+                h2      = (double)optInfo->im[ n[j] ].height / 2.0 - 0.5;
+                w2      = (double)optInfo->im[ n[j] ].width  / 2.0 - 0.5;
+                
+                
+                execute_stack_new(      (double)optInfo->cpt[num].x[j] - w2,            // cartesian x-coordinate src
+                                                (double)optInfo->cpt[num].y[j] - h2,            // cartesian y-coordinate src
+                                                &x, &y, stack);
+
+                x = DEG_TO_RAD( x ); 
+                y = DEG_TO_RAD( y ) + PI/2.0;
+
+                // x is now in the range -PI to +PI, and y is 0 to PI
+                lat[j] = y;
+                lon[j] = x;
+
+                b[j].x[0] =   sin(x) * sin( y );
+                b[j].x[1] =   cos( y );
+                b[j].x[2] = - cos(x) * sin(y);
+        }
+
+        dlon = lon[0]-lon[1];
+        if (dlon < -PI) dlon += 2.0*PI;
+        if (dlon > PI) dlon -= 2.0*PI;
+        distanceComponents[0] = (dlon*sin(0.5*(lat[0]+lat[1]))) * radiansToPixelsFactor;
+        distanceComponents[1] = (lat[0]-lat[1]) * radiansToPixelsFactor;
+
+        // The original acos formulation (acos(SCALAR_PRODUCT(&b[0],&b[1]))
+        // is inaccurate for angles near 0, because it essentially requires finding eps
+        // based on the value of 1-eps^2/2.  The asin formulation is much more
+        // accurate under these conditions.
+
+        CROSS_PRODUCT(&b[0],&b[1],&cp);
+        dangle = asin(ABS_VECTOR(&cp));
+        if (SCALAR_PRODUCT(&b[0],&b[1]) < 0.0) dangle = PI - dangle;
+        dist = dangle * radiansToPixelsFactor;
+        
+        // Diagnostics to help debug various calculation errors.
+        // Do not delete this code --- it has been needed surprisingly often.
+#if 0   
+        {       double olddist;
+                olddist = acos( SCALAR_PRODUCT( &b[0], &b[1] ) ) * radiansToPixelsFactor;
+//              if (adjustLogFile != 0 && abs(dist-olddist) > 1.0) {
+                if (adjustLogFile != 0 && num < 5) {
+                        fprintf(adjustLogFile,"***** DIST ***** dCoord = %g %g, lonlat0 = %g %g, lonlat1 = %g %g, dist=%g, olddist=%g, sumDcoordSq=%g, distSq=%g\n",
+                                                                  distanceComponents[0],distanceComponents[1],lon[0],lat[0],lon[1],lat[1],dist,olddist,
+                                                                  distanceComponents[0]*distanceComponents[0]+distanceComponents[1]*distanceComponents[1],dist*dist);
+                }
+        }
 #endif
 
-	return dist;
+        return dist;
 }
 
 
 
 void pt_getXY(int n, double x, double y, double *X, double *Y){
-	struct 	MakeParams	mp;
-	struct  fDesc        	stack[15];
-	double h2,w2;
-
-	SetInvMakeParams( stack, &mp, &g->im[ n ], &g->pano, 0 );
-	h2 	= (double)g->im[ n ].height / 2.0 - 0.5;
-	w2	= (double)g->im[ n ].width  / 2.0 - 0.5;
-
-
-	execute_stack_new( 	x - w2,	y - h2,	X, Y, stack);
+        struct  MakeParams      mp;
+        struct  fDesc           stack[15];
+        double h2,w2;
+
+        SetInvMakeParams( stack, &mp, &optInfo->im[ n ], &optInfo->pano, 0 );
+        h2      = (double)optInfo->im[ n ].height / 2.0 - 0.5;
+        w2      = (double)optInfo->im[ n ].width  / 2.0 - 0.5;
+
+
+        execute_stack_new(      x - w2, y - h2, X, Y, stack);
 }
 
 // Return distance of points from a line
 // The line through the two farthest apart points is calculated
 // Returned is the sum distance squared of the other two points from the line
 double distsqLine(int N0, int N1){
-	double x[4],y[4], del, delmax, A, B, C, mu, d0, d1;
-	int n0, n1, n2=-1, n3=-1, i, k;
-
-	pt_getXY(g->cpt[N0].num[0], (double)g->cpt[N0].x[0], (double)g->cpt[N0].y[0], &x[0], &y[0]);
-	pt_getXY(g->cpt[N0].num[1], (double)g->cpt[N0].x[1], (double)g->cpt[N0].y[1], &x[1], &y[1]);
-	pt_getXY(g->cpt[N1].num[0], (double)g->cpt[N1].x[0], (double)g->cpt[N1].y[0], &x[2], &y[2]);
-	pt_getXY(g->cpt[N1].num[1], (double)g->cpt[N1].x[1], (double)g->cpt[N1].y[1], &x[3], &y[3]);
-
-	delmax = 0.0;
-	n0 = 0; n1 = 1;
-
-	for(i=0; i<4; i++){
-		for(k=i+1; k<4; k++){
-			del = (x[i]-x[k])*(x[i]-x[k])+(y[i]-y[k])*(y[i]-y[k]);
-			if(del>delmax){
-				n0=i; n1=k; delmax=del;
-			}
-		}
-	}
-	if(delmax==0.0) return 0.0;
-
-	for(i=0; i<4; i++){
-		if(i!= n0 && i!= n1){
-			n2 = i;
-			break;
-		}
-	}
-	for(i=0; i<4; i++){
-		if(i!= n0 && i!= n1 && i!=n2){
-			n3 = i;
-		}
-	}
-
-
-	A=y[n1]-y[n0]; B=x[n0]-x[n1]; C=y[n0]*(x[n1]-x[n0])-x[n0]*(y[n1]-y[n0]);
-
-	mu=1.0/sqrt(A*A+B*B);
-
-	d0 = (A*x[n2]+B*y[n2]+C)*mu;
-	d1 = (A*x[n3]+B*y[n3]+C)*mu;
-	distanceComponents[0] = d0;
-	distanceComponents[1] = d1;
-
-	return d0*d0 + d1*d1;
+        double x[4],y[4], del, delmax, A, B, C, mu, d0, d1;
+        int n0, n1, n2=-1, n3=-1, i, k;
+
+        pt_getXY(optInfo->cpt[N0].num[0], (double)optInfo->cpt[N0].x[0], (double)optInfo->cpt[N0].y[0], &x[0], &y[0]);
+        pt_getXY(optInfo->cpt[N0].num[1], (double)optInfo->cpt[N0].x[1], (double)optInfo->cpt[N0].y[1], &x[1], &y[1]);
+        pt_getXY(optInfo->cpt[N1].num[0], (double)optInfo->cpt[N1].x[0], (double)optInfo->cpt[N1].y[0], &x[2], &y[2]);
+        pt_getXY(optInfo->cpt[N1].num[1], (double)optInfo->cpt[N1].x[1], (double)optInfo->cpt[N1].y[1], &x[3], &y[3]);
+
+        delmax = 0.0;
+        n0 = 0; n1 = 1;
+
+        for(i=0; i<4; i++){
+                for(k=i+1; k<4; k++){
+                        del = (x[i]-x[k])*(x[i]-x[k])+(y[i]-y[k])*(y[i]-y[k]);
+                        if(del>delmax){
+                                n0=i; n1=k; delmax=del;
+                        }
+                }
+        }
+        if(delmax==0.0) return 0.0;
+
+        for(i=0; i<4; i++){
+                if(i!= n0 && i!= n1){
+                        n2 = i;
+                        break;
+                }
+        }
+        for(i=0; i<4; i++){
+                if(i!= n0 && i!= n1 && i!=n2){
+                        n3 = i;
+                }
+        }
+
+
+        A=y[n1]-y[n0]; B=x[n0]-x[n1]; C=y[n0]*(x[n1]-x[n0])-x[n0]*(y[n1]-y[n0]);
+
+        mu=1.0/sqrt(A*A+B*B);
+
+        d0 = (A*x[n2]+B*y[n2]+C)*mu;
+        d1 = (A*x[n3]+B*y[n3]+C)*mu;
+        distanceComponents[0] = d0;
+        distanceComponents[1] = d1;
+
+        return d0*d0 + d1*d1;
 
 }
 
@@ -1761,87 +1751,87 @@
 
 double rectDistSquared( int num ) 
 {
-	double 		x[2], y[2]; 				// Coordinates of control point in panorama
-	double		w2, h2;
-	int j, n[2];
-	double result;
-
-	struct 	MakeParams	mp;
-	struct  fDesc        	stack[15];
-
-	
-
-	n[0] = g->cpt[num].num[0];
-	n[1] = g->cpt[num].num[1];
-	
-	// Calculate coordinates x/y in panorama
-
-	for(j=0; j<2; j++)
-	{
-		SetInvMakeParams( stack, &mp, &g->im[ n[j] ], &g->pano, 0 );
-		
-		h2 	= (double)g->im[ n[j] ].height / 2.0 - 0.5;
-		w2	= (double)g->im[ n[j] ].width  / 2.0 - 0.5;
-		
-
-		execute_stack_new( 	(double)g->cpt[num].x[j] - w2,		// cartesian x-coordinate src
-						(double)g->cpt[num].y[j] - h2,		// cartesian y-coordinate src
-						&x[j], &y[j], stack);
-		// test to check if inverse works
+        double          x[2], y[2];                             // Coordinates of control point in panorama
+        double          w2, h2;
+        int j, n[2];
+        double result;
+
+        struct  MakeParams      mp;
+        struct  fDesc           stack[15];
+
+        
+
+        n[0] = optInfo->cpt[num].num[0];
+        n[1] = optInfo->cpt[num].num[1];
+        
+        // Calculate coordinates x/y in panorama
+
+        for(j=0; j<2; j++)
+        {
+                SetInvMakeParams( stack, &mp, &optInfo->im[ n[j] ], &optInfo->pano, 0 );
+                
+                h2      = (double)optInfo->im[ n[j] ].height / 2.0 - 0.5;
+                w2      = (double)optInfo->im[ n[j] ].width  / 2.0 - 0.5;
+                
+
+                execute_stack_new(      (double)optInfo->cpt[num].x[j] - w2,            // cartesian x-coordinate src
+                                                (double)optInfo->cpt[num].y[j] - h2,            // cartesian y-coordinate src
+                                                &x[j], &y[j], stack);
+                // test to check if inverse works
 #if 0
-		{
-			double xt, yt;
-			struct 	MakeParams	mtest;
-			struct  fDesc 		stacktest[15];
-			SetMakeParams( stacktest, &mtest, &g->im[ n[j] ], &g->pano, 0 );
-			execute_stack_new( 	x[j],		// cartesian x-coordinate src
-							y[j],		// cartesian y-coordinate src
-						&xt, &yt, stacktest);
-			
-			printf("x= %lg,	y= %lg,  xb = %lg, yb = %lg \n", g->cpt[num].x[j], g->cpt[num].y[j], xt+w2, yt+h2);  
-			
-		}
+                {
+                        double xt, yt;
+                        struct  MakeParams      mtest;
+                        struct  fDesc           stacktest[15];
+                        SetMakeParams( stacktest, &mtest, &optInfo->im[ n[j] ], &optInfo->pano, 0 );
+                        execute_stack_new(      x[j],           // cartesian x-coordinate src
+                                                        y[j],           // cartesian y-coordinate src
+                                                &xt, &yt, stacktest);
+                        
+                        printf("x= %lg, y= %lg,  xb = %lg, yb = %lg \n", optInfo->cpt[num].x[j], optInfo->cpt[num].y[j], xt+w2, yt+h2);  
+                        
+                }
 #endif
-	}
-	
-	
-//	printf("Coordinates 0:   %lg:%lg	1:	%lg:%lg\n",x[0] + g->pano->width/2,y[0]+ g->pano->height/2, x[1] + g->pano->width/2,y[1]+ g->pano->height/2);
-
-
-	// take care of wrapping and points at edge of panorama
-	
-	if( g->pano.hfov == 360.0 )
-	{
-		double delta = abs( x[0] - x[1] );
-		
-		if( delta > g->pano.width / 2 )
-		{
-			if( x[0] < x[1] )
-				x[0] += g->pano.width;
-			else
-				x[1] += g->pano.width;
-		}
-	}
-
-
-	switch( g->cpt[num].type )		// What do we want to optimize?
-	{
-		case 1:			// x difference
-			result = ( x[0] - x[1] ) * ( x[0] - x[1] );
-			break;
-		case 2:			// y-difference
-			result =  ( y[0] - y[1] ) * ( y[0] - y[1] );
-			break;
-		default:
-			result = ( y[0] - y[1] ) * ( y[0] - y[1] ) + ( x[0] - x[1] ) * ( x[0] - x[1] ); // square of distance
-			distanceComponents[0] = y[0] - y[1];
-			distanceComponents[1] = x[0] - x[1];
-
-			break;
-	}
-	
-
-	return result;
+        }
+        
+        
+//      printf("Coordinates 0:   %lg:%lg        1:      %lg:%lg\n",x[0] + g->pano->width/2,y[0]+ g->pano->height/2, x[1] + g->pano->width/2,y[1]+ g->pano->height/2);
+
+
+        // take care of wrapping and points at edge of panorama
+        
+        if( optInfo->pano.hfov == 360.0 )
+        {
+                double delta = abs( x[0] - x[1] );
+                
+                if( delta > optInfo->pano.width / 2 )
+                {
+                        if( x[0] < x[1] )
+                                x[0] += optInfo->pano.width;
+                        else
+                                x[1] += optInfo->pano.width;
+                }
+        }
+
+
+        switch( optInfo->cpt[num].type )                // What do we want to optimize?
+        {
+                case 1:                 // x difference
+                        result = ( x[0] - x[1] ) * ( x[0] - x[1] );
+                        break;
+                case 2:                 // y-difference
+                        result =  ( y[0] - y[1] ) * ( y[0] - y[1] );
+                        break;
+                default:
+                        result = ( y[0] - y[1] ) * ( y[0] - y[1] ) + ( x[0] - x[1] ) * ( x[0] - x[1] ); // square of distance
+                        distanceComponents[0] = y[0] - y[1];
+                        distanceComponents[1] = x[0] - x[1];
+
+                        break;
+        }
+        
+
+        return result;
 }
 
 /// huber() is an M-Estimator function. Using an M-Estimator might
@@ -1879,67 +1869,67 @@
 ///                       as possible
 /// Return value is a success flag: 0 = successful, otherwise not.
 
-int	EvaluateControlPointErrorAndComponents ( int num, double *errptr, double errComponent[2]) {
-	int j;
-	int result;
-	switch(g->cpt[num].type){
-		case 0: // normal control points
-			// Jim May 2004. 
-			// Optimizing cylindrical and rectilinear projection by calculating 
-			// distance error in pixel coordinates of the rendered image.
-			// When using angular (spherical) distance for these projections, 
-			// larger errors are generated the further control points are from 
-			// the center.
-			// In theory by optimizing in pixel coordinates all errors will be 
-			// distributed over the image.  This is true.
-			// In practice I have found that optimize large field of view 
-			// rectilinear projection images failed to resolve nicely if the 
-			// parameters were not very close to start with.  I leave the 
-			// code here for others to play with and maybe get better results.
-		/*  if(g->pano.format == _rectilinear || g->pano.format == _panorama)
-			{
-				*errptr = sqrt(rectDistSquared(num));
-				errComponent[0] = distanceComponents[0];
-				errComponent[1] = distanceComponents[1];
-				result = 0;
-				break;
-			}
-			else //  _equirectangular, fisheye, spherical, mirror
-			{  */
-				*errptr = distSphere(num);
-				errComponent[0] = distanceComponents[0];
-				errComponent[1] = distanceComponents[1];
-				result = 0;
-				break;
-			//}
-		case 1: // vertical
-		case 2: // horizontal
-				*errptr = sqrt(rectDistSquared(num));
-				errComponent[0] = *errptr;
-				errComponent[1] = 0.0;
-				result = 0;
-				break;
-		default:// t+ controls = lines = sets of two control point pairs
-				*errptr = 0.0;	// in case there is no second pair
-				errComponent[0] = 0.0;
-				errComponent[1] = 0.0;
-				result = 1;
-				for(j=0; j<g->numPts; j++){
-					if(j!=num && g->cpt[num].type == g->cpt[j].type){
-						*errptr = sqrt(distsqLine(num,j));
-//						errComponent[0] = *errptr;
-//						errComponent[1] = 0.0;
-						errComponent[0] = distanceComponents[0];
-						errComponent[1] = distanceComponents[1];
-						result = 0;
-						break;
-					}
-				}
-				break;
-	}
-	return result;
-}
-	
+int     EvaluateControlPointErrorAndComponents ( int num, double *errptr, double errComponent[2]) {
+        int j;
+        int result;
+        switch(optInfo->cpt[num].type){
+                case 0: // normal control points
+                        // Jim May 2004. 
+                        // Optimizing cylindrical and rectilinear projection by calculating 
+                        // distance error in pixel coordinates of the rendered image.
+                        // When using angular (spherical) distance for these projections, 
+                        // larger errors are generated the further control points are from 
+                        // the center.
+                        // In theory by optimizing in pixel coordinates all errors will be 
+                        // distributed over the image.  This is true.
+                        // In practice I have found that optimize large field of view 
+                        // rectilinear projection images failed to resolve nicely if the 
+                        // parameters were not very close to start with.  I leave the 
+                        // code here for others to play with and maybe get better results.
+                /*  if(optInfo->pano.format == _rectilinear || g->pano.format == _panorama)
+                        {
+                                *errptr = sqrt(rectDistSquared(num));
+                                errComponent[0] = distanceComponents[0];
+                                errComponent[1] = distanceComponents[1];
+                                result = 0;
+                                break;
+                        }
+                        else //  _equirectangular, fisheye, spherical, mirror
+                        {  */
+                                *errptr = distSphere(num);
+                                errComponent[0] = distanceComponents[0];
+                                errComponent[1] = distanceComponents[1];
+                                result = 0;
+                                break;
+                        //}
+                case 1: // vertical
+                case 2: // horizontal
+                                *errptr = sqrt(rectDistSquared(num));
+                                errComponent[0] = *errptr;
+                                errComponent[1] = 0.0;
+                                result = 0;
+                                break;
+                default:// t+ controls = lines = sets of two control point pairs
+                                *errptr = 0.0;  // in case there is no second pair
+                                errComponent[0] = 0.0;
+                                errComponent[1] = 0.0;
+                                result = 1;
+                                for(j=0; j<optInfo->numPts; j++){
+                                        if(j!=num && optInfo->cpt[num].type == optInfo->cpt[j].type){
+                                                *errptr = sqrt(distsqLine(num,j));
+//                                              errComponent[0] = *errptr;
+//                                              errComponent[1] = 0.0;
+                                                errComponent[0] = distanceComponents[0];
+                                                errComponent[1] = distanceComponents[1];
+                                                result = 0;
+                                                break;
+                                        }
+                                }
+                                break;
+        }
+        return result;
+}
+        
 /// This distSquared is a convenience function, to be passed into
 /// WriteResults in the usual fashion, to avoid having to change
 /// other codes that call WriteResults.  It replaces the old distSquared,
@@ -1947,10 +1937,10 @@
 /// internally by EvaluateControlPointErrorAndComponents.
 
 double  distSquared (int num ) {
-	double result;
-	double junk[2];
-	EvaluateControlPointErrorAndComponents (num, &result, junk);
-	return result*result;
+        double result;
+        double junk[2];
+        EvaluateControlPointErrorAndComponents (num, &result, junk);
+        return result*result;
 }
 
 /// Function fcnPano calculates a vector of control points errors,
@@ -1962,184 +1952,185 @@
 int fcnPanoNperCP = 1; // number of functions per control point, 1 or 2
 
 void setFcnPanoNperCP (int i) {
-	fcnPanoNperCP = i;
+        fcnPanoNperCP = i;
 }
 
 int getFcnPanoNperCP() {
-	return fcnPanoNperCP;
+        return fcnPanoNperCP;
 }
 
 void setFcnPanoDoNotInitAvgFov() { // must be called after iflag = -100 call to fcnPano
-	needInitialAvgFov = 0;
+        needInitialAvgFov = 0;
 }
 
 void forceFcnPanoReinitAvgFov() { // applies to next call to fcnPano
-	needInitialAvgFov = 1;
+        needInitialAvgFov = 1;
 }
 
 int fcnPano(int m, int n, double x[], double fvec[], int *iflag)
 {
-	int i;
-	static int numIt;
-	double result;
-	int iresult;
-	double junk;
-	double junk2[2];
-	
-	if( *iflag == -100 ){ // reset
-		numIt = 0;
-		needInitialAvgFov = 1;
-		infoDlg ( _initProgress, "Optimizing Variables" );
+        int i;
+        static int numIt;
+        double result;
+        int iresult;
+        double junk;
+        double junk2[2];
+        
+        if( *iflag == -100 ){ // reset
+                numIt = 0;
+                needInitialAvgFov = 1;
+                infoDlg ( _initProgress, "Optimizing Variables" );
 #if ADJUST_LOGGING_ENABLED
-		if ((adjustLogFile = fopen(ADJUST_LOG_FILENAME,"a")) <= 0) {
-			PrintError("Cannot Open Log File");
-			adjustLogFile = 0;
-		}
+                if ((adjustLogFile = fopen(ADJUST_LOG_FILENAME,"a")) <= 0) {
+                        PrintError("Cannot Open Log File");
+                        adjustLogFile = 0;
+                }
 #endif
-		return 0;
-	}
-	if( *iflag == -99 ){ // 
-		infoDlg ( _disposeProgress, "" );
-		if (adjustLogFile != 0) {
-			result = 0.0;
-			for( i=0; i < m; i++)
-			{
-				result += fvec[i]*fvec[i] ;
-			}
-			result = sqrt( result/ (double)m ) * sqrt((double)fcnPanoNperCP); // to approximate total distance vs dx, dy
-			fprintf(adjustLogFile,"At iflag=-99 (dispose), NperCP=%d, m=%d, n=%d, err = %g, x= \n",
-			                      fcnPanoNperCP,m,n,result);
-			for (i=0; i<n; i++) {
-				fprintf(adjustLogFile,"\t%20.10g",x[i]);
-			}
-			fprintf(adjustLogFile,"\n   fvec = \n");
-			for (i=0; i<m; i++) {
-				fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
-				if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
-			}
-			fprintf(adjustLogFile,"\n");
-			fclose(adjustLogFile);
-		}
-		return 0;
-	}
-
-
-	if( *iflag == 0 )
-	{
-		char message[256];
-		
-		result = 0.0;
-		for( i=0; i < m; i++)
-		{
-			result += fvec[i]*fvec[i] ;
-		}
-		result = sqrt( result/ (double)m ) * sqrt((double)fcnPanoNperCP); // to approximate total distance vs dx, dy
-
-		sprintf( message,"Strategy %d\nAverage (rms) distance between Controlpoints \nafter %d iteration(s): %25.15g units", getFcnPanoNperCP(), numIt,result);//average);
-		numIt += 1; // 10;
-		if( !infoDlg ( _setProgress,message ) )
-			*iflag = -1;
-
-		if (adjustLogFile != 0) {
-			fprintf(adjustLogFile,"At iteration %d, iflag=0 (print), NperCP=%d, m=%d, n=%d, err = %g, x= \n",
-			                      numIt,fcnPanoNperCP,m,n,result);
-			for (i=0; i<n; i++) {
-				fprintf(adjustLogFile,"\t%20.10g",x[i]);
-			}
-			fprintf(adjustLogFile,"\n   fvec = \n");
-			for (i=0; i<m; i++) {
-				fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
-				if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
-			}
-			fprintf(adjustLogFile,"\n");
-			fflush(adjustLogFile);
-		}
-
-		return 0;
-	}
-
-	// Set Parameters
-
-	SetAlignParams( x ) ;
-	if (needInitialAvgFov) {
-		initialAvgFov = avgfovFromSAP;
-		needInitialAvgFov = 0;
-		if (adjustLogFile != 0) {
-			fprintf(adjustLogFile,"setting initialAvgFov = %g\n",initialAvgFov);
-			fflush(adjustLogFile);
-		}
-	}
-
-	if (adjustLogFile != 0) {
-		fprintf(adjustLogFile,"entering fcnPano, m=%d, n=%d, initialAvgFov=%g, avgfovFromSAP=%g, x = \n",
-		                      m,n, initialAvgFov,avgfovFromSAP);
-		for (i=0; i<n; i++) {
-			fprintf(adjustLogFile,"\t%20.10g",x[i]);
-		}
-		fprintf(adjustLogFile,"\n");
-		fflush(adjustLogFile);
-	}
-
-	// Calculate distances
-
-	iresult = 0;
-	for( i=0; i < g->numPts; i++){
-		if (fcnPanoNperCP == 1) {
-			EvaluateControlPointErrorAndComponents ( i, &fvec[iresult], &junk2[0]);
+                return 0;
+        }
+        if( *iflag == -99 ){ // 
+                infoDlg ( _disposeProgress, "" );
+                if (adjustLogFile != 0) {
+                        result = 0.0;
+                        for( i=0; i < m; i++)
+                        {
+                                result += fvec[i]*fvec[i] ;
+                        }
+                        result = sqrt( result/ (double)m ) * sqrt((double)fcnPanoNperCP); // to approximate total distance vs dx, dy
+                        fprintf(adjustLogFile,"At iflag=-99 (dispose), NperCP=%d, m=%d, n=%d, err = %g, x= \n",
+                                              fcnPanoNperCP,m,n,result);
+                        for (i=0; i<n; i++) {
+                                fprintf(adjustLogFile,"\t%20.10g",x[i]);
+                        }
+                        fprintf(adjustLogFile,"\n   fvec = \n");
+                        for (i=0; i<m; i++) {
+                                fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
+                                if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
+                        }
+                        fprintf(adjustLogFile,"\n");
+                        fclose(adjustLogFile);
+                }
+                return 0;
+        }
+
+
+        if( *iflag == 0 )
+        {
+                char message[256];
+                
+                result = 0.0;
+                for( i=0; i < m; i++)
+                {
+                        result += fvec[i]*fvec[i] ;
+                }
+                result = sqrt( result/ (double)m ) * sqrt((double)fcnPanoNperCP); // to approximate total distance vs dx, dy
+
+                sprintf( message,"Strategy %d\nAverage (rms) distance between Controlpoints \nafter %d iteration(s): %25.15g units", getFcnPanoNperCP(), numIt,result);//average);
+                numIt += 1; // 10;
+                if( !infoDlg ( _setProgress,message ) )
+                        *iflag = -1;
+
+                if (adjustLogFile != 0) {
+                        fprintf(adjustLogFile,"At iteration %d, iflag=0 (print), NperCP=%d, m=%d, n=%d, err = %g, x= \n",
+                                              numIt,fcnPanoNperCP,m,n,result);
+                        for (i=0; i<n; i++) {
+                                fprintf(adjustLogFile,"\t%20.10g",x[i]);
+                        }
+                        fprintf(adjustLogFile,"\n   fvec = \n");
+                        for (i=0; i<m; i++) {
+                                fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
+                                if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
+                        }
+                        fprintf(adjustLogFile,"\n");
+                        fflush(adjustLogFile);
+                }
+
+                return 0;
+        }
+
+        // Set Parameters
+
+        SetAlignParams( x ) ;
+
+        if (needInitialAvgFov) {
+                initialAvgFov = avgfovFromSAP;
+                needInitialAvgFov = 0;
+                if (adjustLogFile != 0) {
+                        fprintf(adjustLogFile,"setting initialAvgFov = %g\n",initialAvgFov);
+                        fflush(adjustLogFile);
+                }
+        }
+
+        if (adjustLogFile != 0) {
+                fprintf(adjustLogFile,"entering fcnPano, m=%d, n=%d, initialAvgFov=%g, avgfovFromSAP=%g, x = \n",
+                                      m,n, initialAvgFov,avgfovFromSAP);
+                for (i=0; i<n; i++) {
+                        fprintf(adjustLogFile,"\t%20.10g",x[i]);
+                }
+                fprintf(adjustLogFile,"\n");
+                fflush(adjustLogFile);
+        }
+
+        // Calculate distances
+
+        iresult = 0;
+        for( i=0; i < optInfo->numPts; i++){
+                if (fcnPanoNperCP == 1) {
+                        EvaluateControlPointErrorAndComponents ( i, &fvec[iresult], &junk2[0]);
         } else {
-			EvaluateControlPointErrorAndComponents ( i, &junk, &fvec[iresult]);
+                        EvaluateControlPointErrorAndComponents ( i, &junk, &fvec[iresult]);
             if (fcnPanoHuberSigma) {
                 fvec[iresult] = huber(fvec[iresult], fcnPanoHuberSigma);
                 fvec[iresult+1] = huber(fvec[iresult+1], fcnPanoHuberSigma);
             }
-		}
-		
-		// Field-of-view stabilization.  Applying here means that the
-		// errors seen by the optimizer may be different from those finally
-		// reported, by the same factor for all errors.  This introduces
-		// the possibility of confusion for people who are paying really
-		// close attention to the optimizer's periodic output versus the
-		// final result.  However, it seems like the right thing to do
-		// because then the final reported errors will correspond to the
-		// user's settings for pano size, total fov etc. 
-		
-		if ((initialAvgFov / avgfovFromSAP) > 1.0) {
-			fvec[iresult] *= initialAvgFov / avgfovFromSAP;
-		}
-		iresult += 1;
-		if (fcnPanoNperCP == 2) {
-			if ((initialAvgFov / avgfovFromSAP) > 1.0) {
-				fvec[iresult] *= initialAvgFov / avgfovFromSAP;
-			}
-			iresult += 1;
-		}		
-	}
-	
-	// If not enough control points are provided, then fill out
-	// the function vector with copies of the average error
-	// for the actual control points.
-
-	result = 0.0;
-	for (i=0; i < iresult; i++) {
-		result += fvec[i]*fvec[i];
-	}
-	result = sqrt(result/(double)iresult);
-	for (i=iresult; i < m; i++) {
-		fvec[i] = result;
-	}
-
-	if (adjustLogFile != 0) {
-		result *= sqrt((double)fcnPanoNperCP);
-		fprintf(adjustLogFile,"leaving fcnPano, m=%d, n=%d, err=%g, fvec = \n",m,n,result);
-		for (i=0; i<m; i++) {
-			fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
-			if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
-		}
-		fprintf(adjustLogFile,"\n");
-		fflush(adjustLogFile);
-	}
-
-	return 0;
+                }
+                
+                // Field-of-view stabilization.  Applying here means that the
+                // errors seen by the optimizer may be different from those finally
+                // reported, by the same factor for all errors.  This introduces
+                // the possibility of confusion for people who are paying really
+                // close attention to the optimizer's periodic output versus the
+                // final result.  However, it seems like the right thing to do
+                // because then the final reported errors will correspond to the
+                // user's settings for pano size, total fov etc. 
+                
+                if ((initialAvgFov / avgfovFromSAP) > 1.0) {
+                        fvec[iresult] *= initialAvgFov / avgfovFromSAP;
+                }
+                iresult += 1;
+                if (fcnPanoNperCP == 2) {
+                        if ((initialAvgFov / avgfovFromSAP) > 1.0) {
+                                fvec[iresult] *= initialAvgFov / avgfovFromSAP;
+                        }
+                        iresult += 1;
+                }               
+        }
+        
+        // If not enough control points are provided, then fill out
+        // the function vector with copies of the average error
+        // for the actual control points.
+
+        result = 0.0;
+        for (i=0; i < iresult; i++) {
+                result += fvec[i]*fvec[i];
+        }
+        result = sqrt(result/(double)iresult);
+        for (i=iresult; i < m; i++) {
+                fvec[i] = result;
+        }
+
+        if (adjustLogFile != 0) {
+                result *= sqrt((double)fcnPanoNperCP);
+                fprintf(adjustLogFile,"leaving fcnPano, m=%d, n=%d, err=%g, fvec = \n",m,n,result);
+                for (i=0; i<m; i++) {
+                        fprintf(adjustLogFile,"\t%20.10g",fvec[i]);
+                        if (((i+1) % fcnPanoNperCP) == 0) fprintf(adjustLogFile,"\n");
+                }
+                fprintf(adjustLogFile,"\n");
+                fflush(adjustLogFile);
+        }
+
+        return 0;
 }
 
 
@@ -2150,113 +2141,113 @@
 //      buf = coeff[0] * src + coeff[1]
 #if 1
 void GetColCoeff( Image *src, Image *buf, double ColCoeff[3][2] ){
-	register int 		x,y,c1,c2,i, numPts;
-	double 			xy[3], xi[3], xi2[3], yi[3], xav[3], yav[3];
-	register unsigned char 	*source, *buff;
-	int			BitsPerChannel,bpp;
-
-
-	
-	GetBitsPerChannel( src, BitsPerChannel );
-	bpp = src->bitsPerPixel/8;
-	
-
-	source = *(src->data);
-	buff   = *(buf->data);
-	
-	for(i=0;i<3;i++){
-		xy[i] = xi[i] = xi2[i] = yi[i] = 0.0;
-	}
-	numPts = 0;	
-
-	if( BitsPerChannel == 8 ){
-		for( y=2; y<src->height-2; y++){
-			c1 = y * src->bytesPerLine;
-			for( x=2; x<src->width-2; x++){
-				c2 = c1 + x*bpp;
-				if( source[c2] != 0  &&  buff[c2] != 0 ){ // &&   // In overlap region?
-				    //(source[c2] != UCHAR_MAX  ||  buff[c2] != UCHAR_MAX)){ // above seam?
-					if( pt_average( source+c2, src->bytesPerLine, xav, 1 ) &&
-					    pt_average( buff+c2, src->bytesPerLine, yav, 1 ) ){
-						numPts++;
-						for( i=0; i<3; i++){
-							xi[i]	+= xav[i];
-							yi[i]	+= yav[i];
-							xi2[i] 	+= xav[i]*xav[i];
-							xy[i]	+= xav[i]*yav[i];
-						}
-					}
-				}
-			}
-		}
-	}else{//16
-		for( y=1; y<src->height-1; y++){
-			c1 = y * src->bytesPerLine;
-			for( x=1; x<src->width-1; x++){
-				c2 = c1 + x*bpp;
-				if( *((USHORT*)(source + c2)) != 0  &&  *((USHORT*)(buff + c2)) != 0 ) { //&& // In overlap region?
-				 //( *((USHORT*)(source + c2)) != USHRT_MAX  ||  *((USHORT*)(buff + c2)) != USHRT_MAX ) ){ // above seam?
-					if( pt_average( source + c2, src->bytesPerLine, xav, 2 ) &&
-					    pt_average( buff + c2, src->bytesPerLine, yav, 2 )){
-						numPts++;
-						for( i=0; i<3; i++){
-							xi[i]	+= xav[i];
-							yi[i]	+= yav[i];
-							xi2[i] 	+= xav[i]*xav[i];
-							xy[i]	+= xav[i]*yav[i];
-						}
-					}
-				}
-			}
-		}
-	}
-		
-	
-	if( numPts > 0 ){
-		for( i=0; i<3; i++){
-			ColCoeff[i][0] = ( numPts * xy[i] - xi[i] * yi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
-			ColCoeff[i][1] = ( xi2[i] * yi[i] - xy[i] * xi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
-		}
-	}else{
-		for( i=0; i<3; i++){
-			ColCoeff[i][0] = 1.0;
-			ColCoeff[i][1] = 0.0;
-		}
-	}
+        register int            x,y,c1,c2,i, numPts;
+        double                  xy[3], xi[3], xi2[3], yi[3], xav[3], yav[3];
+        register unsigned char  *source, *buff;
+        int                     BitsPerChannel,bpp;
+
+
+        
+        GetBitsPerChannel( src, BitsPerChannel );
+        bpp = src->bitsPerPixel/8;
+        
+
+        source = *(src->data);
+        buff   = *(buf->data);
+        
+        for(i=0;i<3;i++){
+                xy[i] = xi[i] = xi2[i] = yi[i] = 0.0;
+        }
+        numPts = 0;     
+
+        if( BitsPerChannel == 8 ){
+                for( y=2; y<src->height-2; y++){
+                        c1 = y * src->bytesPerLine;
+                        for( x=2; x<src->width-2; x++){
+                                c2 = c1 + x*bpp;
+                                if( source[c2] != 0  &&  buff[c2] != 0 ){ // &&   // In overlap region?
+                                    //(source[c2] != UCHAR_MAX  ||  buff[c2] != UCHAR_MAX)){ // above seam?
+                                        if( pt_average( source+c2, src->bytesPerLine, xav, 1 ) &&
+                                            pt_average( buff+c2, src->bytesPerLine, yav, 1 ) ){
+                                                numPts++;
+                                                for( i=0; i<3; i++){
+                                                        xi[i]   += xav[i];
+                                                        yi[i]   += yav[i];
+                                                        xi2[i]  += xav[i]*xav[i];
+                                                        xy[i]   += xav[i]*yav[i];
+                                                }
+                                        }
+                                }
+                        }
+                }
+        }else{//16
+                for( y=1; y<src->height-1; y++){
+                        c1 = y * src->bytesPerLine;
+                        for( x=1; x<src->width-1; x++){
+                                c2 = c1 + x*bpp;
+                                if( *((USHORT*)(source + c2)) != 0  &&  *((USHORT*)(buff + c2)) != 0 ) { //&& // In overlap region?
+                                 //( *((USHORT*)(source + c2)) != USHRT_MAX  ||  *((USHORT*)(buff + c2)) != USHRT_MAX ) ){ // above seam?
+                                        if( pt_average( source + c2, src->bytesPerLine, xav, 2 ) &&
+                                            pt_average( buff + c2, src->bytesPerLine, yav, 2 )){
+                                                numPts++;
+                                                for( i=0; i<3; i++){
+                                                        xi[i]   += xav[i];
+                                                        yi[i]   += yav[i];
+                                                        xi2[i]  += xav[i]*xav[i];
+                                                        xy[i]   += xav[i]*yav[i];
+                                                }
+                                        }
+                                }
+                        }
+                }
+        }
+                
+        
+        if( numPts > 0 ){
+                for( i=0; i<3; i++){
+                        ColCoeff[i][0] = ( numPts * xy[i] - xi[i] * yi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
+                        ColCoeff[i][1] = ( xi2[i] * yi[i] - xy[i] * xi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
+                }
+        }else{
+                for( i=0; i<3; i++){
+                        ColCoeff[i][0] = 1.0;
+                        ColCoeff[i][1] = 0.0;
+                }
+        }
 }
 #endif
 // Average 9 pixels
 int pt_average( UCHAR* pixel, int BytesPerLine, double rgb[3], int bytesPerChannel ){
-	int x, y, i;
-	UCHAR *px;
-	double sum = 1.0 + 4 * 0.5 + 8 * 0.2 + 8 * 0.1 ;//2.6;
+        int x, y, i;
+        UCHAR *px;
+        double sum = 1.0 + 4 * 0.5 + 8 * 0.2 + 8 * 0.1 ;//2.6;
 #if 0
-	double bl[3][3] =      {{ 0.1, 0.3, 0.1}, // Blurr overlap using this matrix
-				{ 0.3, 1.0, 0.3},
-				{ 0.1, 0.3, 0.1}};
+        double bl[3][3] =      {{ 0.1, 0.3, 0.1}, // Blurr overlap using this matrix
+                                { 0.3, 1.0, 0.3},
+                                { 0.1, 0.3, 0.1}};
 
 #endif
-	double bl[5][5] =      {{ 0.0, 0.1, 0.2, 0.1, 0.0},
-				{ 0.1, 0.2, 0.5, 0.2, 0.1},
-				{ 0.2, 0.5, 1.0, 0.5, 0.2},
-				{ 0.1, 0.2, 0.5, 0.2, 0.1},
-				{ 0.0, 0.1, 0.2, 0.1, 0.0}};
-
-
-	rgb[0] = rgb[1] = rgb[2] = 0.0;
-	if( bytesPerChannel != 1 ) return -1;
-
-	for(y=0; y<5; y++){
-		for(x=0; x<5; x++){
-			px = pixel + (y-2)*BytesPerLine + x-2;
-			if( *px == 0 ) return 0;
-			rgb[0] +=  *(++px) * bl[y][x];
-			rgb[1] +=  *(++px) * bl[y][x];
-			rgb[2] +=  *(++px) * bl[y][x];
-		}
-	}
-	for( i=0; i<3; i++) rgb[i]/=sum;
-	return 0;
+        double bl[5][5] =      {{ 0.0, 0.1, 0.2, 0.1, 0.0},
+                                { 0.1, 0.2, 0.5, 0.2, 0.1},
+                                { 0.2, 0.5, 1.0, 0.5, 0.2},
+                                { 0.1, 0.2, 0.5, 0.2, 0.1},
+                                { 0.0, 0.1, 0.2, 0.1, 0.0}};
+
+
+        rgb[0] = rgb[1] = rgb[2] = 0.0;
+        if( bytesPerChannel != 1 ) return -1;
+
+        for(y=0; y<5; y++){
+                for(x=0; x<5; x++){
+                        px = pixel + (y-2)*BytesPerLine + x-2;
+                        if( *px == 0 ) return 0;
+                        rgb[0] +=  *(++px) * bl[y][x];
+                        rgb[1] +=  *(++px) * bl[y][x];
+                        rgb[2] +=  *(++px) * bl[y][x];
+                }
+        }
+        for( i=0; i<3; i++) rgb[i]/=sum;
+        return 0;
 
 }
 
@@ -2272,87 +2263,87 @@
 
 void GetColCoeff( Image *src, Image *buf, double ColCoeff[3][2] )
 {
-	register int x,y,c1,c2,i, numPts;
-	double xy[3], xi[3], xi2[3], yi[3];
-	register unsigned char *source, *buff;
-	int		BitsPerChannel,bpp;
-	
-	GetBitsPerChannel( src, BitsPerChannel );
-	bpp = src->bitsPerPixel/8;
-	
-
-	source = *(src->data);
-	buff   = *(buf->data);
-	for(i=0;i<3;i++)
-	{
-		xy[i] = xi[i] = xi2[i] = yi[i] = 0.0;
-	}
-	numPts = 0;	
-
-	if( BitsPerChannel == 8 )
-	{
-		for( y=0; y<src->height; y++)
-		{
-			c1 = y * src->bytesPerLine;
-			for( x=0; x<src->width; x++)
-			{
-				c2 = c1 + x*bpp;
-				if( source[c2] != 0  &&  buff[c2] != 0 ) // In overlap region?
-				{
-					numPts++;
-					for( i=0; i<3; i++)
-					{
-						c2++;
-						xi[i]	+= (double)source[c2];
-						yi[i]	+= (double)buff[c2];
-						xi2[i] 	+= ((double)source[c2])*((double)source[c2]);
-						xy[i]	+= ((double)source[c2])*((double)buff[c2]);
-					}
-				}
-			}
-		}
-	}
-	else // 16
-	{
-		for( y=0; y<src->height; y++)
-		{
-			c1 = y * src->bytesPerLine;
-			for( x=0; x<src->width; x++)
-			{
-				c2 = c1 + x*bpp;
-				if( *((USHORT*)(source + c2)) != 0  &&  *((USHORT*)(buff + c2)) != 0 ) // In overlap region?
-				{
-					numPts++;
-					for( i=0; i<3; i++)
-					{
-						c2++;
-						xi[i]	+= (double) *((USHORT*)(source + c2));
-						yi[i]	+= (double) *((USHORT*)(buff + c2));
-						xi2[i] 	+= ((double) *((USHORT*)(source + c2)))*((double) *((USHORT*)(source + c2)));
-						xy[i]	+= ((double) *((USHORT*)(source + c2)))*((double) *((USHORT*)(buff + c2)));
-					}
-				}
-			}
-		}
-	}
-		
-	
-	if( numPts > 0 )
-	{
-		for( i=0; i<3; i++)
-		{
-			ColCoeff[i][0] = ( numPts * xy[i] - xi[i] * yi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
-			ColCoeff[i][1] = ( xi2[i] * yi[i] - xy[i] * xi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
-		}
-	}
-	else
-	{
-		for( i=0; i<3; i++)
-		{
-			ColCoeff[i][0] = 1.0;
-			ColCoeff[i][1] = 0.0;
-		}
-	}
+        register int x,y,c1,c2,i, numPts;
+        double xy[3], xi[3], xi2[3], yi[3];
+        register unsigned char *source, *buff;
+        int             BitsPerChannel,bpp;
+        
+        GetBitsPerChannel( src, BitsPerChannel );
+        bpp = src->bitsPerPixel/8;
+        
+
+        source = *(src->data);
+        buff   = *(buf->data);
+        for(i=0;i<3;i++)
+        {
+                xy[i] = xi[i] = xi2[i] = yi[i] = 0.0;
+        }
+        numPts = 0;     
+
+        if( BitsPerChannel == 8 )
+        {
+                for( y=0; y<src->height; y++)
+                {
+                        c1 = y * src->bytesPerLine;
+                        for( x=0; x<src->width; x++)
+                        {
+                                c2 = c1 + x*bpp;
+                                if( source[c2] != 0  &&  buff[c2] != 0 ) // In overlap region?
+                                {
+                                        numPts++;
+                                        for( i=0; i<3; i++)
+                                        {
+                                                c2++;
+                                                xi[i]   += (double)source[c2];
+                                                yi[i]   += (double)buff[c2];
+                                                xi2[i]  += ((double)source[c2])*((double)source[c2]);
+                                                xy[i]   += ((double)source[c2])*((double)buff[c2]);
+                                        }
+                                }
+                        }
+                }
+        }
+        else // 16
+        {
+                for( y=0; y<src->height; y++)
+                {
+                        c1 = y * src->bytesPerLine;
+                        for( x=0; x<src->width; x++)
+                        {
+                                c2 = c1 + x*bpp;
+                                if( *((USHORT*)(source + c2)) != 0  &&  *((USHORT*)(buff + c2)) != 0 ) // In overlap region?
+                                {
+                                        numPts++;
+                                        for( i=0; i<3; i++)
+                                        {
+                                                c2++;
+                                                xi[i]   += (double) *((USHORT*)(source + c2));
+                                                yi[i]   += (double) *((USHORT*)(buff + c2));
+                                                xi2[i]  += ((double) *((USHORT*)(source + c2)))*((double) *((USHORT*)(source + c2)));
+                                                xy[i]   += ((double) *((USHORT*)(source + c2)))*((double) *((USHORT*)(buff + c2)));
+                                        }
+                                }
+                        }
+                }
+        }
+                
+        
+        if( numPts > 0 )
+        {
+                for( i=0; i<3; i++)
+                {
+                        ColCoeff[i][0] = ( numPts * xy[i] - xi[i] * yi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
+                        ColCoeff[i][1] = ( xi2[i] * yi[i] - xy[i] * xi[i] ) / ( numPts * xi2[i] - xi[i]*xi[i] );
+                }
+        }
+        else
+        {
+                for( i=0; i<3; i++)
+                {
+                        ColCoeff[i][0] = 1.0;
+                        ColCoeff[i][1] = 0.0;
+                }
+        }
 }
 
 #endif
@@ -2364,56 +2355,56 @@
 
 void ColCorrect( Image *im, double ColCoeff[3][2] )
 {
-	register int x,y, c1, c2, i;
-	register unsigned char* data;
-	register double result;
-	int bpp, BitsPerChannel;
-	
-	GetBitsPerChannel( im, BitsPerChannel );
-	bpp = im->bitsPerPixel/8;
-
-	data = *(im->data);
-
-	if( BitsPerChannel == 8 )
-	{
-		for( y=0; y<im->height; y++)
-		{
-			c1 = y * im->bytesPerLine;
-			for( x=0; x<im->width; x++ )
-			{
-				c2 = c1 + x * bpp;
-				if( data[ c2 ] != 0 ) // Alpha channel set
-				{
-					for( i=0; i<3; i++)
-					{
-						c2++;
-						result = ColCoeff[i][0] * data[ c2 ] + ColCoeff[i][1];
-						DBL_TO_UC( data[ c2 ], result );
-					}
-				}
-			}
-		}
-	}
-	else // 16
-	{
-		for( y=0; y<im->height; y++)
-		{
-			c1 = y * im->bytesPerLine;
-			for( x=0; x<im->width; x++ )
-			{
-				c2 = c1 + x * bpp;
-				if( *((USHORT*)(data + c2 )) != 0 ) // Alpha channel set
-				{
-					for( i=0; i<3; i++)
-					{
-						c2++;
-						result = ColCoeff[i][0] * *((USHORT*)(data + c2 )) + ColCoeff[i][1];
-						DBL_TO_US( *((USHORT*)(data + c2 )) , result );
-					}
-				}
-			}
-		}
-	}
+        register int x,y, c1, c2, i;
+        register unsigned char* data;
+        register double result;
+        int bpp, BitsPerChannel;
+        
+        GetBitsPerChannel( im, BitsPerChannel );
+        bpp = im->bitsPerPixel/8;
+
+        data = *(im->data);
+
+        if( BitsPerChannel == 8 )
+        {
+                for( y=0; y<im->height; y++)
+                {
+                        c1 = y * im->bytesPerLine;
+                        for( x=0; x<im->width; x++ )
+                        {
+                                c2 = c1 + x * bpp;
+                                if( data[ c2 ] != 0 ) // Alpha channel set
+                                {
+                                        for( i=0; i<3; i++)
+                                        {
+                                                c2++;
+                                                result = ColCoeff[i][0] * data[ c2 ] + ColCoeff[i][1];
+                                                DBL_TO_UC( data[ c2 ], result );
+                                        }
+                                }
+                        }
+                }
+        }
+        else // 16
+        {
+                for( y=0; y<im->height; y++)
+                {
+                        c1 = y * im->bytesPerLine;
+                        for( x=0; x<im->width; x++ )
+                        {
+                                c2 = c1 + x * bpp;
+                                if( *((USHORT*)(data + c2 )) != 0 ) // Alpha channel set
+                                {
+                                        for( i=0; i<3; i++)
+                                        {
+                                                c2++;
+                                                result = ColCoeff[i][0] * *((USHORT*)(data + c2 )) + ColCoeff[i][1];
+                                                DBL_TO_US( *((USHORT*)(data + c2 )) , result );
+                                        }
+                                }
+                        }
+                }
+        }
 }
 
 
@@ -2439,15 +2430,15 @@
     prefs->fastStep     = FAST_TRANSFORM_STEP_NONE;
 }
 
-				
-
-void 	DisposeAlignInfo( struct AlignInfo *g )
+                                
+
+void    DisposeAlignInfo( struct AlignInfo *g )
 {
-	if(g->im != NULL) free(g->im);
-	if(g->opt!= NULL) free(g->opt);
-	if(g->cpt!= NULL) free(g->cpt);
-	if(g->t  != NULL) free(g->t);
-	if(g->cim != NULL) free(g->cim);
+        if(g->im != NULL) free(g->im);
+        if(g->opt!= NULL) free(g->opt);
+        if(g->cpt!= NULL) free(g->cpt);
+        if(g->t  != NULL) free(g->t);
+        if(g->cim != NULL) free(g->cim);
 }
 
 
@@ -2455,94 +2446,130 @@
 
 // Set global preferences structures using LM-params
 
-int	SetAlignParams( double *x )
+int     SetAlignParams( double *x )
 {
-	// Set Parameters
-	int i,j,k;
-	double sumfov = 0.0;
-	
-	j = 0;
-	
-	for( i=0; i<g->numIm; i++ ){
-		if( (k = g->opt[i].yaw) > 0 ){
-			if( k == 1 ){	g->im[i].yaw  =	x[j++];	NORM_ANGLE( g->im[i].yaw );
-			}else{	g->im[i].yaw  =	g->im[k-2].yaw;	}
-		}
-		if( (k = g->opt[i].pitch) > 0 ){
-			if( k == 1 ){	g->im[i].pitch  =	x[j++];	NORM_ANGLE( g->im[i].pitch );
-			}else{	g->im[i].pitch  =	g->im[k-2].pitch;	}
-		}
-		if( (k = g->opt[i].roll) > 0 ){
-			if( k == 1 ){	g->im[i].roll  =	x[j++];	NORM_ANGLE( g->im[i].roll );
-			}else{	g->im[i].roll  =	g->im[k-2].roll;	}
-		}
-		if( (k = g->opt[i].hfov) > 0 ){
-			if( k == 1 ){	
-				g->im[i].hfov  =	x[j++];	
-				if( g->im[i].hfov < 0.0 )
-					g->im[i].hfov = - g->im[i].hfov;
-			}else{	g->im[i].hfov  = g->im[k-2].hfov;	}
-		}
-		sumfov += g->im[i].hfov;
-		if( (k = g->opt[i].a) > 0 ){
-			if( k == 1 ){ g->im[i].cP.radial_params[0][3]  =	x[j++] / C_FACTOR;
-			}else{	g->im[i].cP.radial_params[0][3] = g->im[k-2].cP.radial_params[0][3];}
-		}
-		if( (k = g->opt[i].b) > 0 ){
-			if( k == 1 ){ g->im[i].cP.radial_params[0][2]  =	x[j++] / C_FACTOR;
-			}else{	g->im[i].cP.radial_params[0][2] = g->im[k-2].cP.radial_params[0][2];}
-		}
-		if( (k = g->opt[i].c) > 0 ){
-			if( k == 1 ){ g->im[i].cP.radial_params[0][1]  =	x[j++] / C_FACTOR;
-			}else{	g->im[i].cP.radial_params[0][1] = g->im[k-2].cP.radial_params[0][1];}
-		}
-		if( (k = g->opt[i].d) > 0 ){
-			if( k == 1 ){ g->im[i].cP.horizontal_params[0]  =	x[j++];
-			}else{	g->im[i].cP.horizontal_params[0] = g->im[k-2].cP.horizontal_params[0];}
-		}
-		if( (k = g->opt[i].e) > 0 ){
-			if( k == 1 ){ g->im[i].cP.vertical_params[0]  =	x[j++];
-			}else{	g->im[i].cP.vertical_params[0] = g->im[k-2].cP.vertical_params[0];}
-		}
+        // Set Parameters
+        int i,j,k;
+        double sumfov = 0.0;
+        
+        j = 0;
+        for( i=0; i<optInfo->numIm; i++ ){
+
+                if( (k = optInfo->opt[i].yaw) > 0 ){
+                        if( k == 1 ){   optInfo->im[i].yaw  = x[j++]; NORM_ANGLE( optInfo->im[i].yaw );
+                        }else{  optInfo->im[i].yaw  = optInfo->im[k-2].yaw; }
+                }
+                if( (k = optInfo->opt[i].pitch) > 0 ){
+                        if( k == 1 ){   optInfo->im[i].pitch  =       x[j++]; NORM_ANGLE( optInfo->im[i].pitch );
+                        }else{  optInfo->im[i].pitch  =       optInfo->im[k-2].pitch;       }
+                }
+                if( (k = optInfo->opt[i].roll) > 0 ){
+                        if( k == 1 ){   optInfo->im[i].roll  =        x[j++]; NORM_ANGLE( optInfo->im[i].roll );
+                        }else{  optInfo->im[i].roll  =        optInfo->im[k-2].roll;        }
+                }
+                if( (k = optInfo->opt[i].hfov) > 0 ){
+                        if( k == 1 ){   
+                                optInfo->im[i].hfov  =        x[j++]; 
+                                if( optInfo->im[i].hfov < 0.0 )
+                                        optInfo->im[i].hfov = - optInfo->im[i].hfov;
+                        }else{  optInfo->im[i].hfov  = optInfo->im[k-2].hfov; }
+                }
+                sumfov += optInfo->im[i].hfov;
+                if( (k = optInfo->opt[i].a) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.radial_params[0][3]  =  x[j++] / C_FACTOR;
+                        }else{  optInfo->im[i].cP.radial_params[0][3] = optInfo->im[k-2].cP.radial_params[0][3];}
+                }
+                if( (k = optInfo->opt[i].b) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.radial_params[0][2]  =  x[j++] / C_FACTOR;
+                        }else{  optInfo->im[i].cP.radial_params[0][2] = optInfo->im[k-2].cP.radial_params[0][2];}
+                }
+                if( (k = optInfo->opt[i].c) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.radial_params[0][1]  =  x[j++] / C_FACTOR;
+                        }else{  optInfo->im[i].cP.radial_params[0][1] = optInfo->im[k-2].cP.radial_params[0][1];}
+                }
+                if( (k = optInfo->opt[i].d) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.horizontal_params[0]  = x[j++];
+                        }else{  optInfo->im[i].cP.horizontal_params[0] = optInfo->im[k-2].cP.horizontal_params[0];}
+                }
+                if( (k = optInfo->opt[i].e) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.vertical_params[0]  =   x[j++];
+                        }else{  optInfo->im[i].cP.vertical_params[0] = optInfo->im[k-2].cP.vertical_params[0];}
+                }
                 // tilt
-		if( (k = g->opt[i].tiltX) > 0 ){
-			if( k == 1 ){ g->im[i].cP.tilt_x  =	x[j++];
-			}else{	g->im[i].cP.tilt_x = g->im[k-2].cP.tilt_x;}
-		}
-		if( (k = g->opt[i].tiltY) > 0 ){
-			if( k == 1 ){ g->im[i].cP.tilt_y  =	x[j++];
-			}else{	g->im[i].cP.tilt_y = g->im[k-2].cP.tilt_y;}
-		}
-		if( (k = g->opt[i].tiltZ) > 0 ){
-			if( k == 1 ){ g->im[i].cP.tilt_z  =	x[j++];
-			}else{	g->im[i].cP.tilt_z = g->im[k-2].cP.tilt_z;}
-		}
-		if( (k = g->opt[i].tiltScale) > 0 ){
-			if( k == 1 ){ g->im[i].cP.tilt_scale  =	x[j++];
-			}else{	g->im[i].cP.tilt_scale = g->im[k-2].cP.tilt_scale;}
-		}
+                if( (k = optInfo->opt[i].tiltXopt) > 0 ){
+                    if( k == 1 ){ optInfo->im[i].cP.tilt_x  = x[j++]; NORM_ANGLE_RAD(optInfo->im[i].cP.tilt_x);
+                    }else{  optInfo->im[i].cP.tilt_x = optInfo->im[k-2].cP.tilt_x;}
+                }
+                if( (k = optInfo->opt[i].tiltYopt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.tilt_y  = x[j++]; NORM_ANGLE_RAD(optInfo->im[i].cP.tilt_y);
+                        }else{  optInfo->im[i].cP.tilt_y = optInfo->im[k-2].cP.tilt_y;}
+                }
+                if( (k = optInfo->opt[i].tiltZopt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.tilt_z  =       x[j++];NORM_ANGLE_RAD(optInfo->im[i].cP.tilt_z);
+                        }else{  optInfo->im[i].cP.tilt_z = optInfo->im[k-2].cP.tilt_z;}
+                }
+                if( (k = optInfo->opt[i].tiltScaleOpt) > 0 ){
+                    if( k == 1 ) { 
+                        optInfo->im[i].cP.tilt_scale  = x[j++]; 
+                        if (optInfo->im[i].cP.tilt_scale == 0) {
+                            optInfo->im[i].cP.tilt_scale = 0.001; //make sure it never becomes zero
+                        }
+                        optInfo->im[i].cP.tilt_scale = fabs(optInfo->im[i].cP.tilt_scale);
+                    } else{  optInfo->im[i].cP.tilt_scale = optInfo->im[k-2].cP.tilt_scale;}
+                }
+                // translate
+                if( (k = optInfo->opt[i].transXopt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.trans_x  =      x[j++];
+                        }else{  optInfo->im[i].cP.trans_x = optInfo->im[k-2].cP.trans_x;}
+                }
+                if( (k = optInfo->opt[i].transYopt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.trans_y  =      x[j++];
+                        }else{  optInfo->im[i].cP.trans_y = optInfo->im[k-2].cP.trans_y;}
+                }
+                if( (k = optInfo->opt[i].transZopt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.trans_z  =      x[j++];
+                        }else{  optInfo->im[i].cP.trans_z = optInfo->im[k-2].cP.trans_z;}
+                }
+                // test
+                if( (k = optInfo->opt[i].testP0opt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.test_p0  =      x[j++];
+                        }else{  optInfo->im[i].cP.test_p0 = optInfo->im[k-2].cP.test_p0;}
+                }
+                if( (k = optInfo->opt[i].testP1opt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.test_p1  =      x[j++];
+                        }else{  optInfo->im[i].cP.test_p1 = optInfo->im[k-2].cP.test_p1;}
+                }
+                if( (k = optInfo->opt[i].testP2opt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.test_p2  =      x[j++];
+                        }else{  optInfo->im[i].cP.test_p2 = optInfo->im[k-2].cP.test_p2;}
+                }
+                if( (k = optInfo->opt[i].testP3opt) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.test_p3  =      x[j++];
+                        }else{  optInfo->im[i].cP.test_p3 = optInfo->im[k-2].cP.test_p3;}
+                }
+
                 //shear
-		if( (k = g->opt[i].shear_x) > 0 ){
-			if( k == 1 ){ g->im[i].cP.shear_x  =	x[j++];
-			}else{	g->im[i].cP.shear_x = g->im[k-2].cP.shear_x;}
-		}
-
-		if( (k = g->opt[i].shear_y) > 0 ){
-			if( k == 1 ){ g->im[i].cP.shear_y  =	x[j++];
-			}else{	g->im[i].cP.shear_y = g->im[k-2].cP.shear_y;}
-		}
-
-		
-		g->im[i].cP.radial_params[0][0] = 1.0 - ( g->im[i].cP.radial_params[0][3]
-														+ g->im[i].cP.radial_params[0][2]
-														+ g->im[i].cP.radial_params[0][1] ) ;
-
-	}
-	avgfovFromSAP = sumfov / g->numIm;
-	if( j != g->numParam )
-		return -1;
-	else
-		return 0;
+                if( (k = optInfo->opt[i].shear_x) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.shear_x  =      x[j++];
+                        }else{  optInfo->im[i].cP.shear_x = optInfo->im[k-2].cP.shear_x;}
+                }
+
+                if( (k = optInfo->opt[i].shear_y) > 0 ){
+                        if( k == 1 ){ optInfo->im[i].cP.shear_y  =      x[j++];
+                        }else{  optInfo->im[i].cP.shear_y = optInfo->im[k-2].cP.shear_y;}
+                }
+
+                
+                optInfo->im[i].cP.radial_params[0][0] = 1.0 - ( optInfo->im[i].cP.radial_params[0][3]
+                                                                                                                + optInfo->im[i].cP.radial_params[0][2]
+                                                                                                                + optInfo->im[i].cP.radial_params[0][1] ) ;
+
+        }
+        avgfovFromSAP = sumfov / optInfo->numIm;
+        if( j != optInfo->numParam )
+                return -1;
+        else
+                return 0;
 
 }
 
@@ -2551,69 +2578,93 @@
 
 int SetLMParams( double *x )
 {
-	int i,j;
-		
-	j=0; // Counter for optimization parameters
-
-
-	for( i=0; i<g->numIm; i++ ){
-		if(g->opt[i].yaw == 1)  //  optimize alpha? 0-no 1-yes
-			x[j++] = g->im[i].yaw;
-
-		if(g->opt[i].pitch == 1)  //  optimize pitch? 0-no 1-yes
-			x[j++] = g->im[i].pitch; 
-
-		if(g->opt[i].roll == 1)  //  optimize gamma? 0-no 1-yes
-			x[j++] = g->im[i].roll ; 
-
-		if(g->opt[i].hfov == 1)  //  optimize hfov? 0-no 1-yes
-			x[j++] = g->im[i].hfov ; 
-
-		if(g->opt[i].a == 1)  //  optimize a? 0-no 1-yes
-			x[j++] =  g->im[i].cP.radial_params[0][3] * C_FACTOR; 
-
-		if(g->opt[i].b == 1)   //  optimize b? 0-no 1-yes
-			x[j++] = g->im[i].cP.radial_params[0][2] * C_FACTOR; 
-
-		if(g->opt[i].c == 1)  //  optimize c? 0-no 1-yes
-			x[j++] = g->im[i].cP.radial_params[0][1] * C_FACTOR; 
-
-		if(g->opt[i].d == 1)  //  optimize d? 0-no 1-yes
-			x[j++] = g->im[i].cP.horizontal_params[0] ; 
-
-		if(g->opt[i].e == 1)  //  optimize e? 0-no 1-yes
-			x[j++] = g->im[i].cP.vertical_params[0]  ; 
-
-		if(g->opt[i].tiltX == 1) { //  optimize tilt_x? 0-no 1-yes
-			x[j++] = g->im[i].cP.tilt_x  ;
-                }
-
-		if(g->opt[i].tiltY == 1)  //  optimize tilt_y? 0-no 1-yes
-			x[j++] = g->im[i].cP.tilt_y  ;
-
-		if(g->opt[i].tiltZ == 1) { //  optimize tilt_Z? 0-no 1-yes
-			x[j++] = g->im[i].cP.tilt_z  ;
-                }
-		if(g->opt[i].tiltScale == 1) { //  optimize tilt_scale? 0-no 1-yes
-			x[j++] = g->im[i].cP.tilt_scale  ;
-                }
-		if(g->opt[i].shear_x == 1)  //  optimize shear_x? 0-no 1-yes
-			x[j++] = g->im[i].cP.shear_x  ;
-
-		if(g->opt[i].shear_y == 1)  //  optimize shear_y? 0-no 1-yes
-			x[j++] = g->im[i].cP.shear_y  ;
-	}
-	
-	if( j != g->numParam )
-		return -1;
-	else
-		return 0;
-
-}
-
-
-
-		
+        int i,j;
+                
+        j=0; // Counter for optimization parameters
+
+
+        for( i=0; i<optInfo->numIm; i++ ){
+                if(optInfo->opt[i].yaw == 1)  //  optimize alpha? 0-no 1-yes
+                        x[j++] = optInfo->im[i].yaw;
+
+                if(optInfo->opt[i].pitch == 1)  //  optimize pitch? 0-no 1-yes
+                        x[j++] = optInfo->im[i].pitch; 
+
+                if(optInfo->opt[i].roll == 1)  //  optimize gamma? 0-no 1-yes
+                        x[j++] = optInfo->im[i].roll ; 
+
+                if(optInfo->opt[i].hfov == 1)  //  optimize hfov? 0-no 1-yes
+                        x[j++] = optInfo->im[i].hfov ; 
+
+                if(optInfo->opt[i].a == 1)  //  optimize a? 0-no 1-yes
+                        x[j++] =  optInfo->im[i].cP.radial_params[0][3] * C_FACTOR; 
+
+                if(optInfo->opt[i].b == 1)   //  optimize b? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.radial_params[0][2] * C_FACTOR; 
+
+                if(optInfo->opt[i].c == 1)  //  optimize c? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.radial_params[0][1] * C_FACTOR; 
+
+                if(optInfo->opt[i].d == 1)  //  optimize d? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.horizontal_params[0] ; 
+
+                if(optInfo->opt[i].e == 1)  //  optimize e? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.vertical_params[0]  ; 
+
+                // Tilt
+                if(optInfo->opt[i].tiltXopt == 1) { //  optimize tilt_x? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.tilt_x  ;
+                }
+                if(optInfo->opt[i].tiltYopt == 1)  //  optimize tilt_y? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.tilt_y  ;
+
+                if(optInfo->opt[i].tiltZopt == 1) { //  optimize tilt_Z? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.tilt_z  ;
+                }
+                if(optInfo->opt[i].tiltScaleOpt == 1) { //  optimize tilt_scale? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.tilt_scale  ;
+                }
+                // Trans
+                if(optInfo->opt[i].transXopt == 1) { //  optimize trans_x? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.trans_x  ;
+                }
+                if(optInfo->opt[i].transYopt == 1)  //  optimize trans_y? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.trans_y  ;
+
+                if(optInfo->opt[i].transZopt == 1) { //  optimize trans_Z? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.trans_z  ;
+                }
+                // Test
+                if(optInfo->opt[i].testP0opt == 1) {
+                    x[j++] = optInfo->im[i].cP.test_p0;  ;
+                }
+                if(optInfo->opt[i].testP1opt == 1) {
+                    x[j++] = optInfo->im[i].cP.test_p1;  ;
+                }
+                if(optInfo->opt[i].testP2opt == 1) {
+                    x[j++] = optInfo->im[i].cP.test_p2;  ;
+                }
+                if(optInfo->opt[i].testP3opt == 1) {
+                    x[j++] = optInfo->im[i].cP.test_p3;  ;
+                }
+
+                if(optInfo->opt[i].shear_x == 1)  //  optimize shear_x? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.shear_x  ;
+
+                if(optInfo->opt[i].shear_y == 1)  //  optimize shear_y? 0-no 1-yes
+                        x[j++] = optInfo->im[i].cP.shear_y  ;
+        }
+        
+        if( j != optInfo->numParam )
+                return -1;
+        else
+                return 0;
+
+}
+
+
+
+                
 
 
 
@@ -2624,160 +2675,162 @@
 
 void getControlPoints( Image *im, controlPoint *cp )
 {
-	int y, x, cy,cx, bpp, r,g,b,n, nim=0, k,i,np;
-	register unsigned char *p,*ch;
-	
-	
-	p = *(im->data);
-	bpp = im->bitsPerPixel/8;
-	if( bpp == 4 )
-	{
-		r = 1; g = 2; b = 3;
-	}
-	else if( bpp == 3 )
-	{		
-		r = 0; g = 1; b = 2;
-	}
-	else
-	{
-		PrintError("Can't read ControlPoints from images with %d Bytes per Pixel", bpp);
-		return;
-	}
-	
-	np = 0;
-	for(y=0; y<im->height; y++)
-	{
-		cy = y * im->bytesPerLine;
-		for(x=0; x<im->width; x++)
-		{
-			cx = cy + bpp * x;
-			if( p[ cx 			+ r ] 	== 0  	&& p[ cx 			+ g ] 	== 255 	&& p[ cx 			+ b ] 	== 0   &&
-				p[ cx + bpp 	+ r ] 	== 255  && p[ cx + bpp 		+ g ] 	== 0 	&& p[ cx + bpp 		+ b ] 	== 0   &&
-				p[ cx + 2*bpp 	+ r ] 	== 0  	&& p[ cx + 2*bpp 	+ g ] 	== 0 	&& p[ cx + 2*bpp 	+ b ] 	== 255 &&
-				p[ cx - bpp 	+ r ] 	== 0  	&& p[ cx - bpp 		+ g ] 	== 0 	&& p[ cx - bpp 		+ b ] 	== 0 )
-			{
-				if(p[cx + 3*bpp + r ] 	== 0  	&& p[ cx + 3*bpp 	+ g ] 	== 255 	&& p[ cx + 3*bpp 	+ b ] 	== 255)
-				{	// Control Point
-					ch = &(p[cx + 4*bpp + r ]);
-					n = 0;
-					while( ch[0] == 255 && ch[1] == 0 && ch[2] == 0 )
-					{
-						n++;
-						ch += bpp;
-					}
-					if( n >= 0 )
-					{
-						k = 0;
-						if( cp[n].num[0] != -1 )
-							k = 1;
-						cp[n].x[k] = x + DX;
-						cp[n].y[k] = y + DY;
-						np++;
-					}
-				}
-				else if(p[cx+3*bpp +r] 	== 255  && p[ cx + 3*bpp 	+ g ] 	== 255 	&& p[ cx + 3*bpp 	+ b ] 	== 0)
-				{	// Image number
-					ch = &(p[cx + 4*bpp + r ]);
-					n = 0;
-					while( ch[0] == 255 && ch[1] == 0 && ch[2] == 0 )
-					{
-						n++;
-						ch += bpp;
-					}
-					if( n >= 0 )
-					{
-						nim = n;
-					}
-				}
-			}
-		}
-	}
-	k = 0;
-	if( cp[0].num[0] != -1 )
-		k = 1;
-	for(i=0; i<np; i++)
-		cp[i].num[k] = nim;
-	
-
-}
-			
-			
+        int y, x, cy,cx, bpp, r,g,b,n, nim=0, k,i,np;
+        register unsigned char *p,*ch;
+        
+        
+        p = *(im->data);
+        bpp = im->bitsPerPixel/8;
+        if( bpp == 4 )
+        {
+                r = 1; g = 2; b = 3;
+        }
+        else if( bpp == 3 )
+        {               
+                r = 0; g = 1; b = 2;
+        }
+        else
+        {
+                PrintError("Can't read ControlPoints from images with %d Bytes per Pixel", bpp);
+                return;
+        }
+        
+        np = 0;
+        for(y=0; y<im->height; y++)
+        {
+                cy = y * im->bytesPerLine;
+                for(x=0; x<im->width; x++)
+                {
+                        cx = cy + bpp * x;
+                        if( p[ cx                       + r ]   == 0    && p[ cx                        + g ]   == 255  && p[ cx                        + b ]   == 0   &&
+                                p[ cx + bpp     + r ]   == 255  && p[ cx + bpp          + g ]   == 0    && p[ cx + bpp          + b ]   == 0   &&
+                                p[ cx + 2*bpp   + r ]   == 0    && p[ cx + 2*bpp        + g ]   == 0    && p[ cx + 2*bpp        + b ]   == 255 &&
+                                p[ cx - bpp     + r ]   == 0    && p[ cx - bpp          + g ]   == 0    && p[ cx - bpp          + b ]   == 0 )
+                        {
+                                if(p[cx + 3*bpp + r ]   == 0    && p[ cx + 3*bpp        + g ]   == 255  && p[ cx + 3*bpp        + b ]   == 255)
+                                {       // Control Point
+                                        ch = &(p[cx + 4*bpp + r ]);
+                                        n = 0;
+                                        while( ch[0] == 255 && ch[1] == 0 && ch[2] == 0 )
+                                        {
+                                                n++;
+                                                ch += bpp;
+                                        }
+                                        if( n >= 0 )
+                                        {
+                                                k = 0;
+                                                if( cp[n].num[0] != -1 )
+                                                        k = 1;
+                                                cp[n].x[k] = x + DX;
+                                                cp[n].y[k] = y + DY;
+                                                np++;
+                                        }
+                                }
+                                else if(p[cx+3*bpp +r]  == 255  && p[ cx + 3*bpp        + g ]   == 255  && p[ cx + 3*bpp        + b ]   == 0)
+                                {       // Image number
+                                        ch = &(p[cx + 4*bpp + r ]);
+                                        n = 0;
+                                        while( ch[0] == 255 && ch[1] == 0 && ch[2] == 0 )
+                                        {
+                                                n++;
+                                                ch += bpp;
+                                        }
+                                        if( n >= 0 )
+                                        {
+                                                nim = n;
+                                        }
+                                }
+                        }
+                }
+        }
+        k = 0;
+        if( cp[0].num[0] != -1 )
+                k = 1;
+        for(i=0; i<np; i++)
+                cp[i].num[k] = nim;
+        
+
+}
+                        
+                        
 // Write Control Point coordinates into script 
 
 void writeControlPoints( controlPoint *cp,char* cdesc )
 {
-	int i;
-	char line[80];
-	
-	*cdesc = 0;
-	for(i=0; i<NUMPTS && cp[i].num[0] != -1; i++)
-	{
-		//sprintf( line, "c n%d N%d x%d y%d X%d Y%d\n", cp[i].num[0], cp[i].num[1], 
-		sprintf( line, "c n%d N%d x%lf y%lf X%lf Y%lf\n", cp[i].num[0], cp[i].num[1], 
-													   cp[i].x[0], cp[i].y[0],
-													   cp[i].x[1], cp[i].y[1]);
-		strcat( cdesc, line );
-	}
-}
-
-
-void	SetStitchDefaults( struct stitchBuffer *sBuf)
+        int i;
+        char line[80];
+        
+        *cdesc = 0;
+        for(i=0; i<NUMPTS && cp[i].num[0] != -1; i++)
+        {
+                //sprintf( line, "c n%d N%d x%d y%d X%d Y%d\n", cp[i].num[0], cp[i].num[1], 
+                sprintf( line, "c n%d N%d x%lf y%lf X%lf Y%lf\n", cp[i].num[0], cp[i].num[1], 
+                                                                                                           cp[i].x[0], cp[i].y[0],
+                                                                                                           cp[i].x[1], cp[i].y[1]);
+                strcat( cdesc, line );
+        }
+}
+
+
+void    SetStitchDefaults( struct stitchBuffer *sBuf)
 {
-	*sBuf->srcName 		= 0;
-	*sBuf->destName 	= 0;
-	sBuf->feather		= 10;			
-	sBuf->colcorrect	= 0;			
-	sBuf->seam			= _middle;	
-}
-
-void		SetOptDefaults( optVars *opt )
+        *sBuf->srcName          = 0;
+        *sBuf->destName         = 0;
+        sBuf->feather           = 10;                   
+        sBuf->colcorrect        = 0;                    
+        sBuf->seam                      = _middle;      
+}
+
+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->tiltX = opt->tiltY = opt->tiltZ = opt->tiltScale = 0;
+    opt->tiltXopt = opt->tiltYopt = opt->tiltZopt = opt->tiltScaleOpt = 0;
+    opt->transXopt = opt->transYopt = opt->transZopt  = 0;
+    opt->testP0opt = opt->testP1opt = opt->testP2opt = opt->testP3opt = 0;
     opt->shear_x = opt->shear_y = 0;
 }
 
 void DoColorCorrection( Image *im1, Image *im2, int mode )
 {
-	double 	ColCoeff [3][2];
-	int 	i;
-
-	switch( mode )
-	{
-		case 0: 
-			break; // no correction
-		case 1: // Correct im1
-			GetColCoeff( im1, im2, ColCoeff );
-			ColCorrect( im1, ColCoeff );
-			break; 
-		case 2: // Correct im2
-			GetColCoeff( im1, im2, ColCoeff );
-			// Invert coefficients
-			for( i = 0;  i<3;  i++)
-			{
-				ColCoeff[i][1] = - ColCoeff[i][1] / ColCoeff[i][0];
-				ColCoeff[i][0] = 1.0/ColCoeff[i][0];
-			}
-			ColCorrect( im2, ColCoeff );
-			break; 
-		case 3: // Correct both halfs									
-			GetColCoeff( im1, im2, ColCoeff );
-			for(i = 0; i<3; i++)
-			{
-				ColCoeff[i][1] =  ColCoeff[i][1] / 2.0 ;
-				ColCoeff[i][0] = (ColCoeff[i][0] + 1.0 ) / 2.0;
-			}
-			ColCorrect( im1, ColCoeff );
-			for(i = 0; i<3; i++)
-			{
-				ColCoeff[i][1] = - ColCoeff[i][1] / ColCoeff[i][0];
-				ColCoeff[i][0] = 1.0 / ColCoeff[i][0];
-			}
-			ColCorrect( im2, ColCoeff );
-			break;
-		default: break;
-	} // switch
+        double  ColCoeff [3][2];
+        int     i;
+
+        switch( mode )
+        {
+                case 0: 
+                        break; // no correction
+                case 1: // Correct im1
+                        GetColCoeff( im1, im2, ColCoeff );
+                        ColCorrect( im1, ColCoeff );
+                        break; 
+                case 2: // Correct im2
+                        GetColCoeff( im1, im2, ColCoeff );
+                        // Invert coefficients
+                        for( i = 0;  i<3;  i++)
+                        {
+                                ColCoeff[i][1] = - ColCoeff[i][1] / ColCoeff[i][0];
+                                ColCoeff[i][0] = 1.0/ColCoeff[i][0];
+                        }
+                        ColCorrect( im2, ColCoeff );
+                        break; 
+                case 3: // Correct both halfs                                                                   
+                        GetColCoeff( im1, im2, ColCoeff );
+                        for(i = 0; i<3; i++)
+                        {
+                                ColCoeff[i][1] =  ColCoeff[i][1] / 2.0 ;
+                                ColCoeff[i][0] = (ColCoeff[i][0] + 1.0 ) / 2.0;
+                        }
+                        ColCorrect( im1, ColCoeff );
+                        for(i = 0; i<3; i++)
+                        {
+                                ColCoeff[i][1] = - ColCoeff[i][1] / ColCoeff[i][0];
+                                ColCoeff[i][0] = 1.0 / ColCoeff[i][0];
+                        }
+                        ColCorrect( im2, ColCoeff );
+                        break;
+                default: break;
+        } // switch
 }
 
 
@@ -2785,54 +2838,63 @@
 
 int CheckParams( AlignInfo *g )
 {
-	int i;
-	int		err = -1;
-	char 	*errmsg[] = {
-				"No Parameters to optimize",
-				"No input images",
-				"No Feature Points",
-				"Image width must be positive",
-				"Image height must be positive",
-				"Field of View must be positive",
-				"Field of View must be smaller than 180 degrees in rectilinear Images",
-				"Unsupported Image Format (must be 0,1,2,3,4,7,8,10,14 or 19)",
-				"Panorama Width must be positive",
-				"Panorama Height must be positive",
-				"Field of View must be smaller than 180 degrees in rectilinear Panos",
-				"Unsupported Panorama Format",
-				"Control Point Coordinates must be positive",
-				"Invalid Image Number in Control Point Descriptions"
-				};
-
-	if( g->numParam == 0 )				err = 0;
-	if( g->numIm	== 0 )				err = 1;
-	if( g->numPts	== 0 )				err = 2;
-	
-	// Check images
-	
-	for( i=0; i<g->numIm; i++)
-	{
-		if( g->im[i].width  <= 0 )		err = 3;
-		if( g->im[i].height <= 0 )		err = 4;
-		if( g->im[i].hfov   <= 0.0 )	err = 5;
-		if( g->im[i].format == _rectilinear && g->im[i].hfov >= 180.0 )	err = 6;
-		if( g->im[i].format != _rectilinear     && g->im[i].format != _panorama &&
-        g->im[i].format != _fisheye_circ    && g->im[i].format != _fisheye_ff && 
-        g->im[i].format != _equirectangular && g->im[i].format != _orthographic &&
-        g->im[i].format != _mirror          && g->im[i].format != _stereographic && 
-        g->im[i].format != _equisolid)
-            err = 7;
-	}
-	
-	// Check Panorama specs
-	
-	if( g->pano.hfov <= 0.0 )	err = 5;
-	if( g->pano.width <=0 )		err = 8;
-	if( g->pano.height <=0 )		err = 9;
-	if( g->pano.format == _rectilinear && g->pano.hfov >= 180.0 )	err = 10;
-	
-	
-	if( g->pano.format != _rectilinear          && g->pano.format != _panorama           &&
+    int i;
+    int         err = -1;
+    char        *errmsg[] = {
+        "No Parameters to optimize",
+        "No input images",
+        "No Feature Points",
+        "Image width must be positive",
+        "Image height must be positive",
+        "Field of View must be positive",
+        "Field of View must be smaller than 180 degrees in rectilinear Images",
+        "Unsupported Image Format (must be 0,1,2,3,4,7,8,10,14 or 19)",
+        "Panorama Width must be positive",
+        "Panorama Height must be positive",
+        "Field of View must be smaller than 180 degrees in rectilinear Panos",
+        "Unsupported Panorama Format",
+        "Control Point Coordinates must be positive",
+        "Invalid Image Number in Control Point Descriptions",
+    };
+    
+    if( g->numParam == 0 )                              err = 0;
+    if( g->numIm        == 0 )                          err = 1;
+    if( g->numPts       == 0 )                          err = 2;
+    
+    // Check images
+    
+
+
+    for( i=0; i<g->numIm; i++)
+        {
+
+            if (g->im[i].cP.tilt_scale == 0) {
+                PrintError("Image [%d] has tilt_scale equal zero [%d]\n", i, g->im[i].cP.tilt_scale);
+                return -1;
+            }
+
+            if( g->im[i].width  <= 0 )          err = 3;
+            if( g->im[i].height <= 0 )          err = 4;
+            if( g->im[i].hfov   <= 0.0 )        err = 5;
+            if( g->im[i].format == _rectilinear && g->im[i].hfov >= 180.0 )     err = 6;
+            if( g->im[i].format != _rectilinear     && g->im[i].format != _panorama &&
+                g->im[i].format != _fisheye_circ    && g->im[i].format != _fisheye_ff && 
+                g->im[i].format != _equirectangular && g->im[i].format != _orthographic &&
+                g->im[i].format != _mirror          && g->im[i].format != _stereographic && 
+                g->im[i].format != _equisolid)
+                err = 7;
+        }
+
+    
+    // Check Panorama specs
+    
+    if( g->pano.hfov <= 0.0 )   err = 5;
+    if( g->pano.width <=0 )             err = 8;
+    if( g->pano.height <=0 )            err = 9;
+    if( g->pano.format == _rectilinear && g->pano.hfov >= 180.0 )       err = 10;
+    
+    
+    if( g->pano.format != _rectilinear          && g->pano.format != _panorama           &&
         g->pano.format != _equirectangular      && g->pano.format != _fisheye_ff         &&
         g->pano.format != _stereographic        && g->pano.format != _mercator           &&
         g->pano.format != _trans_mercator       && g->pano.format != _sinusoidal         &&
@@ -2841,148 +2903,148 @@
         g->pano.format != _panini               && g->pano.format != _architectural      &&
         g->pano.format != _equisolid            && g->pano.format != _equipanini         &&
         g->pano.format != _biplane              && g->pano.format != _triplane
-      ) err=11;
-		    
-	// Check Control Points
-	for( i=0; i<g->numPts; i++)
-	{
-// Joost: cp coordinates can be possible, no problem!  
-//		if( g->cpt[i].x[0] < 0 || g->cpt[i].y[0] < 0 || g->cpt[i].x[1] < 0 || g->cpt[i].y[1] < 0 )
-//			err = 12;
-		if( g->cpt[i].num[0] < 0 || g->cpt[i].num[0] >= g->numIm ||
-			g->cpt[i].num[1] < 0 || g->cpt[i].num[1] >= g->numIm )			err = 13;
-	}
-	
-	if( err != -1 )
-	{
-		PrintError( errmsg[ err ] );
-		return -1;
-	}
-	else
-		return 0;
-}
-			
-
-static int		CheckMakeParams( aPrefs *aP)
+        ) err=11;
+    
+    // Check Control Points
+    for( i=0; i<g->numPts; i++)         {
+        // Joost: cp coordinates can be possible, no problem!  
+        //              if( g->cpt[i].x[0] < 0 || g->cpt[i].y[0] < 0 || g->cpt[i].x[1] < 0 || g->cpt[i].y[1] < 0 )
+        //                      err = 12;
+        if( g->cpt[i].num[0] < 0 || g->cpt[i].num[0] >= g->numIm ||
+            g->cpt[i].num[1] < 0 || g->cpt[i].num[1] >= g->numIm )                      err = 13;
+    }
+    
+    if( err != -1 ) {
+        PrintError( errmsg[ err ] );
+        return -1;
+    }
+    else
+        return 0;
+}
+                        
+
+static int              CheckMakeParams( aPrefs *aP)
 {
-	double im_vfov;
-	im_vfov = aP->im.hfov / aP->im.width * aP->im.height;
-	
-	if( (aP->pano.format == _rectilinear) && (aP->pano.hfov >= 180.0) )
-	{
-		PrintError("Rectilinear Panorama can not have 180 or more degrees field of view.");
-		return -1;
-	}
-	if( (aP->im.format == _rectilinear) && (aP->im.hfov >= 180.0) )
-	{
-		PrintError("Rectilinear Image can not have 180 or more degrees field of view.");
-		return -1;
-	}
-	if( (aP->mode & 7) == _insert ){
-		if( (aP->im.format == _fisheye_circ || 	aP->im.format == _fisheye_ff) &&
-		    (aP->im.hfov > MAX_FISHEYE_FOV && im_vfov > MAX_FISHEYE_FOV) ){
-				PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
-				return -1;
-		}
-	}
-
-	return 0;
-	
-}
-
-
-			
+        double im_vfov;
+        im_vfov = aP->im.hfov / aP->im.width * aP->im.height;
+        
+        if( (aP->pano.format == _rectilinear) && (aP->pano.hfov >= 180.0) )
+        {
+                PrintError("Rectilinear Panorama can not have 180 or more degrees field of view.");
+                return -1;
+        }
+        if( (aP->im.format == _rectilinear) && (aP->im.hfov >= 180.0) )
+        {
+                PrintError("Rectilinear Image can not have 180 or more degrees field of view.");
+                return -1;
+        }
+        if( (aP->mode & 7) == _insert ){
+                if( (aP->im.format == _fisheye_circ ||  aP->im.format == _fisheye_ff) &&
+                    (aP->im.hfov > MAX_FISHEYE_FOV && im_vfov > MAX_FISHEYE_FOV) ){
+                                PrintError("Fisheye lens processing limited to fov <= %lg", MAX_FISHEYE_FOV);
+                                return -1;
+                }
+        }
+
+        return 0;
+        
+}
+
+
+                        
 
 // return 0, if overlap exists, else -1
 /*
 static int GetOverlapRect( PTRect *OvRect, PTRect *r1, PTRect *r2 )
 {
-	OvRect->left 	= max( r1->left, r2->left );
-	OvRect->right	= min( r1->right, r2->right );
-	OvRect->top		= max( r1->top, r2->top );
-	OvRect->bottom	= min( r1->bottom, r2->bottom );
-	
-	if( OvRect->right > OvRect->left && OvRect->bottom > OvRect->top )
-		return 0;
-	else
-		return -1;
+        OvRect->left    = max( r1->left, r2->left );
+        OvRect->right   = min( r1->right, r2->right );
+        OvRect->top             = max( r1->top, r2->top );
+        OvRect->bottom  = min( r1->bottom, r2->bottom );
+        
+        if( OvRect->right > OvRect->left && OvRect->bottom > OvRect->top )
+                return 0;
+        else
+                return -1;
 }
 */
+
 
 void SetGlobalPtr( AlignInfo *p )
 {
-	g = p;
-}
-
-AlignInfo* GetGlobalPtr()
+	optInfo = p;
+}
+
+
+AlignInfo* GetGlobalPtr(void)
 {
-	return g;
+        return optInfo;
 }
 
 void GetControlPointCoordinates(int i, double *x, double *y, AlignInfo *gl )
 {
-	double		w2, h2;
-	int j, n[2];
-
-	struct 	MakeParams	mp;
-	struct  fDesc        	stack[15];
-
-	
-
-	n[0] = gl->cpt[i].num[0];
-	n[1] = gl->cpt[i].num[1];
-	
-	// Calculate coordinates x/y in panorama
-
-	for(j=0; j<2; j++)
-	{
-		SetInvMakeParams( stack, &mp, &gl->im[ n[j] ], &gl->pano, 0 );
-		
-		h2 	= (double)gl->im[ n[j] ].height / 2.0 - 0.5;
-		w2	= (double)gl->im[ n[j] ].width  / 2.0 - 0.5;
-		
-
-		execute_stack_new( 	(double)gl->cpt[i].x[j] - w2,		// cartesian x-coordinate src
-						(double)gl->cpt[i].y[j] - h2,		// cartesian y-coordinate src
-						&x[j], &y[j], stack);
-
-		h2 	= (double)gl->pano.height / 2.0 - 0.5;
-		w2	= (double)gl->pano.width  / 2.0 - 0.5;
-		x[j] += w2;
-		y[j] += h2;
-	}
+        double          w2, h2;
+        int j, n[2];
+
+        struct  MakeParams      mp;
+        struct  fDesc           stack[15];
+
+        
+
+        n[0] = gl->cpt[i].num[0];
+        n[1] = gl->cpt[i].num[1];
+        
+        // Calculate coordinates x/y in panorama
+
+        for(j=0; j<2; j++)
+        {
+                SetInvMakeParams( stack, &mp, &gl->im[ n[j] ], &gl->pano, 0 );
+                
+                h2      = (double)gl->im[ n[j] ].height / 2.0 - 0.5;
+                w2      = (double)gl->im[ n[j] ].width  / 2.0 - 0.5;
+                
+
+                execute_stack_new(      (double)gl->cpt[i].x[j] - w2,           // cartesian x-coordinate src
+                                                (double)gl->cpt[i].y[j] - h2,           // cartesian y-coordinate src
+                                                &x[j], &y[j], stack);
+
+                h2      = (double)gl->pano.height / 2.0 - 0.5;
+                w2      = (double)gl->pano.width  / 2.0 - 0.5;
+                x[j] += w2;
+                y[j] += h2;
+        }
 }
 
 
 int AddEdgePoints( AlignInfo *gl )
 {
-	void *tmp;
-
-	tmp =  realloc( gl->cpt, (gl->numPts+4) * sizeof( controlPoint ) );
-	if( tmp == NULL )	return -1;
-	gl->numPts+=4; gl->cpt = (controlPoint*)tmp; 
-
-	gl->cpt[gl->numPts-4].num[0] = 0;
-	gl->cpt[gl->numPts-4].num[1] = 1;
-	gl->cpt[gl->numPts-4].x[0] = gl->cpt[gl->numPts-4].x[1] = -9.0 * (double)gl->pano.width;
-	gl->cpt[gl->numPts-4].y[0] = gl->cpt[gl->numPts-4].y[1] = -9.0 * (double)gl->pano.height;
-
-	gl->cpt[gl->numPts-3].num[0] = 0;
-	gl->cpt[gl->numPts-3].num[1] = 1;
-	gl->cpt[gl->numPts-3].x[0] = gl->cpt[gl->numPts-3].x[1] = 10.0 * (double)gl->pano.width;
-	gl->cpt[gl->numPts-3].y[0] = gl->cpt[gl->numPts-3].y[1] = -9.0 * (double)gl->pano.height;
-
-	gl->cpt[gl->numPts-2].num[0] = 0;
-	gl->cpt[gl->numPts-2].num[1] = 1;
-	gl->cpt[gl->numPts-2].x[0] = gl->cpt[gl->numPts-2].x[1] = -9.0 * (double)gl->pano.width;
-	gl->cpt[gl->numPts-2].y[0] = gl->cpt[gl->numPts-2].y[1] = 10.0 * (double)gl->pano.height;
-
-	gl->cpt[gl->numPts-1].num[0] = 0;
-	gl->cpt[gl->numPts-1].num[1] = 1;
-	gl->cpt[gl->numPts-1].x[0] = gl->cpt[gl->numPts-1].x[1] = 10.0 * (double)gl->pano.width;
-	gl->cpt[gl->numPts-1].y[0] = gl->cpt[gl->numPts-1].y[1] = 10.0 * (double)gl->pano.height;
-
-	return 0;
-}
-
-
+        void *tmp;
+
+        tmp =  realloc( gl->cpt, (gl->numPts+4) * sizeof( controlPoint ) );
+        if( tmp == NULL )       return -1;
+        gl->numPts+=4; gl->cpt = (controlPoint*)tmp; 
+
+        gl->cpt[gl->numPts-4].num[0] = 0;
+        gl->cpt[gl->numPts-4].num[1] = 1;
+        gl->cpt[gl->numPts-4].x[0] = gl->cpt[gl->numPts-4].x[1] = -9.0 * (double)gl->pano.width;
+        gl->cpt[gl->numPts-4].y[0] = gl->cpt[gl->numPts-4].y[1] = -9.0 * (double)gl->pano.height;
+
+        gl->cpt[gl->numPts-3].num[0] = 0;
+        gl->cpt[gl->numPts-3].num[1] = 1;
+        gl->cpt[gl->numPts-3].x[0] = gl->cpt[gl->numPts-3].x[1] = 10.0 * (double)gl->pano.width;
+        gl->cpt[gl->numPts-3].y[0] = gl->cpt[gl->numPts-3].y[1] = -9.0 * (double)gl->pano.height;
+
+        gl->cpt[gl->numPts-2].num[0] = 0;
+        gl->cpt[gl->numPts-2].num[1] = 1;
+        gl->cpt[gl->numPts-2].x[0] = gl->cpt[gl->numPts-2].x[1] = -9.0 * (double)gl->pano.width;
+        gl->cpt[gl->numPts-2].y[0] = gl->cpt[gl->numPts-2].y[1] = 10.0 * (double)gl->pano.height;
+
+        gl->cpt[gl->numPts-1].num[0] = 0;
+        gl->cpt[gl->numPts-1].num[1] = 1;
+        gl->cpt[gl->numPts-1].x[0] = gl->cpt[gl->numPts-1].x[1] = 10.0 * (double)gl->pano.width;
+        gl->cpt[gl->numPts-1].y[0] = gl->cpt[gl->numPts-1].y[1] = 10.0 * (double)gl->pano.height;
+
+        return 0;
+}
+
+