风言枫语  

之前在GDALDestroyDriverManager 分析中没有看到对dGDALDatasert的回收。先看一个例子程序,这个例子打开了一个tif文件,读取了一些基本信息。

为了简单示范,没有写成C++的各种类分散到各个文件中。

 

#include "stdafx.h"
#include "gdal_priv.h"
#include "cpl_conv.h" // for CPLMalloc()
#include <string>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <boost/cstdint.hpp>

using namespace std;

void print_line() {
	cout << "----------------------" << endl;
}

void printDataType(GDALDataType type) {
	if (type == GDALDataType::GDT_Byte) {
		cout << "GDALDataType: GDT_Byte" << endl;
	} else {
		cout << "GDALDataType: GDT_Unknown" << endl;
	}
}

void printAccess(GDALAccess access) {
	if (access == GDALAccess::GA_ReadOnly) {
		cout << "GDALAccess: GA_ReadOnly" << endl;
	} else {
		cout << "GDALAccess: GA_Update" << endl;
	}
}

void printCategoryNames(char** names) {
	if (names == NULL) {
		cout << "non category names" << endl;
		return;
	}
	size_t i = 0;
	char* str = names[i];
	while(str != "") {
		cout << str << endl;
		str = names[i];
	}
}

void printColorInterp(GDALColorInterp interp) {
	switch(interp) {
	case GDALColorInterp::GCI_AlphaBand:
		cout << "GDALColorInterp: GCI_AlphaBand" << endl;
		break;
	case GDALColorInterp::GCI_BlackBand:
		cout << "GDALColorInterp: GCI_BlackBand" << endl;
		break;
	case GDALColorInterp::GCI_RedBand:
		cout << "GDALColorInterp: GCI_RedBand" << endl;
		break;
	case GDALColorInterp::GCI_GreenBand:
		cout << "GDALColorInterp: GCI_GreenBand" << endl;
		break;
	case GDALColorInterp::GCI_BlueBand:
		cout << "GDALColorInterp: GCI_BlueBand" << endl;
		break;
	default:
		cout << "GDALColorInterp: GCI_Undefined: " << interp << endl;
	}
}

void printColorTable(GDALColorTable* table) {
	if (table == NULL) {
		cout << "color table is null" << endl;
		return;
	}

	cout << "ColorEntryCount: " << table->GetColorEntryCount() << endl;
}

string getBytesAsHexString(uint8_t * data, size_t size) {
	stringstream stream;
	stream << std::hex << std::uppercase << std::setfill('0');
	for (size_t i = 0; i < size; ++i) {
		stream <<std::setw(2) << static_cast<uint32_t>(data[i] & 0xff) << " ";
	}
	return stream.str();
}

void printBand(GDALRasterBand* band) {
	cout << "XSize: " << band->GetXSize() << endl;
	cout << "YSize: " << band->GetYSize() << endl;
	cout << "Band number(index for itself): " << band->GetBand() << endl;
	printDataType(band->GetRasterDataType());
	int x_size = 0;
	int y_size = 0;
	band->GetBlockSize(&x_size, &y_size);
	cout << "Band Block size, x size: " << x_size << " pixels , y size: " << y_size << " pixels" << endl;
	printAccess(band->GetAccess());
	printCategoryNames(band->GetCategoryNames());
	cout << "no data value: " << band->GetNoDataValue() << endl;
	cout << "minimum value: " << band->GetMinimum() << endl;
	cout << "maximum value: " << band->GetMaximum() << endl;
	cout << "offset value: " << band->GetOffset() << endl;
	cout << "scale value: " << band->GetScale() << endl;
	cout << "unit type: " << band->GetUnitType() << endl;
	printColorInterp(band->GetColorInterpretation());
	printColorTable(band->GetColorTable());

	GByte * data = static_cast<GByte*>(CPLMalloc(x_size * y_size));
	band->ReadBlock(5000, 3000, data);
	cout << "one block data: " << getBytesAsHexString(data, x_size * y_size) << endl;
}

void printTiffInfo(GDALDataset* set) {
	print_line();
	cout << "Tiff info " << endl;
	cout << "RasterXSize: " << set->GetRasterXSize() << endl;
	cout << "RasterYSize: " << set->GetRasterYSize() << endl;
	size_t band_count = set->GetRasterCount();
	cout << "Raster band count: " << band_count << endl;
	for (size_t i = 1; i <= band_count; ++i) {
		GDALRasterBand* band = set->GetRasterBand(i);
		print_line();
		cout << "Band " << i << " : " << endl;
		printBand(band);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	
	GDALAllRegister();
	string data_dir = "../../../study/data/";
	string tiffPath = data_dir + "v4_dem_gtopo30/v4_dem.tif";
	GDALDataset* dataset = (GDALDataset *) GDALOpen(tiffPath.c_str(), GA_ReadOnly);
    if (dataset == NULL) {
		cout << "open ttf file in TiffCopy app failed" << endl;
		GDALDestroyDriverManager();
		exit(1);
    }

	cout << "loading tiff file successfully" << endl;
	printTiffInfo(dataset);

	GDALClose(dataset);
	GDALDestroyDriverManager();
	return 0;
}


在main函数中,用GDALOpen打开了一个tif文件,并且获得了GDALDataset对象的指针,然后用GDALClose销毁了这个对象。下面是GDALClose代码:

 

 

/**
 * \brief Close GDAL dataset. 
 *
 * For non-shared datasets (opened with GDALOpen()) the dataset is closed
 * using the C++ "delete" operator, recovering all dataset related resources.  
 * For shared datasets (opened with GDALOpenShared()) the dataset is 
 * dereferenced, and closed only if the referenced count has dropped below 1.
 *
 * @param hDS The dataset to close.  May be cast from a "GDALDataset *". 
 */

void CPL_STDCALL GDALClose( GDALDatasetH hDS )

{
    VALIDATE_POINTER0( hDS, "GDALClose" );

    GDALDataset *poDS = (GDALDataset *) hDS;
    CPLMutexHolderD( &hDLMutex );
    CPLLocaleC  oLocaleForcer;

    if (poDS->GetShared())
    {
/* -------------------------------------------------------------------- */
/*      If this file is in the shared dataset list then dereference     */
/*      it, and only delete/remote it if the reference count has        */
/*      dropped to zero.                                                */
/* -------------------------------------------------------------------- */
        if( poDS->Dereference() > 0 )
            return;

        delete poDS;
        return;
    }

/* -------------------------------------------------------------------- */
/*      This is not shared dataset, so directly delete it.              */
/* -------------------------------------------------------------------- */
    delete poDS;
}


注释表明GDALDataset支持普通和引用计数管理两种生命周期管理方式。代码中表明在销毁的时候使用了互斥量,因此是线程安全的。

 

 

 

 

posted on 2013-08-15 19:49  风言枫语  阅读(1245)  评论(0编辑  收藏  举报