Пример #1
0
QList<DpySpec>
fetchSessions(int flags)
{
    QList<DpySpec> sessions;
    DpySpec tsess;

    gSet(1);
    gSendInt(G_List);
    gSendInt(flags);
  next:
    while (!(tsess.display = qString(gRecvStr())).isEmpty()) {
        tsess.from = qString(gRecvStr());
#ifdef HAVE_VTS
        tsess.vt = gRecvInt();
#endif
        tsess.user = qString(gRecvStr());
        tsess.session = qString(gRecvStr());
        tsess.flags = gRecvInt();
        if ((tsess.flags & isTTY) && !tsess.from.isEmpty())
            for (int i = 0; i < sessions.size(); i++)
                if (!sessions[i].user.isEmpty() &&
                    sessions[i].user == tsess.user &&
                    sessions[i].from == tsess.from)
                {
                    sessions[i].count++;
                    goto next;
                }
        tsess.count = 1;
        sessions.append(tsess);
    }
    gSet(0);
    return sessions;
}
Пример #2
0
static void
sendStr( int lv, const char *msg )
{
	gSet( &ctltalk );
	gSendInt( lv );
	gSendStr( msg );
	gRecvInt();
}
Пример #3
0
static void
processDPipe(struct display *d)
{
    char *user, *pass, *args;
    int cmd;
    GTalk dpytalk;
#ifdef XDMCP
    int ct, len;
    ARRAY8 ca, cp, ha;
#endif

    dpytalk.pipe = &d->pipe;
    if (Setjmp(dpytalk.errjmp)) {
        stopDisplay(d);
        return;
    }
    gSet(&dpytalk);
    if (!gRecvCmd(&cmd)) {
        /* process already exited */
        unregisterInput(d->pipe.fd.r);
        return;
    }
    switch (cmd) {
    case D_User:
        d->userSess = gRecvInt();
        d->userName = gRecvStr();
        d->sessName = gRecvStr();
        break;
    case D_UnUser:
        sessionDone(d);
        if (d->sdRec.how) {
            if (d->sdRec.force == SHUT_ASK &&
                (anyUserLogins(-1) || d->allowShutdown == SHUT_ROOT))
            {
                gSendInt(True);
            } else {
                if (!sdRec.how || sdRec.force != SHUT_FORCE ||
                    !((d->allowNuke == SHUT_NONE && sdRec.uid != d->sdRec.uid) ||
                      (d->allowNuke == SHUT_ROOT && d->sdRec.uid)))
                {
                    free(sdRec.osname);
                    sdRec = d->sdRec;
                } else {
                    free(d->sdRec.osname);
                }
                d->sdRec.how = 0;
                d->sdRec.osname = 0;
                gSendInt(False);
            }
        } else {
            gSendInt(False);
        }
        break;
    case D_ReLogin:
        user = gRecvStr();
        pass = gRecvStr();
        args = gRecvStr();
        setNLogin(d, user, pass, args, 1);
        free(args);
        free(pass);
        free(user);
        break;
#ifdef XDMCP
    case D_ChooseHost:
        ca.data = (unsigned char *)gRecvArr(&len);
        ca.length = (CARD16)len;
        cp.data = (unsigned char *)gRecvArr(&len);
        cp.length = (CARD16)len;
        ct = gRecvInt();
        ha.data = (unsigned char *)gRecvArr(&len);
        ha.length = (CARD16)len;
        registerIndirectChoice(&ca, &cp, ct, &ha);
        XdmcpDisposeARRAY8(&ha);
        XdmcpDisposeARRAY8(&cp);
        XdmcpDisposeARRAY8(&ca);
        break;
    case D_RemoteHost:
        free(d->remoteHost);
        d->remoteHost = gRecvStr();
        break;
#endif
    case D_XConnOk:
        startingServer = 0;
        break;
    default:
        logError("Internal error: unknown D_* command %d\n", cmd);
        stopDisplay(d);
        break;
    }
}
Пример #4
0
int
startClient( volatile int *pid )
{
	const char *home, *sessargs, *desksess;
	char **env, *xma;
	char **argv, *fname, *str;
#ifdef USE_PAM
	char ** volatile pam_env;
# ifndef HAVE_PAM_GETENVLIST
	char **saved_env;
# endif
	int pretc;
#else
# ifdef _AIX
	char *msg;
	char **theenv;
	extern char **newenv; /* from libs.a, this is set up by setpenv */
# endif
#endif
#ifdef HAVE_SETUSERCONTEXT
	extern char **environ;
#endif
	char *failsafeArgv[2];
	char *buf, *buf2;
	int i;

	if (strCmp( dmrcuser, curuser )) {
		if (curdmrc) { free( curdmrc ); curdmrc = 0; }
		if (dmrcuser) { free( dmrcuser ); dmrcuser = 0; }
	}

#if defined(USE_PAM) || defined(_AIX)
	if (!(p = getpwnam( curuser ))) {
		logError( "getpwnam(%s) failed.\n", curuser );
	  pError:
		displayStr( V_MSG_ERR, 0 );
		return 0;
	}
#endif

#ifndef USE_PAM
# ifdef _AIX
	msg = NULL;
	loginsuccess( curuser, hostname, tty, &msg );
	if (msg) {
		debug( "loginsuccess() - %s\n", msg );
		free( (void *)msg );
	}
# else /* _AIX */
#  if defined(KERBEROS) && defined(AFS)
	if (krbtkfile[0] != '\0') {
		if (k_hasafs()) {
			int fail = 0;
			if (k_setpag() == -1) {
				logError( "setpag() for %s failed\n", curuser );
				fail = 1;
			}
			if ((ret = k_afsklog( NULL, NULL )) != KSUCCESS) {
				logError( "AFS Warning: %s\n", krb_get_err_text( ret ) );
				fail = 1;
			}
			if (fail)
				displayMsg( V_MSG_ERR,
				            "Warning: Problems during Kerberos4/AFS setup." );
		}
	}
#  endif /* KERBEROS && AFS */
# endif /* _AIX */
#endif	/* !PAM */

	curuid = p->pw_uid;
	curgid = p->pw_gid;

	env = baseEnv( curuser );
	xma = 0;
	strApp( &xma, "method=", curtype, (char *)0 );
	if (td_setup)
		strApp( &xma, ",auto", (char *)0 );
	if (xma) {
		env = setEnv( env, "XDM_MANAGED", xma );
		free( xma );
	}
	if (td->autoLock && cursource == PWSRC_AUTOLOGIN)
		env = setEnv( env, "DESKTOP_LOCKED", "true" );
	env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath );
	env = setEnv( env, "SHELL", p->pw_shell );
	env = setEnv( env, "HOME", p->pw_dir );
#if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS)
	if (krbtkfile[0] != '\0')
		env = setEnv( env, "KRBTKFILE", krbtkfile );
#endif
	userEnviron = inheritEnv( env, envvars );
	env = systemEnv( curuser );
	systemEnviron = setEnv( env, "HOME", p->pw_dir );
	debug( "user environment:\n%[|''>'\n's"
	       "system environment:\n%[|''>'\n's"
	       "end of environments\n",
	       userEnviron,
	       systemEnviron );

	/*
	 * for user-based authorization schemes,
	 * add the user to the server's allowed "hosts" list.
	 */
	for (i = 0; i < td->authNum; i++) {
#ifdef SECURE_RPC
		if (td->authorizations[i]->name_length == 9 &&
		    !memcmp( td->authorizations[i]->name, "SUN-DES-1", 9 ))
		{
			XHostAddress addr;
			char netname[MAXNETNAMELEN+1];
			char domainname[MAXNETNAMELEN+1];

			getdomainname( domainname, sizeof(domainname) );
			user2netname( netname, curuid, domainname );
			addr.family = FamilyNetname;
			addr.length = strlen( netname );
			addr.address = netname;
			XAddHost( dpy, &addr );
		}
#endif
#ifdef K5AUTH
		if (td->authorizations[i]->name_length == 14 &&
		    !memcmp( td->authorizations[i]->name, "MIT-KERBEROS-5", 14 ))
		{
			/* Update server's auth file with user-specific info.
			 * Don't need to AddHost because X server will do that
			 * automatically when it reads the cache we are about
			 * to point it at.
			 */
			XauDisposeAuth( td->authorizations[i] );
			td->authorizations[i] =
				krb5GetAuthFor( 14, "MIT-KERBEROS-5", td->name );
			saveServerAuthorizations( td, td->authorizations, td->authNum );
		}
#endif
	}

	if (*dmrcDir)
		mergeSessionArgs( TRUE );

	debug( "now starting the session\n" );

#ifdef USE_PAM

# ifdef HAVE_SETUSERCONTEXT
	if (setusercontext( lc, p, p->pw_uid, LOGIN_SETGROUP )) {
		logError( "setusercontext(groups) for %s failed: %m\n",
		          curuser );
		goto pError;
	}
# else
	if (!setGid( curuser, curgid ))
		goto pError;
# endif

# ifndef HAVE_PAM_GETENVLIST
	if (!(pam_env = initStrArr( 0 ))) {
		resetGids();
		goto pError;
	}
	saved_env = environ;
	environ = pam_env;
# endif
	removeCreds = 1; /* set it first - i don't trust PAM's rollback */
	pretc = pam_setcred( pamh, 0 );
	reInitErrorLog();
# ifndef HAVE_PAM_GETENVLIST
	pam_env = environ;
	environ = saved_env;
# endif
# ifdef HAVE_INITGROUPS
	/* This seems to be a strange place for it, but do it:
	   - after the initial groups are set
	   - after pam_setcred might have set something, even in the error case
	   - before pam_setcred(DELETE_CRED) might need it
	 */
	if (!saveGids())
		goto pError;
# endif
	if (pretc != PAM_SUCCESS) {
		logError( "pam_setcred() for %s failed: %s\n",
		          curuser, pam_strerror( pamh, pretc ) );
		resetGids();
		return 0;
	}

	removeSession = 1; /* set it first - same as above */
	pretc = pam_open_session( pamh, 0 );
	reInitErrorLog();
	if (pretc != PAM_SUCCESS) {
		logError( "pam_open_session() for %s failed: %s\n",
		          curuser, pam_strerror( pamh, pretc ) );
		resetGids();
		return 0;
	}

	/* we don't want sessreg and the startup/reset scripts run with user
	   credentials. unfortunately, we can reset only the gids. */
	resetGids();

# define D_LOGIN_SETGROUP LOGIN_SETGROUP
#else /* USE_PAM */
# define D_LOGIN_SETGROUP 0
#endif /* USE_PAM */

	removeAuth = 1;
	chownCtrl( &td->ctrl, curuid );
	endpwent();
#if !defined(USE_PAM) && defined(USESHADOW) && !defined(_AIX)
	endspent();
#endif
	ctltalk.pipe = &ctlpipe;
	ASPrintf( &buf, "sub-daemon for display %s", td->name );
	ASPrintf( &buf2, "client for display %s", td->name );
	switch (gFork( &ctlpipe, buf, buf2, 0, 0, mstrtalk.pipe, pid )) {
	case 0:

		gCloseOnExec( ctltalk.pipe );
		if (Setjmp( ctltalk.errjmp ))
			exit( 1 );

		gCloseOnExec( mstrtalk.pipe );
		if (Setjmp( mstrtalk.errjmp ))
			goto cError;

#ifndef NOXDMTITLE
		setproctitle( "%s'", td->name );
#endif
		strApp( &prog, " '", (char *)0 );
		reInitErrorLog();

		setsid();

		sessreg( td, getpid(), curuser, curuid );

		/* We do this here, as we want to have the session as parent. */
		switch (source( systemEnviron, td->startup, td_setup )) {
		case 0:
			break;
		case wcCompose( 0, 0, 127 ):
			goto cError;
		default: /* Explicit failure => message already displayed. */
			logError( "Startup script returned non-zero exit code\n" );
			exit( 1 );
		}

	/* Memory leaks are ok here as we exec() soon. */

#if defined(USE_PAM) || !defined(_AIX)

# ifdef USE_PAM
		/* pass in environment variables set by libpam and modules it called */
#  ifdef HAVE_PAM_GETENVLIST
		pam_env = pam_getenvlist( pamh );
		reInitErrorLog();
#  endif
		if (pam_env)
			for (; *pam_env; pam_env++)
				userEnviron = putEnv( *pam_env, userEnviron );
# endif

# ifdef HAVE_SETLOGIN
		if (setlogin( curuser ) < 0) {
			logError( "setlogin for %s failed: %m\n", curuser );
			goto cError;
		}
#  define D_LOGIN_SETLOGIN LOGIN_SETLOGIN
# else
#  define D_LOGIN_SETLOGIN 0
# endif

# if defined(USE_PAM) && defined(HAVE_INITGROUPS)
		if (!restoreGids())
			goto cError;
# endif

# ifndef HAVE_SETUSERCONTEXT

#  ifdef USE_PAM
		if (!setUid( curuser, curuid ))
			goto cError;
#  else
		if (!setUser( curuser, curuid, curgid ))
			goto cError;
#  endif

# else /* !HAVE_SETUSERCONTEXT */

		/*
		 * Destroy environment.
		 * We need to do this before setusercontext() because that may
		 * set or reset some environment variables.
		 */
		if (!(environ = initStrArr( 0 )))
			goto cError;

		/*
		 * Set the user's credentials: uid, gid, groups,
		 * environment variables, resource limits, and umask.
		 */
		if (setusercontext( lc, p, p->pw_uid,
		        LOGIN_SETALL & ~(D_LOGIN_SETGROUP|D_LOGIN_SETLOGIN) ) < 0)
		{
			logError( "setusercontext for %s failed: %m\n", curuser );
			goto cError;
		}

		for (i = 0; environ[i]; i++)
			userEnviron = putEnv( environ[i], userEnviron );

# endif /* !HAVE_SETUSERCONTEXT */

#else /* PAM || !_AIX */
		/*
		 * Set the user's credentials: uid, gid, groups,
		 * audit classes, user limits, and umask.
		 */
		if (setpcred( curuser, NULL ) == -1) {
			logError( "setpcred for %s failed: %m\n", curuser );
			goto cError;
		}

		/*
		 * Set the users process environment. Store protected variables and
		 * obtain updated user environment list. This call will initialize
		 * global 'newenv'.
		 */
		if (setpenv( curuser, PENV_INIT | PENV_ARGV | PENV_NOEXEC,
		             userEnviron, NULL ) != 0)
		{
			logError( "Cannot set %s's process environment\n", curuser );
			goto cError;
		}
		userEnviron = newenv;

#endif /* _AIX */

		/*
		 * for user-based authorization schemes,
		 * use the password to get the user's credentials.
		 */
#ifdef SECURE_RPC
		/* do like "keylogin" program */
		if (!curpass[0])
			logInfo( "No password for NIS provided.\n" );
		else {
			char netname[MAXNETNAMELEN+1], secretkey[HEXKEYBYTES+1];
			int nameret, keyret;
			int len;
			int key_set_ok = 0;
			struct key_netstarg netst;

			nameret = getnetname( netname );
			debug( "user netname: %s\n", netname );
			len = strlen( curpass );
			if (len > 8)
				bzero( curpass + 8, len - 8 );
			keyret = getsecretkey( netname, secretkey, curpass );
			debug( "getsecretkey returns %d, key length %d\n",
			       keyret, strlen( secretkey ) );
			netst.st_netname = netname;
			memcpy( netst.st_priv_key, secretkey, HEXKEYBYTES );
			memset( netst.st_pub_key, 0, HEXKEYBYTES );
			if (key_setnet( &netst ) < 0)
				debug( "Could not set secret key.\n" );
			/* is there a key, and do we have the right password? */
			if (keyret == 1) {
				if (*secretkey) {
					keyret = key_setsecret( secretkey );
					debug( "key_setsecret returns %d\n", keyret );
					if (keyret == -1)
						logError( "Failed to set NIS secret key\n" );
					else
						key_set_ok = 1;
				} else {
					/* found a key, but couldn't interpret it */
					logError( "Password incorrect for NIS principal %s\n",
					          nameret ? netname : curuser );
				}
			}
			if (!key_set_ok)
				nukeAuth( 9, "SUN-DES-1" );
			bzero( secretkey, strlen( secretkey ) );
		}
#endif
#ifdef K5AUTH
		/* do like "kinit" program */
		if (!curpass[0])
			logInfo( "No password for Kerberos5 provided.\n" );
		else
			if ((str = krb5Init( curuser, curpass, td->name )))
				userEnviron = setEnv( userEnviron, "KRB5CCNAME", str );
			else
				nukeAuth( 14, "MIT-KERBEROS-5" );
#endif /* K5AUTH */
		if (td->autoReLogin) {
			gSet( &mstrtalk );
			gSendInt( D_ReLogin );
			gSendStr( curuser );
			gSendStr( curpass );
			gSendStr( newdmrc );
		}
		if (curpass)
			bzero( curpass, strlen( curpass ) );
		setUserAuthorization( td );
		home = getEnv( userEnviron, "HOME" );
		if (home && chdir( home ) < 0) {
			logError( "Cannot chdir to %s's home %s: %m\n", curuser, home );
			sendStr( V_MSG_ERR, "Cannot enter home directory. Using /.\n" );
			chdir( "/" );
			userEnviron = setEnv( userEnviron, "HOME", "/" );
			home = 0;
		}
		if (home || td->clientLogFile[0] == '/') {
			if (!createClientLog( td->clientLogFile )) {
				logWarn( "Session log file according to %s cannot be created: %m\n",
				         td->clientLogFile );
				goto tmperr;
			}
		} else {
		  tmperr:
			if (!createClientLog( td->clientLogFallback ))
				logError( "Fallback session log file according to %s cannot be created: %m\n",
				          td->clientLogFallback );
			/* Could inform the user, but I guess this is only confusing. */
		}
		if (!*dmrcDir)
			mergeSessionArgs( home != 0 );
		if (!(desksess = iniEntry( curdmrc, "Desktop", "Session", 0 )))
			desksess = "failsafe"; /* only due to OOM */
		gSet( &mstrtalk );
		gSendInt( D_User );
		gSendInt( curuid );
		gSendStr( curuser );
		gSendStr( desksess );
		close( mstrtalk.pipe->fd.w );
		userEnviron = setEnv( userEnviron, "DESKTOP_SESSION", desksess );
		for (i = 0; td->sessionsDirs[i]; i++) {
			fname = 0;
			if (strApp( &fname, td->sessionsDirs[i], "/", desksess, ".desktop", (char *)0 )) {
				if ((str = iniLoad( fname ))) {
					if (!strCmp( iniEntry( str, "Desktop Entry", "Hidden", 0 ), "true" ) ||
					    !(sessargs = iniEntry( str, "Desktop Entry", "Exec", 0 )))
						sessargs = "";
					free( str );
					free( fname );
					goto gotit;
				}
				free( fname );
			}
		}
		if (!strcmp( desksess, "failsafe" ) ||
		    !strcmp( desksess, "default" ) ||
		    !strcmp( desksess, "custom" ))
			sessargs = desksess;
		else
			sessargs = "";
	  gotit:
		if (!(argv = parseArgs( (char **)0, td->session )) ||
		    !(argv = addStrArr( argv, sessargs, -1 )))
			exit( 1 );
		if (argv[0] && *argv[0]) {
			debug( "executing session %\"[s\n", argv );
			execute( argv, userEnviron );
			logError( "Session %\"s execution failed: %m\n", argv[0] );
		} else
			logError( "Session has no command/arguments\n" );
		failsafeArgv[0] = td->failsafeClient;
		failsafeArgv[1] = 0;
		execute( failsafeArgv, userEnviron );
		logError( "Failsafe client %\"s execution failed: %m\n",
		          failsafeArgv[0] );
	  cError:
		sendStr( V_MSG_ERR, 0 );
		exit( 1 );
	case -1:
		free( buf );
		return 0;
	}
	debug( "StartSession, fork succeeded %d\n", *pid );
	free( buf );

	gSet( &ctltalk );
	if (!Setjmp( ctltalk.errjmp ))
		while (gRecvCmd( &i )) {
			buf = gRecvStr();
			displayStr( i, buf );
			free( buf );
			gSet( &ctltalk );
			gSendInt( 0 );
		}
	gClosen( ctltalk.pipe );
	finishGreet();

	return 1;
}
CvSize ConformalResizing::GetConstrainUnits(const IplImage* srcImg32F,  
										 const IplImage* img8U3C,
										 const CvSize szGrid, 
										 vector<ConstrainUnits>& quads, 
										 vector<ConstrainUnits>& qaud5s,
										 vector<ConstrainUnits>& edges,
										 vector<double>& ppos,/*added 2009.08.16*/
										 int meshQuadSize)
{

	// Get importance map
	//IplImage* impImg32F = cvCreateImage(cvGetSize(srcImg32F), IPL_DEPTH_32F, 1);
	//cvScale(srcImg32F, impImg32F);

	IplImage* impImg32F = NULL;
	if (strlen(FileNames::impName) > 0)
	{
		IplImage* impMap = cvLoadImage(FileNames::impName, CV_LOAD_IMAGE_GRAYSCALE);
		//if (impMap != NULL)
		{
			NormalizeImg(impMap, meshQuadSize);
			impImg32F = cvCreateImage(cvGetSize(impMap), IPL_DEPTH_32F, 1);
			cvScale(impMap, impImg32F, 1/255.0);
			cvReleaseImage(&impMap);
			cvNamedWindow("Importance");
			cvShowImage("Importance", impImg32F);
			cvAddS(impImg32F, cvScalarAll(gSet("minWeight")), impImg32F);
		}
	}

	CmImportance imp;
	if (impImg32F == NULL)
	{
		double weights[5];
		weights[0] = gSet("edgeWeight");
		weights[1] = gSet("faceWeight");
		weights[2] = gSet("motionWeight");
		weights[3] = gSet("contrastWeight"); 
		weights[4] = gSet("minWeight");

		impImg32F = imp.calcEnergy(img8U3C, weights);
		imp.showEnergy();
	}

	{
		IplImage* impSave = cvCreateImage(cvGetSize(impImg32F), IPL_DEPTH_8U, 1);
		cvScale(impImg32F, impSave, 255);
		//cvSaveImage(FileNames::outImp, impSave);
		cvReleaseImage(&impSave);
	}

//#ifdef _DEBUG
//	cvSave("impd.xml", img8U3C, "impImg32F");
//#else
//	cvSave("imp.xml", img8U3C, "impImg32F");
//#endif // _DEBUG

	//
	IplImage *pGridNodeX64F, *pGridNodeY64F;
	CmCvHelper::MeshGrid(pGridNodeX64F, pGridNodeY64F, 0, srcImg32F->width, 0, srcImg32F->height, meshQuadSize, meshQuadSize);
	double (*pGridPos)[2] = new double[szGrid.width * szGrid.height][2]; //Original edge point position within each grid. (x, y)
	int *pGridIdx = new int[szGrid.width * szGrid.height];  // Index of grid point variable
	int *pGridIdxE = new int[szGrid.width * szGrid.height]; // Index of edge contain this grid point
	typedef vector<pair<int, int>> EdgePos;  // Position of edge point in grid
	vector<EdgePos> edgePntPos;
	int varaInd = (szGrid.height + 1) * (szGrid.width + 1);
	/*added 2009.08.16*/
	{
		ppos.reserve(varaInd*2);
		for(int y=0;y<=szGrid.height;y++)
			for(int x=0;x<=szGrid.width;x++)
			{
				ppos.push_back(x*meshQuadSize);//x
				ppos.push_back(y*meshQuadSize);//y
			}
	}
	{
		//Get Edges
		const IplImage* pLineInd;
		vector<CEdge> edge;
		CDetectEdge detEdge(edge, gSet("Sigma"));
		detEdge.Initial(srcImg32F);
		detEdge.CalFirDer();
		detEdge.NoneMaximalSuppress((float)gSet("LinkEndBound"), (float)gSet("LinkStartBound"));
		detEdge.Link(gSet["ShortRemoveBound"]);
		pLineInd = detEdge.LineIdx();

		int* pTmp = pGridIdx;  // Borrow memory inside
		memset(pTmp, 0xff, szGrid.width * szGrid.height * sizeof(int));
		memset(pGridIdxE, 0xff, szGrid.width * szGrid.height * sizeof(int));

		for (int y = 0; y < srcImg32F->height; y++)
		{
			int* lineIdx = (int*)(pLineInd->imageData + pLineInd->widthStep * y); 
			for (int x = 0; x < srcImg32F->width; x++)
			{
				if (lineIdx[x] > 0) // it's an edge point
				{
					int dx = x % meshQuadSize;
					dx = min(dx, meshQuadSize - dx);
					int dy = y % meshQuadSize;
					dy = min(dy, meshQuadSize - dy);
					dx = min(dx, dy);
					int gridPos = y / meshQuadSize * szGrid.width + x / meshQuadSize;

					if (dx > pTmp[gridPos] && dx > gSet("minEdgeRatio") * meshQuadSize)
					{
						pGridPos[gridPos][0] = x;
						pGridPos[gridPos][1] = y;
						pGridIdxE[gridPos] = lineIdx[x];
						pTmp[gridPos] = dx;
					}
				}
			}
		}

		map<int, EdgePos> edgePntPosMap;
		for (int y = 0; y < szGrid.height; y++)
		{
			for (int x = 0; x < szGrid.width; x++)
			{
				int gridPos = y * szGrid.width + x;
				int idx = pGridIdxE[gridPos];
				if (idx > 0) // an edge point within grid
				{
					edgePntPosMap[idx].push_back(pair<int, int>(x, y));
				}
			}
		}

		for (map<int, EdgePos>::iterator it = edgePntPosMap.begin(); it != edgePntPosMap.end(); it++)
		{
			EdgePos& edPos = it->second;
			if (edPos.size() >= 3)
				edgePntPos.push_back(edPos);
			else
			{
				for (size_t i = 0; i < edPos.size(); i++)
					pGridIdxE[edPos[i].first + edPos[i].second * szGrid.width] = -1;
			}
		}

		for (int y = 0; y < szGrid.height; y++)
		{
			for (int x = 0; x < szGrid.width; x++)
			{
				int gridPos = y * szGrid.width + x;
				int idx = pGridIdxE[gridPos];
				if (idx > 0) // an edge point within grid
				{
					pGridIdx[gridPos] = varaInd;
					varaInd++;
					ppos.push_back(pGridPos[gridPos][0]);
					ppos.push_back(pGridPos[gridPos][1]);
				}
				else
					pGridIdx[gridPos] = -1;
			}
		}

		for (size_t i = 0; i < edgePntPos.size(); i++)
		{
			for (size_t j = 0; j < edgePntPos[i].size(); j++)
			{
				int gridPos = edgePntPos[i][j].first + szGrid.width * edgePntPos[i][j].second;
				pGridIdxE[gridPos] = i;
			}
		}

		CmShow::Labels(pLineInd, "Labels", 1); // Show Line Idx
		//CmShow::MixedMesh(img8U3C, pGridNodeX64F, pGridNodeY64F, szGrid, pGridPos, pGridIdxE, "Mixed", 1);
	}

	CvSize szConstrainA = cvSize(varaInd, 0);

	// Get constrain units
	{
		IplImage* gridImp32F = cvCreateImage(szGrid, IPL_DEPTH_32F, 1);
		cvResize(impImg32F, gridImp32F, CV_INTER_AREA/*added 2009-7-27*/);

		double* pNodeX = (double*)(pGridNodeX64F->imageData);
		double* pNodeY = (double*)(pGridNodeY64F->imageData);

		// Quads constrains and qaud5 constrains
		for (int y = 0; y < szGrid.height; y++)
		{
			for (int x = 0; x < szGrid.width; x++)
			{
				int gridpos = szGrid.width * y + x;

				ConstrainUnits unit;
				unit.SetNumber(pGridIdxE[gridpos] >= 0 ? 5 : 4);

				unit.ind[0] = y * (szGrid.width + 1) + x;
				unit.ind[1] = unit.ind[0] + szGrid.width + 1;
				unit.ind[2] = unit.ind[0] + 1;
				unit.ind[3] = unit.ind[0] + szGrid.width + 2;

				if (pGridIdxE[gridpos] >= 0)
				{
					unit.ind[4] = pGridIdx[gridpos];
					unit.pnts[4].x = pGridPos[gridpos][0];
					unit.pnts[4].y = pGridPos[gridpos][1];
				}

				for (int i = 0; i < 4; i++)
				{
					unit.pnts[i].x = pNodeX[unit.ind[i]];
					unit.pnts[i].y = pNodeY[unit.ind[i]];
				}

				unit.imp = CV_IMAGE_ELEM(gridImp32F, float, y, x);
				if (pGridIdxE[gridpos] >= 0)
				{
					//unit.imp *=1.2;
					qaud5s.push_back(unit);					
				}
				else
					quads.push_back(unit);
			}
		}

		szConstrainA.height = quads.size() * 8 + qaud5s.size() * 10;

		// Edge constrains
		for (size_t i = 0; i < edgePntPos.size(); i++)
		{
			ConstrainUnits unit;
			unit.SetNumber(edgePntPos[i].size());
			double imp = 0;
			for (size_t j = 0; j < edgePntPos[i].size(); j++)
			{
				int gridPos = edgePntPos[i][j].first + edgePntPos[i][j].second * szGrid.width;
				unit.ind[j] = pGridIdx[gridPos];
				unit.pnts[j].x = pGridPos[gridPos][0];
				unit.pnts[j].y = pGridPos[gridPos][1];
				imp += ((float*)(gridImp32F->imageData))[gridPos];
			}
			unit.imp = imp/unit.n * gSet("EdgeConstrainRation");
			edges.push_back(unit);
			szConstrainA.height += unit.n * 2;
		}

		cvReleaseImage(&gridImp32F);
		ShowConstrains(img8U3C, quads, qaud5s, edges, "Constrains", 1, FileNames::srcMeshName);
	}
	delete []pGridIdxE;
	delete []pGridIdx;
	delete []pGridPos;
	cvReleaseImage(&pGridNodeY64F);
	cvReleaseImage(&pGridNodeX64F);
	//cvReleaseImage(&impImg32F);

	szConstrainA.width *= 2;
	return szConstrainA;
}