void vtBitmapBase::ScalePixel32(int x, int y, float fScale) { RGBAi rgba; GetPixel32(x, y, rgba); rgba.MultRGB(fScale); if (rgba.r > 255) rgba.r = 255; if (rgba.g > 255) rgba.g = 255; if (rgba.b > 255) rgba.b = 255; SetPixel32(x, y, rgba); }
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; }