Esempio n. 1
0
 virtual CPLErr IReadBlock( int nBlockXOff, int nBlockYOff, void * pData )
 {
     return poUnderlyingBand->ReadBlock(nBlockXOff, nBlockYOff, pData);
 }
Esempio n. 2
0
bool vtImageGeo::ReadTIF(const char *filename, bool progress_callback(int))
{
	// Use GDAL to read a TIF file (or any other format that GDAL is
	//  configured to read) into this OSG image.
	bool bRet = true;
	vtString message;

	setFileName(filename);

	g_GDALWrapper.RequestGDALFormats();

	GDALDataset *pDataset = NULL;
	GDALRasterBand *pBand;
	GDALRasterBand *pRed = NULL;
	GDALRasterBand *pGreen = NULL;
	GDALRasterBand *pBlue = NULL;
	GDALRasterBand *pAlpha = NULL;
	GDALColorTable *pTable;
	uchar *pScanline = NULL;
	uchar *pRedline = NULL;
	uchar *pGreenline = NULL;
	uchar *pBlueline = NULL;
	uchar *pAlphaline = NULL;

	CPLErr Err;
	bool bColorPalette = false;
	int iXSize, iYSize;
	int nxBlocks, nyBlocks;
	int xBlockSize, yBlockSize;

	try
	{
		pDataset = (GDALDataset *) GDALOpen(filename, GA_ReadOnly);
		if(pDataset == NULL )
			throw "Couldn't open that file.";

		// Get size
		iXSize = pDataset->GetRasterXSize();
		iYSize = pDataset->GetRasterYSize();

		// Try getting CRS
		vtProjection temp;
		bool bHaveProj = false;
		const char *pProjectionString = pDataset->GetProjectionRef();
		if (pProjectionString)
		{
			OGRErr err = temp.importFromWkt((char**)&pProjectionString);
			if (err == OGRERR_NONE)
			{
				m_proj = temp;
				bHaveProj = true;
			}
		}
		if (!bHaveProj)
		{
			// check for existence of .prj file
			bool bSuccess = temp.ReadProjFile(filename);
			if (bSuccess)
			{
				m_proj = temp;
				bHaveProj = true;
			}
		}

		// Try getting extents
		double affineTransform[6];
		if (pDataset->GetGeoTransform(affineTransform) == CE_None)
		{
			m_extents.left = affineTransform[0];
			m_extents.right = m_extents.left + affineTransform[1] * iXSize;
			m_extents.top = affineTransform[3];
			m_extents.bottom = m_extents.top + affineTransform[5] * iYSize;
		}

		// Raster count should be 3 for colour images (assume RGB)
		int iRasterCount = pDataset->GetRasterCount();

		if (iRasterCount != 1 && iRasterCount != 3 && iRasterCount != 4)
		{
			message.Format("Image has %d bands (not 1, 3, or 4).", iRasterCount);
			throw (const char *)message;
		}

		if (iRasterCount == 1)
		{
			pBand = pDataset->GetRasterBand(1);

			// Check the band's data type
			GDALDataType dtype = pBand->GetRasterDataType();
			if (dtype != GDT_Byte)
			{
				message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype));
				throw (const char *)message;
			}
			GDALColorInterp ci = pBand->GetColorInterpretation();

			if (ci == GCI_PaletteIndex)
			{
				if (NULL == (pTable = pBand->GetColorTable()))
					throw "Couldn't get color table.";
				bColorPalette = true;
			}
			else if (ci == GCI_GrayIndex)
			{
				// we will assume 0-255 is black to white
			}
			else
				throw "Unsupported color interpretation.";

			pBand->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize;
			if (NULL == (pScanline = new uchar[xBlockSize * yBlockSize]))
				throw "Couldnt allocate scan line.";
		}

		if (iRasterCount == 3)
		{
			for (int i = 1; i <= 3; i++)
			{
				pBand = pDataset->GetRasterBand(i);

				// Check the band's data type
				GDALDataType dtype = pBand->GetRasterDataType();
				if (dtype != GDT_Byte)
				{
					message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype));
					throw (const char *)message;
				}
				switch (pBand->GetColorInterpretation())
				{
				case GCI_RedBand:
					pRed = pBand;
					break;
				case GCI_GreenBand:
					pGreen = pBand;
					break;
				case GCI_BlueBand:
					pBlue = pBand;
					break;
				}
			}
			if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue))
				throw "Couldn't find bands for Red, Green, Blue.";

			pRed->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize;

			pRedline = new uchar[xBlockSize * yBlockSize];
			pGreenline = new uchar[xBlockSize * yBlockSize];
			pBlueline = new uchar[xBlockSize * yBlockSize];
		}

		if (iRasterCount == 4)
		{
#if VTDEBUG
			VTLOG1("Band interpretations:");
#endif
			for (int i = 1; i <= 4; i++)
			{
				pBand = pDataset->GetRasterBand(i);

				// Check the band's data type
				GDALDataType dtype = pBand->GetRasterDataType();
				if (dtype != GDT_Byte)
				{
					message.Format("Band is of type %s, but we support type Byte.", GDALGetDataTypeName(dtype));
					throw (const char *)message;
				}
				GDALColorInterp ci = pBand->GetColorInterpretation();
#if VTDEBUG
				VTLOG(" %d", ci);
#endif
				switch (ci)
				{
				case GCI_RedBand:
					pRed = pBand;
					break;
				case GCI_GreenBand:
					pGreen = pBand;
					break;
				case GCI_BlueBand:
					pBlue = pBand;
					break;
				case GCI_AlphaBand:
					pAlpha = pBand;
					break;
				case GCI_Undefined:
					// If we have four bands: R,G,B,undefined, then assume that
					//  the undefined one is actually alpha
					if (pRed && pGreen && pBlue && !pAlpha)
						pAlpha = pBand;
					break;
				}
			}
#if VTDEBUG
			VTLOG1("\n");
#endif
			if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue) || (NULL == pAlpha))
				throw "Couldn't find bands for Red, Green, Blue, Alpha.";

			pRed->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iXSize + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iYSize + yBlockSize - 1) / yBlockSize;

			pRedline = new uchar[xBlockSize * yBlockSize];
			pGreenline = new uchar[xBlockSize * yBlockSize];
			pBlueline = new uchar[xBlockSize * yBlockSize];
			pAlphaline = new uchar[xBlockSize * yBlockSize];
		}

		// Allocate the image buffer
		if (iRasterCount == 4)
		{
			Create(iXSize, iYSize, 32);
		}
		else if (iRasterCount == 3 || bColorPalette)
		{
			Create(iXSize, iYSize, 24);
		}
		else if (iRasterCount == 1)
			Create(iXSize, iYSize, 8);

		// Read the data
#if LOG_IMAGE_LOAD
		VTLOG("Reading the image data (%d x %d pixels)\n", iXSize, iYSize);
#endif

		int x, y;
		int ixBlock, iyBlock;
		int nxValid, nyValid;
		int iY, iX;
		RGBi rgb;
		RGBAi rgba;
		if (iRasterCount == 1)
		{
			GDALColorEntry Ent;
			for (iyBlock = 0; iyBlock < nyBlocks; iyBlock++)
			{
				if (progress_callback != NULL)
					progress_callback(iyBlock * 100 / nyBlocks);

				y = iyBlock * yBlockSize;
				for (ixBlock = 0; ixBlock < nxBlocks; ixBlock++)
				{
					x = ixBlock * xBlockSize;
					Err = pBand->ReadBlock(ixBlock, iyBlock, pScanline);
					if (Err != CE_None)
						throw "Problem reading the image data.";

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iXSize)
						nxValid = iXSize - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iYSize)
						nyValid = iYSize - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for( iY = 0; iY < nyValid; iY++ )
					{
						for( iX = 0; iX < nxValid; iX++ )
						{
							if (bColorPalette)
							{
								pTable->GetColorEntryAsRGB(pScanline[iY * xBlockSize + iX], &Ent);
								rgb.r = (uchar) Ent.c1;
								rgb.g = (uchar) Ent.c2;
								rgb.b = (uchar) Ent.c3;
								SetPixel24(x + iX, y + iY, rgb);
							}
							else
								SetPixel8(x + iX, y + iY, pScanline[iY * xBlockSize + iX]);
						}
					}
				}
			}
		}
		if (iRasterCount >= 3)
		{
			for (iyBlock = 0; iyBlock < nyBlocks; iyBlock++)
			{
				if (progress_callback != NULL)
					progress_callback(iyBlock * 100 / nyBlocks);

				y = iyBlock * yBlockSize;
				for (ixBlock = 0; ixBlock < nxBlocks; ixBlock++)
				{
					x = ixBlock * xBlockSize;
					Err = pRed->ReadBlock(ixBlock, iyBlock, pRedline);
					if (Err != CE_None)
						throw "Cannot read data.";
					Err = pGreen->ReadBlock(ixBlock, iyBlock, pGreenline);
					if (Err != CE_None)
						throw "Cannot read data.";
					Err = pBlue->ReadBlock(ixBlock, iyBlock, pBlueline);
					if (Err != CE_None)
						throw "Cannot read data.";
					if (iRasterCount == 4)
					{
						Err = pAlpha->ReadBlock(ixBlock, iyBlock, pAlphaline);
						if (Err != CE_None)
							throw "Cannot read data.";
					}

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iXSize)
						nxValid = iXSize - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iYSize)
						nyValid = iYSize - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for (int iY = 0; iY < nyValid; iY++)
					{
						for (int iX = 0; iX < nxValid; iX++)
						{
							if (iRasterCount == 3)
							{
								rgb.r = pRedline[iY * xBlockSize + iX];
								rgb.g = pGreenline[iY * xBlockSize + iX];
								rgb.b = pBlueline[iY * xBlockSize + iX];
								SetPixel24(x + iX, y + iY, rgb);
							}
							else if (iRasterCount == 4)
							{
								rgba.r = pRedline[iY * xBlockSize + iX];
								rgba.g = pGreenline[iY * xBlockSize + iX];
								rgba.b = pBlueline[iY * xBlockSize + iX];
								rgba.a = pAlphaline[iY * xBlockSize + iX];
								SetPixel32(x + iX, y + iY, rgba);
							}
						}
					}
				}
			}
		}
	}
	catch (const char *msg)
	{
		VTLOG1("Problem: ");
		VTLOG1(msg);
		VTLOG1("\n");
		bRet = false;
	}

	if (NULL != pDataset)
		GDALClose(pDataset);
	if (NULL != pScanline)
		delete pScanline;
	if (NULL != pRedline)
		delete pRedline;
	if (NULL != pGreenline)
		delete pGreenline;
	if (NULL != pBlueline)
		delete pBlueline;
	if (NULL != pAlphaline)
		delete pAlphaline;

	return bRet;
}
Esempio n. 3
0
	bool DEM::load(const std::string& filename) {
		GDALAllRegister();

		GDALDataset* poDS;
		poDS = (GDALDataset*)GDALOpenEx(filename.c_str(), GDAL_OF_RASTER, NULL, NULL, NULL);
		if (poDS == NULL) return false;

		double adfGeoTransform[6];
		if (poDS->GetGeoTransform(adfGeoTransform) == CE_None) {
			origin.x = adfGeoTransform[0];
			origin.y = adfGeoTransform[3];

			pixelSize.x = adfGeoTransform[1];
			pixelSize.y = abs(adfGeoTransform[5]);
		}

		width = poDS->GetRasterXSize() * pixelSize.x;
		height = poDS->GetRasterYSize() * pixelSize.y;
		data.resize(width * height);
		min_val = std::numeric_limits<float>::max();
		max_val = -std::numeric_limits<float>::max();

		// bandが存在しない場合は、エラー
		if (poDS->GetRasterCount() == 0) return false;

		// 最初のbandのみを読み込む。複数bandは未対応
		GDALRasterBand* poBand = poDS->GetRasterBand(1);

		int nBlockXSize, nBlockYSize;
		poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
		//printf("Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName(poBand->GetColorInterpretation()));

		// 最低、最高の値を取得
		int bGotMin, bGotMax;
		double adfMinMax[2];
		adfMinMax[0] = poBand->GetMinimum(&bGotMin);
		adfMinMax[1] = poBand->GetMaximum(&bGotMax);
		if (!(bGotMin && bGotMax)) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
		//printf("Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1]);
		min_val = adfMinMax[0];
		max_val = adfMinMax[1];
			
		//int nXSize = poBand->GetXSize();
		//int nYSize = poBand->GetYSize();

		int nXBlocks = (poBand->GetXSize() + nBlockXSize - 1) / nBlockXSize;
		int nYBlocks = (poBand->GetYSize() + nBlockYSize - 1) / nBlockYSize;
		float *pData = (float *)CPLMalloc(sizeof(float*) * nBlockXSize * nBlockYSize);
		for (int iYBlock = 0; iYBlock < nYBlocks; iYBlock++) {
			for (int iXBlock = 0; iXBlock < nXBlocks; iXBlock++) {
				int nXValid, nYValid;

				poBand->ReadBlock(iXBlock, iYBlock, pData);

				// Compute the portion of the block that is valid
				// for partial edge blocks.
				if ((iXBlock + 1) * nBlockXSize > poBand->GetXSize())
					nXValid = poBand->GetXSize() - iXBlock * nBlockXSize;
				else
					nXValid = nBlockXSize;
				if ((iYBlock + 1) * nBlockYSize > poBand->GetYSize())
					nYValid = poBand->GetYSize() - iYBlock * nBlockYSize;
				else
					nYValid = nBlockYSize;

				for (int iY = 0; iY < nYValid; iY++) {
					for (int iX = 0; iX < nXValid; iX++) {
						float val;
						if (pData[iY * nBlockXSize + iX] > max_val) {
							val = max_val;
						}
						else if (pData[iY * nBlockXSize + iX] < min_val) {
							val = min_val;
						}
						else {
							val = pData[iY * nBlockXSize + iX];
						}

						for (int y = 0; y < pixelSize.y; ++y) {
							for (int x = 0; x < pixelSize.x; ++x) {
								data[((iYBlock * nBlockYSize + iY) * pixelSize.y + y) * width + (iXBlock * nBlockXSize + iX) * pixelSize.x + x] = val;
							}
						}
						
					}
				}
			}
		}

		GDALClose(poDS);

		return true;
	}