⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tree_utils.c

📁 图像处理的压缩算法
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------------*
 * File Name: tree_utils.c	 													*
 * Creation: May 07, 2003														*
 * Purpose: define tree utility functions										*
 * Copyright (c)2003 OriginLab Corp.											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/
 
#include <origin.h> // main Origin C header that is precompiled and already include most headers 

////////////////////////////////////////////////////////////////////////////////////

#define PAGE_INFO_EXPORT		"Export"

////////////////////////////////////////////////////////////////////////////////////
// start your functions here

TreeNode tree_get_ini_section(TreeNode &trIni, LPCSTR lpcszSection)
{
	if( !trIni || NULL == lpcszSection )
		return false;
	TreeNode trIniSection;
	foreach(trIniSection in trIni.Children)
	{
		if( trIniSection.Name.IsValid() && 0 == lstrcmpi(lpcszSection, trIniSection.Name.strVal) )
			return trIniSection;
	}
	TreeNode trNull; // return invalid tree node
	return trNull;
}

bool tree_read_ini(TreeNode &trIni, LPCSTR lpcszFile)
{
	if( !trIni || NULL == lpcszFile )
		return false;
	INIFile iniFile(lpcszFile);
	return tree_read_ini(trIni, iniFile);
}

bool tree_read_ini(TreeNode &trIni, INIFile &iniFile)
{
	if( !trIni )
		return false;
	StringArray saIniSections;
	iniFile.GetSectionNames(saIniSections);
	for( int i = 0; i < saIniSections.GetSize(); i++ )
		tree_read_ini_section(trIni, iniFile, saIniSections[i]);
	return true;
}

bool tree_read_ini_section(TreeNode &trIni, LPCSTR lpcszFile, LPCSTR lpcszSection)
{
	if( !trIni || NULL == lpcszFile || NULL == lpcszSection )
		return false;
	INIFile iniFile(lpcszFile);
	return tree_read_ini_section(trIni, iniFile, lpcszSection);
}

bool tree_read_ini_section(TreeNode &trIni, INIFile &iniFile, LPCSTR lpcszSection)
{
	if( !trIni || NULL == lpcszSection )
		return false;
	
	string str = lpcszSection;
	str.MakeValidCName('S');
	
	TreeNode trIniSection = tree_get_ini_section(trIni, str);
	if( trIniSection )
	{
		trIniSection.Reset();
	}
	else // section not found
	{
		trIniSection = trIni.AddNode(str);
	}
	if( !trIniSection )
		return false;

	// If section name is not a valid identifier name
	// then store the original name in the label attribute.
	if( str.Compare(lpcszSection) )
	{
		trIniSection.SetAttribute(STR_LABEL_ATTRIB, lpcszSection);
	}
	
	TreeNode trIniKey;
	StringArray saIniKeyNames;
	iniFile.GetKeyNames(saIniKeyNames, lpcszSection);
	for( int i = 0; i < saIniKeyNames.GetSize(); i++ )
	{
		str = saIniKeyNames[i];
		str.MakeValidCName('K');

		trIniKey = trIniSection.AddNode(str);
		if( trIniKey )
		{
			if( str.Compare(saIniKeyNames[i]) )
				trIniKey.SetAttribute(STR_LABEL_ATTRIB, saIniKeyNames[i]);
			trIniKey.strVal = iniFile.ReadString(lpcszSection, saIniKeyNames[i]);
		}
	}
	return true;
}

bool tree_write_ini(TreeNode &trIni, LPCSTR lpcszFile, bool bClearSections)
{
	if( !trIni || NULL == lpcszFile )
		return false;
	INIFile iniFile(lpcszFile);
	return tree_write_ini(trIni, iniFile, bClearSections);
}

bool tree_write_ini(TreeNode &trIni, INIFile &iniFile, bool bClearSections)
{
	if( !trIni )
		return false;
	TreeNode trIniSection;
	foreach(trIniSection in trIni.Children)
		tree_write_ini_section(trIniSection, iniFile, bClearSections);
	return true;
}

bool tree_write_ini_section(TreeNode &trIniSection, INIFile &iniFile, bool bClearSection)
{
	if( !trIniSection )
		return false;

	string strSection;
	if( !trIniSection.GetAttribute(STR_LABEL_ATTRIB, strSection) || strSection.IsEmpty() )
		strSection = trIniSection.tagName;

	if( bClearSection )
		iniFile.WriteString(strSection, NULL, NULL); // delete ini file section

	string strKey;
	TreeNode trIniKey;
	foreach(trIniKey in trIniSection.Children)
	{
		if( !trIniKey.GetAttribute(STR_LABEL_ATTRIB, strKey) || strKey.IsEmpty() )
			strKey = trIniKey.tagName;
		iniFile.WriteString(strSection, strKey, trIniKey.strVal);
	}
	return true;
}

bool tree_write_ini_section(TreeNode &trIniSection, LPCSTR lpcszFile, bool bClearSection)
{
	if( !trIniSection || NULL == lpcszFile )
		return false;
	INIFile iniFile(lpcszFile);
	return tree_write_ini_section(trIniSection, iniFile, bClearSection);
}

///////////////////////////////////////
///// read/write image export settings
///////////////////////////////////////

bool tree_read_image_export_settings(TreeNode &trSettings, LPCSTR lpcszFormat)
{
	string str(lpcszFormat);;
	LabTalk.Image.Export.GetIni("a", "b", str);
	char szFile[MAX_PATH], szSec[MAX_PATH];
	if( !LT_get_str("%a", szFile, MAX_PATH) || !LT_get_str("%b", szSec, MAX_PATH) )
		return false;
	bool bRet;
	if( szSec[0] ) // if ini section specified
		bRet = tree_read_ini_section(trSettings, szFile, szSec);
	else
		bRet = tree_read_ini(trSettings, szFile);
	return bRet;
}

bool tree_write_image_export_settings(TreeNode &trSettings, LPCSTR lpcszFormat, bool bClearSections)
{
	string str(lpcszFormat);;
	//LabTalk.Image.Export.GetIni("a", "b", lpcszFormat);
	LabTalk.Image.Export.GetIni("a", "b", str);
	char szFile[MAX_PATH], szSec[MAX_PATH];
	if( !LT_get_str("%a", szFile, MAX_PATH) || !LT_get_str("%a", szSec, MAX_PATH) )
		return false;
	bool bRet;
	if( szSec[0] ) // if ini section specified
		bRet = tree_write_ini_section(trSettings, szFile, bClearSections);//, szSec);
	else
		bRet = tree_write_ini(trSettings, szFile, bClearSections);
	return bRet;
}

bool tree_get_page_image_export_settings(TreeNode &trSettings, Page &pg, LPCSTR lpcszFormat)
{
	/* This old code used page's ini storage
	pg.Info.Add(PAGE_INFO_EXPORT);
	storage st;
	st = pg.GetStorage(PAGE_INFO_EXPORT);
	if( st && st.GetSection(lpcszFormat, trSettings) )
		return true;
	return false;
	*/
	string str;
	str.Format(PAGE_INFO_EXPORT"%s", lpcszFormat);
	vector<byte> vb;
	if( pg.GetMemory(str, vb) )
	{
		if( str.SetBytes(vb) )
		{
			trSettings.XML = str;
			return true;
		}
	}
	return false;
}

bool tree_set_page_image_export_settings(TreeNode &trSettings, Page &pg, LPCSTR lpcszFormat, bool bClearSection)
{
	/* This old code used page's ini storage
	pg.Info.Add(PAGE_INFO_EXPORT);
	storage st;
	st = pg.GetStorage(PAGE_INFO_EXPORT);
	if( st )
	{
		if( bClearSection )
		{
			//---temp code until st.RemoveSection is implemented
			string strSection = lpcszFormat;
			pg.Info.Export.RemoveSection(strSection);
			//---
			//st.RemoveSection(lpcszFormat);
		}
		if( st.SetSection(lpcszFormat, trSettings) )
			return true;
	}
	return false;
	*/
	string str = trSettings.XML;
	vector<byte> vb;
	if( str.GetBytes(vb) )
	{
		str.Format(PAGE_INFO_EXPORT"%s", lpcszFormat);
		return pg.SetMemory(str, vb);
	}
	return false;
}

///////////////////////////////////////
///// general tree related utilities
///////////////////////////////////////

bool out_tree(TreeNode& tr, int nLevel) // = 0
{
	if(NULL==tr)
		return false;
	
	for(int ii = 0; ii < nLevel; ii++)
		printf("  ");
	
	if(tr.GetNodeCount() > 0) // branch node
	{
		printf("%s\n", tr.tagName);
		foreach(TreeNode cNode in tr.Children)
			out_tree(cNode, nLevel+1);
	}
	else // leaf node
		printf("%s = %s\n", tr.tagName, tr.Text);

	return true;
}

static string get_tree_node_attribute_as_str(const TreeNode& tr)
{
	vector<string> vsKnownAttributes = {
		STR_ENABLE_ATTRIB, STR_SHOW_ATTRIB, STR_ID_ATTRIB, STR_COMBO_ATTRIB, STR_LABEL_ATTRIB
	};
	string strRet;
	string strTemp;
	for(int ii = 0; ii < vsKnownAttributes.GetSize(); ii++)
	{
		if(tr.GetAttribute(vsKnownAttributes[ii], strTemp))
		{
			if(!strRet.IsEmpty())
				strRet += ",";
			strRet += vsKnownAttributes[ii] + "=" + strTemp;
		}
	}
	if(strRet.IsEmpty())
		return strRet;
	// add ()
	strTemp = "(" + strRet + ")";
	return strTemp;
}
	
			
static bool dump_tree(const TreeNode& tr, LPCSTR lpcsz, int nOutput, int nLevel)
{
	if(NULL==tr)
		return false;
	
	string strTemp = lpcsz;
	if(0==nLevel && lpcsz)
		strTemp.WriteLine(nOutput);
		
	for(int ii = 0; ii < nLevel; ii++)
	{
		strTemp = "  ";
		strTemp.Write(nOutput);
	}
	//--- attributes
	string strAttrib = get_tree_node_attribute_as_str(tr);
	
	if(tr.GetNodeCount() > 0) // branch node
	{
		strTemp = tr.tagName;
		strTemp += strAttrib;
		strTemp.WriteLine(nOutput);
		foreach(TreeNode cNode in tr.Children)
			dump_tree(cNode, NULL, nOutput, nLevel+1);
	}
	else // leaf node
	{
		strTemp.Format("%s%s = %s", tr.tagName, strAttrib, tr.Text);
		strTemp.WriteLine(nOutput);
	}

	return true;
}

bool tree_dump(const TreeNode& tr, LPCSTR lpcsz, int nOutput) // = NULL, WRITE_SCRIPT_WINDOW
{
	return dump_tree(tr, lpcsz, nOutput, 0);
}


static void treeNode_count(TreeNode& trNode, int& nLeafs, int& nBranches)
{	
	if(trNode.GetNodeCount() > 0 || trNode.ID == ONODETYPE_BRANCH) // branch node
	{
		int nSubBranches = 0;
		nBranches++;
		nLeafs += tree_count_items(trNode, &nSubBranches);
		nBranches += nSubBranches;
	}
	else
	{
		DWORD dwID = trNode.ID;
		DWORD dwBranchBits = ONODETYPE_BRANCH | ONODETYPE_BRANCH_COMPOSITE | ONODETYPE_BRANCH_DIALOG;
		if(dwID && (dwID & dwBranchBits)) // skip branch nodes
		{
			//out_int("skipped ", dwID);
			return;
		}
		//else
		//	out_int("not skipped ", dwID);
		nLeafs++;
	}
}

// count number of leafs in the given tree
// if lpnSections given, then count the number of branches that contain these leafs
int tree_count_items(TreeNode& tr, int* lpnSections)// = NULL);
{
	if(NULL==tr)
		return -1;
	
	int nLeafs = 0;
	//
	if(NULL==lpnSections)
	{
		if(tr.GetAttribute(THEME_COUNT_NAME, nLeafs))
			return nLeafs;
		
	}
	
	int nBranches = 0;
	foreach(TreeNode trN in tr.Children)
	{
		treeNode_count(trN, nLeafs, nBranches);
	}
	if(lpnSections)
		*lpnSections = nBranches;
	
	return nLeafs;
}


// consider a linearized tree and return node at given row number, with nRow = 0 to return the root
TreeNode tree_get_node(TreeNode& trRoot, int nRow, int* lpInc) // = NULL
{
	TreeNode cNode = trRoot.FirstNode;
	if(!cNode)
		return cNode;//NULL
	
	int nIndex = (lpInc)? *lpInc : 0;
	foreach(TreeNode trN in trRoot.Children)
	{
		if(nIndex == nRow)
			return trN;
		
		nIndex++;
		if(trN.GetNodeCount() > 0) // branch node
		{
			cNode = tree_get_node(trN, nRow, &nIndex);
			if(cNode)
				return cNode;
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -