GDAL读取影像测试速度程序

这个程序代码是很多年前一个同事写的,之前我们写过很多这样零碎测试的代码,时间太久了,很多都遗忘了。现在放这里做一个备份,也供需要的人做个参考。

程序使用说明

模式1
  分配任务方式:
	将所有图片依次依序分配读取任务,每次任务读取的数据量由buff能容纳的量决定
	现在默认为500MB,可以修改main.cpp的参数如下来调整
	#define MAXBUFSIZE  (1024 * 1024 * 500)   	//500M
  是否支持随机读取:
	支持,通过--random 参数指定


模式2
  分配任务方式:
	将所有图片依次依序分配读取任务,每次任务读取512*512,buff也是512*512,没有抽析过程。
  是否支持随机读取:
	支持,通过--random 参数指定


模式3
  分配任务方式:
	将所有图片依次依序分配读取任务,每次任务进行抽析,buff是512*512,逐层级进行抽析。
  是否支持随机读取:
	支持,通过--random 参数指定

程序代码

/***************************************************************************
* Project:  gdalread
* Purpose:  Implement gdal read speed test.
* Author:   Chengsong of ... COMPANY
****************************************************************************
* Copyright (c)
****************************************************************************/

#ifdef WIN32
#	include <windows.h>
#	include "gdal_priv.h"
#	include <io.h>	
#else 
#	include <sys/time.h>
#	include <unistd.h>
#	include "./include/gdal_priv.h"
#	include <stdio.h>  
#	include <string.h> 
#	include <stdlib.h>  
#	include <dirent.h>  
#	include <sys/stat.h>  
#	include <unistd.h>  
#	include <sys/types.h> 
#	include <iostream>
#endif

#include "getopt.h"
#include <iostream>
#include <mutex>
#include <string>
#include <vector>
#include <iomanip>
#include <string>
#include <fstream> 

using std::string;
using std::cout;
using std::endl;
using std::ifstream;
using std::vector;
using std::string;
using std::cout;
using std::hex;
using std::endl;
using std::setw;
using std::streambuf;
using std::ofstream;
using std::setiosflags;
using std::setprecision;
using std::ios;
using std::mutex;

#ifndef no_argument
#	define	no_argument			0
#endif
#ifndef required_argument
#	define required_argument	1
#endif
#ifndef opt_argument
#	define opt_argument	2
#endif

const struct option longOpts[] = {
	{ "help", no_argument, NULL, 'h' },
	{ "recursive", no_argument, NULL, 'r' },
	{ "nodetail", no_argument, NULL, 'n' },
	{ "verbose", no_argument, NULL, 'v' },
	{ "path", required_argument, NULL, 'p' },
	{ "mode", required_argument, NULL, 'm' },
	{ "deap", required_argument, NULL, 'd' },
	{ "layer", required_argument, NULL, 'l' },
	{ "out", required_argument, NULL, 'o' },
	{ "ext", required_argument, NULL, 'e' },
	{ "thread", required_argument, NULL, 't' },
	{ "random", no_argument, NULL, 1 },
	{ NULL, 0, NULL, 0 },
};
static const char *optString = "hrnvp:m:d:o:l:e:t:";

string oPath;
string oMode;
string oOutFile;
string oFileExt;
int    mode;
char   timE[80];
#define SPLITLINE "  --------------------------------------------------------------------------------------------------------------------------------------------"
#define MAXBUFSIZE  (1024 * 1024 * 500)   	//500M

GUIntBig TotalFilesSize;
int threads;
int deapth;
bool recursive;
bool nodetail;
bool verbose;
bool bContinue;
bool bRandom;
int bound_map[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int setedlayer;
int curlayer = 1;
#define MAXTHREADNUM 300
int ThreadRetFlag[MAXTHREADNUM];
int ThreadRetFlagPos;
ofstream of;
streambuf* coutBuf;
streambuf* fileBuf;

#define MAXBANDNUM 10
#define MAXBANDDEAP 3
#define MALLOC521BLOCKSIZE (512*512*MAXBANDNUM*MAXBANDDEAP)
GByte * pblock512buff[MAXTHREADNUM];

vector<string> files;
int file_num;
const char* pszLocalPath;

typedef struct{
	const char* filepath;
	int START_X;
	int START_Y;
	int SIZE_X;
	int SIZE_Y;
	int SIZE_OUT_X;
	int SIZE_OUT_Y;
	int bands;
	int deap;
	int rand;
	int f_sizex;
	int f_sizey;
}TASK;

typedef vector<TASK> TASKGROUP;
typedef vector<TASKGROUP> ALLTASK;
ALLTASK AllTask;
int taskg_num = 0;

typedef struct{
	const char* filepath;
	GUIntBig SIZE;	//MB
	int SIZE_X;
	int SIZE_Y;
	int bands;
	int deap;
}info;
typedef vector<info> FILESINFO;
FILESINFO FilesInfo;

CPLString str_print;
int str_print_pos;

//Function Declaration
int  GDALReadFile(const char* pszLocalFilePath, int extend);
void FormatPrint(const char* pszLocalFile, GIntBig  nFileSize, int nSizeX, int nSizeY, int Bands, int deap, long timeuse_ms);
void f_ExitIfTure(int val, const char* pstr);
void getFiles(string path, vector<string>& files);
void helpinfo(void);
char* DateTimeStr(void);
void GatherFilesInfo(void);
void AssignTask_mode1(void);
void AssignTask_mode2(void);
int AssignTask_mode3(int count);
void StartThread(void);
void WaitUntilFinished(void);
void PerformThread(void* parg);
void TaskOutput(TASK* task, float timeuse_ms, CPLString & osOut, GIntBig PID);
void TaskGroupOutput(TASKGROUP* taskg, float timeuse_ms, CPLString & osOut, GIntBig PID);

/************************************************************************/
/*                              helpinfo()                              */
/************************************************************************/
void helpinfo(void)
{
#ifdef WIN32
	cout << "说明:\n"
		<< "  -p or --path          指定文件夹。\n"
		<< "  -r or recursive [opt] 指定是否递归搜索子文件夹内的文件,不指定,则不递归搜索。\n"
		<< "  -m or --mode          指定读取模式,现有三种模式:1 2 3。\n"
		<< "  -t or --thread  [opt] 指定并发线程数量,不指定,则为单线程。\n"
		<< "  -d or --deap    [opt] 指定读取层级深度。不指定,则读取所有有效层级深度,直到放大一次。\n"
		<< "  -l or --layer   [opt] 指定读取层级。\n"
		<< "  -v or --verbose [opt] 指定输出详细信息。,不指定,则不输出详细信息。\n"
		<< "  -n or nodetail  [opt] 仅输出总结信息。\n"
		<< "  -o or --out     [opt] 指定输出文件名,不指定,则以时间为文件名。\n"
		<< "  -e or --ext     [opt] 指定图片数据的后缀名,默认为tif,不需要输入 \".\"。\n"
		<< "  --random        [opt] 实现随机读取,不指定则为顺序读。\n"
		<< "示例:\n";
#else
	cout << "Description:\n"
		<< "  -p or --path          Specified the path.\n"
		<< "  -r or recursive [opt] Recursive search for files within a sub folder.\n"
		<< "  -m or --mode          Specifies the reading mode, there are three modes: 1 2 3.\n"
		<< "  -t or --thread  [opt] thread number, the maximum is 300.\n"
		<< "  -d or --deap    [opt] Set the depth of reading layer by layer.\n"
		<< "  -l or --layer   [opt] Set the specified layer.\n"
		<< "  -v or --verbose [opt] Output details\n"
		<< "  -n or nodetail  [opt] Only output summary information\n"
		<< "  -o or --out     [opt] Specify the output file name.If you do not specify a file\n"
		<< "  -e or --ext     [opt] specifies the file extension (default is TIF), do not need to add \".\".\n"
		<< "  --random        [opt] Implementation of random read.\n"
		<< "Examples:\n";
#endif
	cout << "  gdalread -p D:\\test -m 1 \n"
		<< "  gdalread -p D:\\test -m 1 -o out1.txt -e jpg \n"
		<< "  gdalread -p D:\\test -m 2 \n"
		<< "  gdalread -p D:\\test -m 3 \n"
		<< "  gdalread -p D:\\test -m 3 -t 4 \n"
		<< "  gdalread -p D:\\test -m 3 -t 4 -d 4 \n"
		<< "  gdalread -p D:\\test -m 3 -t 4 -l 4 \n";
	exit(0);
}

/************************************************************************/
/*                                main()                                */
/************************************************************************/

int compare(const TASKGROUP &a, const TASKGROUP &b)
{
	return a.at(0).rand > b.at(0).rand;
}

#include <algorithm>
int main(int argc, char ** argv)
{
	GDALAllRegister();
	int bHaveUnknownPara = 0;
	int opt = 0;
	int longIndex = 0;

	if (argc == 1)
		helpinfo();

	opt = getopt_long(argc, argv, optString, longOpts, &longIndex);

	while (opt != -1)
	{
		switch (opt)
		{
		case 'p':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			oPath = optarg;
			break;
		case 'm':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			oMode = optarg;
			break;
		case 'd':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			deapth = atoi(optarg);
			break;
		case 'l':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			setedlayer = atoi(optarg);
			break;
		case 'o':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			oOutFile = optarg;
			break;
		case 'e':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			oFileExt = optarg;
			break;
		case 't':
			f_ExitIfTure(optarg[0] == '-', (string("option -") + (char)opt + " requiers an argument.").c_str());
			threads = atoi(optarg);
			break;
		case  1:
			bRandom = 1;
			break;
		case 'r':
			recursive = 1;
			break;
		case 'n':
			nodetail = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case '?':
		case ':':
		case 'h':
			helpinfo();
			return 0;
			break;
		default:
			/* You won't actually get here. */
			break;
		}
		opt = getopt_long(argc, argv, optString, longOpts, &longIndex);
	}
	// Process Parameters
	f_ExitIfTure(oPath.empty(), "please input path name, format : -p pathname");
	f_ExitIfTure(oMode.empty(), "please input file name, format : -f filename");

	srand((unsigned)time(NULL));

#ifdef WIN32
	if (oPath[oPath.length() - 1] != '\\')
		oPath += '\\';
#else
	if (oPath[oPath.length() - 1] != '/')
		oPath += '/';
#endif
	pszLocalPath = oPath.c_str();

	if (oMode == "whole" || oMode == "1")
		mode = 1;
	else if (oMode == "512" || oMode == "2")
		mode = 2;
	else if (oMode == "3")
		mode = 3;
	else{
		cout << "Mode ERROR!" << endl;
		return 1;
	}

	if (oOutFile.empty())
		oOutFile = (CPLString)DateTimeStr() + ".txt";

	if (oFileExt.empty())
		oFileExt = ".tif";
	else
		oFileExt = '.' + oFileExt;
	if (deapth == 0)
		deapth = 100;


	getFiles(pszLocalPath, files);
	for (vector<string>::iterator iter = files.begin(); iter != files.end();){
		CPLString ext = (*iter).c_str() + (*iter).find_last_of('.');
		if (ext != oFileExt){
			iter = files.erase(iter);
			continue;
		}
		iter++;
	}
	file_num = files.size();


	//打开输出文件
	coutBuf = cout.rdbuf();				// Save cout stream buffer pointer
	of.open(oOutFile.c_str(), ios::app);	    // Gets the file out.txt stream buffer pointer
	if (of.fail()){
		cout << "Unable to create file: " << oOutFile << ", the file name can not contain\" \\ / : * ? \" < > | \"" << endl;
		exit(1);
	}
	fileBuf = of.rdbuf();

	//start timing
	long timeuse_ms;
#ifdef WIN32
	//	DWORD t1 = 0, t2 = 0;
	LARGE_INTEGER nTime1, nTime2, tc;
	QueryPerformanceFrequency(&tc);
	QueryPerformanceCounter(&nTime1);
	//	t1 = GetTickCount();
#else
	struct timeval t1, t2;
	gettimeofday(&t1, NULL);
#endif
	//分配内存	
	if (threads == 0)
		threads = 1;
	if (mode == 2 || mode == 3){
		for (int i = 0; i < threads; i++)
			pblock512buff[i] = (GByte *)CPLMalloc(MALLOC521BLOCKSIZE);
	}
	//收集文件信息
	GatherFilesInfo();

	//输出初步信息
	str_print.append("  Command: gdalread ");
	for (int i = 1; i < argc; i++)
		str_print.append(argv[i]).append(" ");
	char buff[200];
	str_print.append("\n  File number: ");
	sprintf(buff, "%d", files.size());
	str_print.append(buff);
	str_print.append("\n  Total file size: ");
	sprintf(buff, "%d", TotalFilesSize / (1024 * 1024));
	str_print.append(buff).append("M -- ");
	sprintf(buff, "%.3f", TotalFilesSize * 1.0 / (1024 * 1024 * 1024));
	str_print.append(buff).append("G\n");
	str_print.append(SPLITLINE).append("\n  ");
	sprintf(buff, "%-40s", "FILE_NAME"); str_print.append(buff);
	sprintf(buff, "%-6s", "PID"); str_print.append(buff);
	sprintf(buff, "%-8s", "SIZE/M"); str_print.append(buff);
	sprintf(buff, "%-18s", "X*Y/BANDS/DEAP"); str_print.append(buff);
	sprintf(buff, "%-7s", "LAYER"); str_print.append(buff);
	sprintf(buff, "%-42s", "EXTRACTION"); str_print.append(buff);
	sprintf(buff, "%-10s", "TIME/sec"); str_print.append(buff);
	sprintf(buff, "%-10s", "SPEED M/s\n"); str_print.append(buff);

	//计算执行任务
	//输出详细信息
	if (mode == 1){
		AssignTask_mode1();
		if (bRandom == 1)
			sort(AllTask.begin(), AllTask.end(), compare);
		StartThread();
		WaitUntilFinished();
	}
	else if (mode == 2){
		AssignTask_mode2();
		if (bRandom == 1)
			sort(AllTask.begin(), AllTask.end(), compare);
		StartThread();
		WaitUntilFinished();
	}
	else if (mode == 3){
		if (setedlayer == 0){
			curlayer = 1;
			while (curlayer <= deapth && AssignTask_mode3(curlayer) != 0){
				if (bRandom == 1)
					sort(AllTask.begin(), AllTask.end(), compare);
				//开始计时

				long timeuse_ms_lt;
#ifdef WIN32
				LARGE_INTEGER nTime1_lt, nTime2_lt, tc_lt;
				QueryPerformanceFrequency(&tc_lt);
				QueryPerformanceCounter(&nTime1_lt);
#else
				struct timeval t1_lt, t2_lt;
				gettimeofday(&t1_lt, NULL);
#endif
				//执行任务
				taskg_num = 0;
				ThreadRetFlagPos = 0;
				memset(ThreadRetFlag, 0, MAXTHREADNUM);
				StartThread();
				WaitUntilFinished();
				curlayer++;
				//结束计时
#ifdef WIN32
				QueryPerformanceCounter(&nTime2_lt);
				timeuse_ms_lt = (nTime2_lt.QuadPart - nTime1_lt.QuadPart)*1000.0 / tc_lt.QuadPart;
#else
				gettimeofday(&t2_lt, NULL);
				timeuse_ms_lt = (t2_lt.tv_sec - t1_lt.tv_sec) * 1000 + (t2_lt.tv_usec - t1_lt.tv_usec) / 1000;
#endif
				//输出计时
				char buff[200];
				sprintf(buff, "  Time consumpted of this layer is: %.3f seconds.\n\n", timeuse_ms_lt / 1000.0);
				str_print.append(buff);
			}
		}
		else{
			curlayer = setedlayer;
			if (AssignTask_mode3(setedlayer) != 0){
				if (bRandom == 1)
					sort(AllTask.begin(), AllTask.end(), compare);
				StartThread();
				WaitUntilFinished();
			}
		}
	}
	//任务结束

#ifdef WIN32
	QueryPerformanceCounter(&nTime2);
	timeuse_ms = (nTime2.QuadPart - nTime1.QuadPart)*1000.0 / tc.QuadPart;
#else
	gettimeofday(&t2, NULL);
	timeuse_ms = (t2.tv_sec - t1.tv_sec) * 1000 + (t2.tv_usec - t1.tv_usec) / 1000;
#endif

	//输出总结信息

	if (mode == 2 || mode == 3){
		for (int i = 0; i < threads; i++)
			CPLFree(pblock512buff[i]);
	}
	CPLString sum_print;

	sprintf(buff, "\n  The Total Time Cost is    :%.3f seconds.   \n", timeuse_ms / 1000.0);
	sum_print.append(buff);

	if (mode == 1 || mode == 2){
		sprintf(buff, "  The Average Read Speed is :%.3f M/s.\n", (TotalFilesSize * 1.0 / (1024 * 1024)) / (timeuse_ms / 1000.0));
		sum_print.append(buff);
	}
	sum_print.append("  ---Finished!---\n");
	cout << sum_print;

	cout.rdbuf(fileBuf);	            // Sets the cout stream buffer pointer to the out.txt stream buffer pointer
	cout << sum_print;
	of.flush();
	of.close();
	cout.rdbuf(coutBuf);

	return 0;
}

/************************************************************************/
/*          Thread      WaitUntilFinished()                             */
/************************************************************************/

void WaitUntilFinished(void)
{
	bool bFinished = 0;
	while (bFinished == 0){
		bFinished = 1;
		for (int i = 0; i < threads; i++){
			if (ThreadRetFlag[i] == 0)
				bFinished = 0;
		}
		//打印输出
#define BUFFSIZE_L 1024000
		static char buff[BUFFSIZE_L];
		int curpos = str_print.size();
		if (curpos < BUFFSIZE_L && str_print_pos < curpos - 1){
			CPLSleep(0.001);
			memcpy(buff, str_print.c_str() + str_print_pos, curpos - str_print_pos);
			buff[curpos - str_print_pos] = 0;
			cout << buff;

			cout.rdbuf(fileBuf);	            // Sets the cout stream buffer pointer to the out.txt stream buffer pointer
			cout << buff;
			of.flush();
			cout.rdbuf(coutBuf);

			str_print_pos = curpos;
		}
	}
}

/************************************************************************/
/*          Thread            StartThread()                             */
/************************************************************************/

void StartThread(void)
{
	for (int i = 0; i < threads; i++){
		CPLCreateThread(PerformThread, NULL);
		CPLSleep(0.025);
	}
}

/************************************************************************/
/*          Thread           PerformThread()                            */
/************************************************************************/

static CPLMutex	*hMutex = NULL;
static CPLMutex	*hMutex2 = NULL;
//unsigned __stdcall PerformThread(void* parg)
void PerformThread(void* parg)

{
	TASKGROUP CurrTaskGroup;
	int curr_num;
	GIntBig PID = CPLGetPID();

	CPLCreateOrAcquireMutex(&hMutex, 0);
	int ThisThreadRetFlagPos = ThreadRetFlagPos++;
	CPLReleaseMutex(hMutex);

	GByte * pafScanline = NULL;

	if (mode == 2 || mode == 3)
		pafScanline = pblock512buff[ThisThreadRetFlagPos];

	GDALDataset* poDataset = NULL;
	const char* last_filepath = NULL;

	while (1){
		//Get TaskGroup
		CPLCreateOrAcquireMutex(&hMutex2, 0);
		if (taskg_num > AllTask.size() - 1){
			CPLReleaseMutex(hMutex2);
			ThreadRetFlag[ThisThreadRetFlagPos] = 1;
			return;
		}
		CurrTaskGroup = AllTask.at(taskg_num++);
		//printf("%d\n", taskg_num-1);
		CPLReleaseMutex(hMutex2);

		if (mode == 1)
			pafScanline = (GByte *)CPLMalloc(CurrTaskGroup.at(0).SIZE_OUT_X * CurrTaskGroup.at(0).SIZE_OUT_Y*CurrTaskGroup.at(0).bands*CurrTaskGroup.at(0).deap);

		if (CurrTaskGroup.at(0).filepath != last_filepath){
			poDataset = (GDALDataset*)GDALOpen(CurrTaskGroup.at(0).filepath, GA_ReadOnly);
			last_filepath = CurrTaskGroup.at(0).filepath;
		}

		//#undef WIN32
		float timeuse_ms_g;
#ifdef WIN32
		LARGE_INTEGER nTime1_g, nTime2_g, tc_g;
#else
		struct timeval t1_g, t2_g;
#endif
		if (nodetail == 0 && verbose == 0){
			//开始组计时	
#ifdef WIN32
			QueryPerformanceFrequency(&tc_g);
			QueryPerformanceCounter(&nTime1_g);
#else
			gettimeofday(&t1_g, NULL);
#endif 
		}

		for (int i = 0; i < CurrTaskGroup.size(); i++){
			float timeuse_ms_s;
#ifdef WIN32
			LARGE_INTEGER nTime1_s, nTime2_s, tc_s;
#else
			struct timeval t1_s, t2_s;
#endif
			if (nodetail == 0 && verbose == 1){
				//开始单任务计时		
#ifdef WIN32
				QueryPerformanceFrequency(&tc_s);
				QueryPerformanceCounter(&nTime1_s);
#else
				gettimeofday(&t1_s, NULL);
#endif
			}
			CPLErr err = poDataset->RasterIO(GF_Read, CurrTaskGroup.at(i).START_X, CurrTaskGroup.at(i).START_Y, \
				CurrTaskGroup.at(i).SIZE_X, CurrTaskGroup.at(i).SIZE_Y, \
				pafScanline, CurrTaskGroup.at(i).SIZE_OUT_X, CurrTaskGroup.at(i).SIZE_OUT_Y, \
				GDALDataType(CurrTaskGroup.at(i).deap), CurrTaskGroup.at(i).bands, bound_map, 0, 0, 0);
			if (nodetail == 0 && verbose == 1){
				//结束单任务计时		
#ifdef WIN32
				QueryPerformanceCounter(&nTime2_s);
				timeuse_ms_s = (nTime2_s.QuadPart - nTime1_s.QuadPart)*1000.0 / tc_s.QuadPart;
#else
				gettimeofday(&t2_s, NULL);
				timeuse_ms_s = (t2_s.tv_sec - t1_s.tv_sec) * 1000 + (t2_s.tv_usec - t1_s.tv_usec) / 1000;
#endif		
				//打印输出
				CPLString osOut;
				TaskOutput(&CurrTaskGroup.at(i), timeuse_ms_s, osOut, PID);
				str_print.append(osOut.c_str());
			}
		}

		if (nodetail == 0 && verbose == 0){
			//结束组计时		
#ifdef WIN32
			QueryPerformanceCounter(&nTime2_g);
			timeuse_ms_g = (nTime2_g.QuadPart - nTime1_g.QuadPart)*1000.0 / tc_g.QuadPart;
#else
			gettimeofday(&t2_g, NULL);
			timeuse_ms_g = (t2_g.tv_sec - t1_g.tv_sec) * 1000 + (t2_g.tv_usec - t1_g.tv_usec) / 1000;
#endif		
			//打印输出
			CPLString osOut;
			TaskGroupOutput(&CurrTaskGroup, timeuse_ms_g, osOut, PID);
			str_print.append(osOut.c_str());
		}

		if (mode == 1){
			CPLFree(pafScanline);
			pafScanline = NULL;
		}
	}
}

/************************************************************************/
/*                             TaskGroupOutput()                             */
/************************************************************************/
void TaskGroupOutput(TASKGROUP* taskg, float timeuse_ms, CPLString & osOut, GIntBig PID)
{
	osOut.clear();
	char buff[100];

	osOut.append("  ");
	sprintf(buff, "%-40.38s", CPLGetFilename(taskg->at(0).filepath));	osOut.append(buff);
	sprintf(buff, "%-6d", PID);									osOut.append(buff);
	sprintf(buff, "%-8s", "");									osOut.append(buff);

	sprintf(buff, "%d", taskg->at(0).f_sizex);
	string of_xyb = buff;
	sprintf(buff, "%d", taskg->at(0).f_sizey);
	of_xyb = of_xyb + '*' + buff + '/';
	sprintf(buff, "%d", taskg->at(0).bands);
	of_xyb = of_xyb + buff + '/';
	sprintf(buff, "%d", taskg->at(0).deap);
	of_xyb = of_xyb + buff;

	sprintf(buff, "%-18.18s", of_xyb.c_str());					osOut.append(buff);

	if (mode == 3){
		sprintf(buff, "%-7d", curlayer);						osOut.append(buff);
	}
	else if (mode == 1 || mode == 2){
		sprintf(buff, "%-7s", "");								osOut.append(buff);
	}

	sprintf(buff, "%d", taskg->size());
	string of_extr = buff; of_extr += "*";
	sprintf(buff, "(%d", taskg->at(0).START_X);
	of_extr = of_extr + buff;
	sprintf(buff, "%d", taskg->at(0).START_Y);
	of_extr = of_extr + ',' + buff + "):(";
	sprintf(buff, "%d", taskg->at(0).SIZE_X);
	of_extr = of_extr + buff + '*';
	sprintf(buff, "%d", taskg->at(0).SIZE_Y);
	of_extr = of_extr + buff + ")->(";
	sprintf(buff, "%d", taskg->at(0).SIZE_OUT_X);
	of_extr = of_extr + buff + "*";
	sprintf(buff, "%d", taskg->at(0).SIZE_OUT_Y);
	of_extr = of_extr + buff + ")";

	sprintf(buff, "%-42.40s", of_extr.c_str());					osOut.append(buff);
	sprintf(buff, "%-10.3f", timeuse_ms / 1000.0);				osOut.append(buff);

	if (mode == 1 || mode == 2){
		unsigned long  amount = taskg->size() * taskg->at(0).SIZE_X * taskg->at(0).SIZE_Y * taskg->at(0).bands * taskg->at(0).deap;
		float speed = amount * 1000.0 / (1024 * 1024 * timeuse_ms);
		sprintf(buff, "%-10.1f\n", speed);
	}
	else{
		sprintf(buff, "%-10.1s\n", "");
	}
	osOut.append(buff);

}

/************************************************************************/
/*                             TaskOutput()                             */
/************************************************************************/
void TaskOutput(TASK* task, float timeuse_ms, CPLString & osOut, GIntBig PID)
{
	osOut.clear();
	char buff[100];

	osOut.append("  ");
	sprintf(buff, "%-40.38s", CPLGetFilename(task->filepath));	osOut.append(buff);
	sprintf(buff, "%-6d", PID);									osOut.append(buff);
	sprintf(buff, "%-8s", "");									osOut.append(buff);

	sprintf(buff, "%d", task->f_sizex);
	string of_xyb = buff;
	sprintf(buff, "%d", task->f_sizey);
	of_xyb = of_xyb + '*' + buff + '/';
	sprintf(buff, "%d", task->bands);
	of_xyb = of_xyb + buff + '/';
	sprintf(buff, "%d", task->deap);
	of_xyb = of_xyb + buff;

	sprintf(buff, "%-18.18s", of_xyb.c_str());					osOut.append(buff);

	if (mode == 3){
		sprintf(buff, "%-7d", curlayer);						osOut.append(buff);
	}
	else if (mode == 1 || mode == 2){
		sprintf(buff, "%-7s", "");								osOut.append(buff);
	}


	sprintf(buff, "(%d", task->START_X);
	string of_extr = buff;
	sprintf(buff, "%d", task->START_Y);
	of_extr = of_extr + ',' + buff + "):(";
	sprintf(buff, "%d", task->SIZE_X);
	of_extr = of_extr + buff + '*';
	sprintf(buff, "%d", task->SIZE_Y);
	of_extr = of_extr + buff + ")->(";
	sprintf(buff, "%d", task->SIZE_OUT_X);
	of_extr = of_extr + buff + "*";
	sprintf(buff, "%d", task->SIZE_OUT_Y);
	of_extr = of_extr + buff + ")";

	sprintf(buff, "%-42.40s", of_extr.c_str());					osOut.append(buff);
	sprintf(buff, "%-10.3f", timeuse_ms / 1000.0);				osOut.append(buff);

	if (mode == 1 || mode == 2){
		unsigned long  amount = task->SIZE_X * task->SIZE_Y * task->bands * task->deap;
		float speed = amount * 1000.0 / (1024 * 1024 * timeuse_ms);
		sprintf(buff, "%-10.1f\n", speed);
	}
	else{
		sprintf(buff, "%-10.1s\n", "");
	}
	osOut.append(buff);

}

/************************************************************************/
/*                           GatherFilesInfo()                          */
/************************************************************************/

void GatherFilesInfo(void)
{
	info Info;
	vector<info>::iterator infoiter;
	for (vector<string>::iterator iter = files.begin(); iter != files.end(); iter++){

		Info.filepath = (*iter).c_str();
		//get filesize
		VSILFILE *fpL = NULL;
		fpL = VSIFOpenL((*iter).c_str(), "rb");
		if (fpL == NULL)
		{
			cout << "VSIFOpenL(...) Open File: " << (*iter).c_str() << " Failed!" << endl;
			exit(1);
		}
		GUIntBig nFileSize;
		VSIFSeekL(fpL, 0, SEEK_END);
		nFileSize = VSIFTellL(fpL);
		VSIFCloseL(fpL);
		fpL = NULL;
		Info.SIZE = nFileSize;
		TotalFilesSize += nFileSize;

		GDALDataset *poDataset;
		poDataset = (GDALDataset*)GDALOpen((*iter).c_str(), GA_ReadOnly);

		if (!poDataset){
			cout << "GDALOpen(...) Open File: " << (*iter).c_str() << " Failed!" << endl;
			exit(1);
		}

		Info.bands = poDataset->GetRasterCount();
		Info.SIZE_X = poDataset->GetRasterXSize();
		Info.SIZE_Y = poDataset->GetRasterYSize();
		Info.deap = poDataset->GetRasterBand(1)->GetRasterDataType();

		infoiter = FilesInfo.insert(FilesInfo.end(), Info);
	}
}

/************************************************************************/
/*                           AssignTask_mode1()                         */
/************************************************************************/
void AssignTask_mode1(void)
{
	TASK task;
	TASKGROUP taskg;
	vector<TASK>::iterator iter_taskg;
	vector<TASKGROUP>::iterator iter_atask;

	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
		task.filepath = (*iter).filepath;
		if ((*iter).SIZE > MAXBUFSIZE){
			task.START_X = 0;
			task.SIZE_X = (*iter).SIZE_X;
			task.SIZE_OUT_X = (*iter).SIZE_X;
			int SIZE_Y_R = MAXBUFSIZE / ((*iter).SIZE_X *(*iter).bands * (*iter).deap);

			for (int i = 0; i <= (*iter).SIZE_Y / SIZE_Y_R; i++){
				task.START_Y = SIZE_Y_R * i;
				task.SIZE_Y = SIZE_Y_R;
				if (i == (*iter).SIZE_Y / SIZE_Y_R)
					task.SIZE_Y = (*iter).SIZE_Y % SIZE_Y_R;
				task.SIZE_OUT_Y = task.SIZE_Y;
				task.bands = (*iter).bands;
				task.deap = (*iter).deap;
				task.rand = rand();
				task.f_sizex = (*iter).SIZE_X;
				task.f_sizey = (*iter).SIZE_Y;
				taskg.clear();
				iter_taskg = taskg.insert(taskg.end(), task);
				iter_atask = AllTask.insert(AllTask.end(), taskg);
			}
		}
		else{
			task.START_X = task.START_Y = 0;
			task.SIZE_X = (*iter).SIZE_X;
			task.SIZE_Y = (*iter).SIZE_Y;
			task.SIZE_OUT_X = (*iter).SIZE_X;
			task.SIZE_OUT_Y = (*iter).SIZE_Y;
			task.bands = (*iter).bands;
			task.deap = (*iter).deap;
			task.rand = rand();
			task.f_sizex = (*iter).SIZE_X;
			task.f_sizey = (*iter).SIZE_Y;
			taskg.clear();
			iter_taskg = taskg.insert(taskg.end(), task);
			iter_atask = AllTask.insert(AllTask.end(), taskg);
		}
	}
}
/************************************************************************/
/*                           AssignTask_mode2()                         */
/************************************************************************/

void AssignTask_mode2(void)
{
	TASK task;
	TASKGROUP taskg;
	vector<TASK>::iterator iter_taskg;
	vector<TASKGROUP>::iterator iter_atask;

	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
		task.filepath = (*iter).filepath;
		for (int iy = 0; iy <= (*iter).SIZE_Y / 512; iy++){ //y axis
			taskg.clear();
			for (int ix = 0; ix <= (*iter).SIZE_X / 512; ix++) //x axis
			{
				ix == (*iter).SIZE_X / 512 ? task.SIZE_X = (*iter).SIZE_X % 512 : task.SIZE_X = 512;
				iy == (*iter).SIZE_Y / 512 ? task.SIZE_Y = (*iter).SIZE_Y % 512 : task.SIZE_Y = 512;
				task.START_X = 512 * ix;
				task.START_Y = 512 * iy;
				task.SIZE_OUT_X = task.SIZE_X;
				task.SIZE_OUT_Y = task.SIZE_Y;
				task.bands = (*iter).bands;
				task.deap = (*iter).deap;
				task.rand = rand();
				task.f_sizex = (*iter).SIZE_X;
				task.f_sizey = (*iter).SIZE_Y;
				iter_taskg = taskg.insert(taskg.end(), task);
			}
			iter_atask = AllTask.insert(AllTask.end(), taskg);
		}
	}
}

/************************************************************************/
/*                           AssignTask_mode3()                         */
/************************************************************************/

int AssignTask_mode3(int count)
{
	TASK task;
	TASKGROUP taskg;
	vector<TASK>::iterator iter_taskg;
	vector<TASKGROUP>::iterator iter_atask;
	int times = pow(2, count - 1);
	int taskg_count = 0;

	AllTask.clear();
	for (vector<info>::iterator iter = FilesInfo.begin(); iter != FilesInfo.end(); iter++){
		task.filepath = (*iter).filepath;
		int maxXY = (*iter).SIZE_X > (*iter).SIZE_Y ? (*iter).SIZE_X : (*iter).SIZE_Y;
		int stepleng = maxXY / times;

		if (stepleng <= 512 / 2)
			continue;

		if (count == 1){
			task.START_X = 0;
			task.START_Y = 0;
			task.SIZE_X = (*iter).SIZE_X;
			task.SIZE_Y = (*iter).SIZE_Y;
			task.SIZE_OUT_X = 512 * task.SIZE_X / maxXY;
			task.SIZE_OUT_Y = 512 * task.SIZE_Y / maxXY;
			task.bands = (*iter).bands;
			task.deap = (*iter).deap;
			task.rand = rand();
			task.f_sizex = (*iter).SIZE_X;
			task.f_sizey = (*iter).SIZE_Y;
			taskg.clear();
			iter_taskg = taskg.insert(taskg.end(), task);
			iter_atask = AllTask.insert(AllTask.end(), taskg);
			taskg_count++;
		}
		else{
			for (int iy = 0; iy <= ((*iter).SIZE_Y - 1) / stepleng && iy < times; iy++){
				taskg.clear();
				for (int ix = 0; ix <= ((*iter).SIZE_X - 1) / stepleng && ix < times; ix++){
					task.START_X = stepleng * ix;
					task.START_Y = stepleng * iy;

					if (ix == ((*iter).SIZE_X - 1) / stepleng){
						task.SIZE_X = ((*iter).SIZE_X - 1) % stepleng + 1;
						task.SIZE_OUT_X = 512 * task.SIZE_X / stepleng;
					}
					else{
						task.SIZE_X = stepleng;
						task.SIZE_OUT_X = 512;
					}

					if (iy == ((*iter).SIZE_Y - 1) / stepleng){
						task.SIZE_Y = ((*iter).SIZE_Y - 1) % stepleng + 1;
						task.SIZE_OUT_Y = 512 * task.SIZE_Y / stepleng;
					}
					else{
						task.SIZE_Y = stepleng;
						task.SIZE_OUT_Y = 512;
					}
					task.bands = (*iter).bands;
					task.deap = (*iter).deap;
					task.rand = rand();
					task.f_sizex = (*iter).SIZE_X;
					task.f_sizey = (*iter).SIZE_Y;
					iter_taskg = taskg.insert(taskg.end(), task);
				}
				iter_atask = AllTask.insert(AllTask.end(), taskg);
				taskg_count++;
			}//onefile
		}
	}//allfile
	return taskg_count;
}

/************************************************************************/
/*                            f_ExitIfTure()                            */
/************************************************************************/
void f_ExitIfTure(int val, const char* pstr)
{
	if (val == 1){
		cout << "ERROR! " << (pstr ? pstr : "") << endl;
		exit(1);
		return;
	}
}

/************************************************************************/
/*                              getFiles()                              */
/************************************************************************/
#ifdef WIN32
void getFiles(string path, vector<string>& files)
{
	if (path.at(path.length() - 1) == '\\')
		path.erase(path.length() - 1);
	long   hFile = 0;				//File hadle
	struct _finddata_t fileinfo;	//File info
	string p;
	if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1)
	{
		do
		{	//If it is a directory, iteration, if not, join the list
			if ((fileinfo.attrib &  _A_SUBDIR) && recursive == 1)
			{
				if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0)
					getFiles(p.assign(path).append("\\").append(fileinfo.name), files);
			}
			else
			{
				files.push_back(p.assign(path).append("\\").append(fileinfo.name));
			}
		} while (_findnext(hFile, &fileinfo) == 0);
		_findclose(hFile);
	}
}
#else
void getFiles(string o_path, vector<string>& files)
{
	if (o_path.at(o_path.length() - 1) == '/')
		o_path.erase(o_path.length() - 1);
	const char *path = o_path.c_str();
	DIR		*pDir;
	struct dirent	*ent;
	int		i = 0;
	char	childpath[512];

	pDir = opendir(path);
	memset(childpath, 0, sizeof(childpath));
	string p;
	while ((ent = readdir(pDir)) != NULL){
		if (ent->d_type & DT_DIR && recursive == 1){
			if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0)
				continue;
			sprintf(childpath, "%s/%s", path, ent->d_name);
			getFiles(childpath, files);
		}
		else /*if(ent->d_type & DT_REG)*/{
			files.push_back(p.assign(path).append("/").append(ent->d_name));
		}
	}
}

#endif

/************************************************************************/
/*                            DateTimeStr()                             */
/************************************************************************/
char* DateTimeStr(void)
{
	time_t rawtime;
	struct tm* timeinfo;
	time(&rawtime);
	timeinfo = localtime(&rawtime);
	strftime(timE, 80, "%Y-%m-%d_%H-%M-%S", timeinfo);
	return timE;
}
posted @ 2020-07-24 16:33  乌合之众  阅读(374)  评论(0编辑  收藏  举报
clear