GdalUser
#pragma once #include <string> #include <vector> #include "gdal.h" #include "gdal_priv.h" #include <io.h> #ifdef _DEBUG #pragma comment(lib, "gdal\\x64\\gdal_i.lib") #else #pragma comment(lib, "gdal\\x64\\gdal_i.lib") #endif class CGdalUser { public: CGdalUser(); ~CGdalUser(); public: double m_LBX; double m_LBY; double m_RTX; double m_RTY; double m_lfGSD; GDALDataType m_nDataType; int m_nImgWidth; int m_nImgHeight; int m_nBandNum; int m_nBPB; int m_nBPP; std::string m_strFilePath; public: //创建文件初始化 bool InitializeCreate(const char* szFilePath, GDALDataType nDataType, const int& widthDst, const int& heightDst, const int& nBandNum); //读取文件初始化 bool InitializeReadImg(const char* szFilePath, const bool& b16Trans8 = false); //左下角为起始点的 bool ReadImage(int nStartCol, int nStartRow, int nWidth, int nHeight, unsigned char* pData, int nBufferWidth, int nBufferHeight); bool WriteImage(int nStartCol, int nStartRow, int nWidth, int nHeight, unsigned char* pData, int nBufferWidth, int nBufferHeight); //已经准备好读取或者写入 inline bool IsImgReady(); int ReadImg(int nSrcLeft, int nSrcTop, int nSrcRight, int nSrcBottom, unsigned char* pBuf, int nBufWid, int nBufHeight, int nBandNum, int nDestLeft, int nDestTop, int nDestRight, int nDestBottom, int nSrcSkip, int nDestSkip); int WriteImg(int nSrcLeft, int nSrcTop, int nSrcRight, int nSrcBottom, unsigned char* pBuf, int nBufWid, int nBufHeight, int nBandNum, int nDestLeft, int nDestTop, int nDestRight, int nDestBottom, int nSrcSkip, int nDestSkip); //一次性全部读取,左上角为起点,内部分配内存,记得外部delete[],否则内存泄露 static bool ReadImageGDAL(const char* pFilePath, unsigned char **pImageData, GDALDataType nDataType, int& widthDst, int& heightDst, int& nBandNum); //一次性全部写入,左上角为起点,内部只读内存,记得外部delete[],否则内存泄露 static bool WriteImageGDAL(const char* pFilePath, unsigned char *pImageData, GDALDataType nDataType, int width, int height, int nChannels); static char* findImageTypeGDAL(char *pDstImgFileName); //根据格式类型获取占用字节数 static int GetBPB(const GDALDataType& nDataType); //数据的通道重新排序,例如BGR转RGB, arrNewSeq = {2,1,0}即可 static int ReseqChannels(unsigned char* pData, const int& nRows, const int& nCols, const int& nBandNum, const int& nBPB, int arrNewSeq[]); //数据y方向进行翻转 static int VerticalReverse(unsigned char* pData, const int& nRows, const int& nCols, const int& nBandNum, const int& nBPB); private: bool m_bTranto8bit; double* m_plfCount; double* m_pHist; GDALDataset *m_poDataset; int m_nOldBytesPerBand; unsigned char* m_plut; };
#include ".\GdalUser.h" CGdalUser::CGdalUser() { m_LBX = 0.0; m_LBY = 0.0; m_RTX = 0.0; m_RTY = 0.0; m_lfGSD = 1.0; m_nDataType = GDT_Unknown; m_nImgWidth = -1; m_nImgHeight = -1; m_nBandNum = -1; m_nBPB = -1; m_nBPP = -1; m_strFilePath = ""; m_bTranto8bit = false; m_plfCount = nullptr; m_pHist = nullptr; m_poDataset = nullptr; m_nOldBytesPerBand = 0; m_plut = nullptr; } CGdalUser::~CGdalUser() { if (m_poDataset != nullptr) { GDALClose((GDALDatasetH)m_poDataset); m_poDataset = nullptr; } } bool CGdalUser::InitializeCreate(const char* szFilePath, GDALDataType nDataType, const int& widthDst, const int& heightDst, const int& nBandNum) { if (szFilePath == nullptr || widthDst <= 0 ||heightDst <= 0 || nBandNum <= 0 || IsImgReady()) { return false; } GDALAllRegister(); char *GType = NULL; GType = findImageTypeGDAL((char*)szFilePath); if (GType == NULL) { return false; } GDALDriver *pMemDriver = NULL; pMemDriver = GetGDALDriverManager()->GetDriverByName("MEM"); if (pMemDriver == NULL) { return false; } if (nDataType == GDT_Unknown) { nDataType = GDT_Byte; } m_nDataType = nDataType; m_nImgWidth = widthDst; m_nImgHeight = heightDst; m_nBandNum = nBandNum; m_nBPB = GetBPB(nDataType); m_nOldBytesPerBand = m_nBPB; m_nBPP = m_nBPB * nBandNum; GDALDataset* pMemDataSet = pMemDriver->Create("", m_nImgWidth, m_nImgHeight, m_nBandNum, nDataType, NULL); GDALDriver *pDstDriver = NULL; pDstDriver = (GDALDriver *)GDALGetDriverByName(GType); if (pDstDriver == NULL) { return false; } m_poDataset = pDstDriver->CreateCopy(szFilePath, pMemDataSet, FALSE, NULL, NULL, NULL); GDALClose(pMemDataSet); return m_poDataset != nullptr; } bool CGdalUser::InitializeReadImg(const char* szFilePath, const bool& b16Trans8/* = true*/) { if (IsImgReady()) { return false; } m_strFilePath = std::string(szFilePath); const char *pszFilename = szFilePath; GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径 m_poDataset = (GDALDataset *)GDALOpen(pszFilename, GA_ReadOnly); if (m_poDataset == nullptr) { return false; } //获取基本信息 m_nImgWidth = m_poDataset->GetRasterXSize(); m_nImgHeight = m_poDataset->GetRasterYSize(); m_nBandNum = m_poDataset->GetRasterCount(); //这里假设每个通道的类型都相同 m_nDataType = m_poDataset->GetRasterBand(1)->GetRasterDataType(); m_nBPB = GetBPB(m_nDataType); m_nOldBytesPerBand = m_nBPB; m_nBPP = m_nBandNum * m_nBPB; double adfGeoTransform[6] = { 0 }; if (m_poDataset->GetGeoTransform(adfGeoTransform) == CE_None) { //左上角 m_LBX = adfGeoTransform[0]; m_RTY = adfGeoTransform[3]; m_lfGSD = adfGeoTransform[1]; } //计算出的值 m_RTX = m_LBX + m_lfGSD * m_nImgWidth; m_LBY = m_RTY - m_lfGSD * m_nImgHeight; m_bTranto8bit = m_nBPB == 2 && b16Trans8 == true; if (m_nBPB == 2 && m_bTranto8bit == true) { int nBandNum = m_nBandNum; if (m_plut) { delete[] m_plut; m_plut = NULL; } m_plut = new unsigned char[nBandNum * 65536]; memset(m_plut, 0, sizeof(unsigned char)* 65536 * nBandNum); //保存lut文件 std::string szFileName = m_strFilePath + ".czb"; if (_access(szFileName.c_str(), 0) == -1) { const int nBlockLength = 5000; double dWidthIniProp = (double)nBlockLength / m_nImgWidth; double dHeightIniProp = (double)nBlockLength / m_nImgHeight; double dIniScale = dWidthIniProp < dHeightIniProp ? dWidthIniProp : dHeightIniProp; int nIniWidth = int(m_nImgWidth * dIniScale + 0.5); int nIniHeight = int(m_nImgHeight * dIniScale + 0.5); if (dIniScale >= 1.0) { //此时不需要缩放 dIniScale = 1.0; nIniWidth = m_nImgWidth; nIniHeight = m_nImgHeight; } unsigned char *m_pBufferPy = new unsigned char[nIniWidth * nIniHeight * nBandNum * m_nBPB]; memset(m_pBufferPy, 0, nIniWidth * nIniHeight * nBandNum * m_nBPB); const int nBlock = 1024; unsigned char *m_pBlockBuffer = new unsigned char[m_nImgWidth * nBandNum * m_nBPB * nBlock]; memset(m_pBlockBuffer, 0, sizeof(unsigned char)* m_nImgWidth * nBandNum * m_nBPB * nBlock); int nBPP = m_nBPB * nBandNum; CGdalUser tif; tif.InitializeReadImg(szFilePath, false); int nRowBlockNum = (m_nImgHeight + nBlock - 1) / nBlock; for (int j = 0; j < nRowBlockNum; ++j) { memset(m_pBlockBuffer, 0, sizeof(unsigned char)* m_nImgWidth * nBandNum * m_nBPB * nBlock); tif.ReadImage(0, j * nBlock, m_nImgWidth, nBlock, m_pBlockBuffer, m_nImgWidth, nBlock); for (int m = 0; m < nIniHeight; m++) { int nSrcRows = int(m / dIniScale + 0.5) - j * nBlock; if (nSrcRows >= nBlock || nSrcRows < 0) { continue; } unsigned char *pBufferPyIndex = m_pBufferPy + m * nIniWidth * nBPP; unsigned char *pBufferBlockIndex = m_pBlockBuffer + nSrcRows * m_nImgWidth * nBPP; for (int n = 0; n < nIniWidth; n++) { int nSrcCols = int(n / dIniScale + 0.5); if (nSrcCols >= m_nImgWidth) { continue; } unsigned char *pSubBufferPyIndex = pBufferPyIndex + n * nBPP; unsigned char *pSubBufferBlockIndex = pBufferBlockIndex + nSrcCols * nBPP; memcpy(pSubBufferPyIndex, pSubBufferBlockIndex, nBPP); } } } delete[] m_pBlockBuffer; m_pBlockBuffer = NULL; m_pHist = new double[65536 * nBandNum]; memset(m_pHist, 0, sizeof(double)* 65536 * nBandNum); for (int j = 0; j < nIniHeight; ++j) { unsigned short *pBufferIndex = (unsigned short*)m_pBufferPy + j * nIniWidth * nBandNum; for (int i = 0; i < nIniWidth; ++i) { unsigned short *pSubBufferIndex = pBufferIndex + i * nBandNum; for (int k = 0; k < nBandNum; ++k) { m_pHist[k * 65536 + pSubBufferIndex[k]] += 1.0; } } } if (m_plfCount) { delete[] m_plfCount; m_plfCount = NULL; } m_plfCount = new double[10]; memset(m_plfCount, 0, sizeof(double)* 10); for (int i = 0; i < nBandNum; i++) { for (int j = 1; j < 65536; j++) { m_plfCount[i] += m_pHist[i * 65536 + j]; } } double lfMinThreshold = 0.001, lfMaxThreshold = 0.001; for (int i = 0; i < nBandNum; i++) { double lfTmpCount = 0.0001; int nMinCut = 1, nMaxCut = 65535; for (int j = 1; j < 65536; j++) { lfTmpCount += m_pHist[i * 65536 + j]; if (lfTmpCount / m_plfCount[i] > lfMinThreshold) { nMinCut = j; break; } } int nMinValue = 0, nMaxValue = 0; for (int j = 1; j < 65536; j++) { if (m_pHist[i * 65536 + j] > 1e-3) { nMinValue = j; break; } } for (int j = 65534; j > 0; j--) { if (m_pHist[i * 65536 + j] > 1e-3) { nMaxValue = j; break; } } lfTmpCount = 0.0001; for (int j = 65534; j > 0; j--) { lfTmpCount += m_pHist[i * 65536 + j]; if (lfTmpCount / m_plfCount[i] > lfMaxThreshold) { nMaxCut = j; break; } } for (int j = 1; j < nMinCut; j++) { m_plut[i * 65536 + j] = 1; } for (int j = nMinCut; j <= nMaxCut; j++) { m_plut[i * 65536 + j] = MAX(1, MIN(253, (int)(251.0 * ((double)j - nMinCut) / ((double)nMaxCut - nMinCut) + 2))); } for (int j = nMaxCut + 1; j < 65536; j++) { m_plut[i * 65536 + j] = 254; } } delete[] m_plfCount; m_plfCount = NULL; delete[] m_pHist; m_pHist = NULL; delete[] m_pBufferPy; m_pBufferPy = NULL; FILE *pFile; if (fopen_s(&pFile, szFileName.c_str(), "wb") == 0) { fwrite(m_plut, sizeof(unsigned char), 65536 * m_nBandNum, pFile); //for (int i = 0; i < 65536; ++i) //{ // fprintf(pFile, "%d\n", m_plut[i]); //} } fclose(pFile); } else { //读取lut文件 FILE *pFile; if (fopen_s(&pFile, szFileName.c_str(), "rb") == 0) { fread(m_plut, sizeof(unsigned char), 65536 * m_nBandNum, pFile); } fclose(pFile); } } return true; } bool CGdalUser::IsImgReady() { return m_poDataset != nullptr; } bool CGdalUser::ReadImageGDAL(const char* pFilePath, unsigned char **pImageData, GDALDataType nDataType, int& widthDst, int& heightDst, int& nBandNum) { if (pFilePath == nullptr || pImageData == nullptr) { return false; } if (nDataType == GDT_Unknown) { nDataType = GDT_Byte; } int nBPB = GetBPB(nDataType); GDALAllRegister(); int width = 0, height = 0; GDALDataset *poDataset = NULL; poDataset = (GDALDataset*)GDALOpen(pFilePath, GA_ReadOnly); if (poDataset == NULL) { GDALClose(poDataset); return false; } width = poDataset->GetRasterXSize(); height = poDataset->GetRasterYSize(); if (widthDst <= 0 && heightDst <= 0) { widthDst = width; heightDst = height; } GDALRasterBand* pBand; int i = 0; nBandNum = poDataset->GetRasterCount(); unsigned char **img = new unsigned char*[nBandNum]; for (i = 0; i < nBandNum; i++) { img[i] = new unsigned char[widthDst * heightDst * nBPB]; } for (i = 1; i <= nBandNum; ++i) { //默认读取顺序 pBand = poDataset->GetRasterBand(i); pBand->RasterIO(GF_Read, 0, 0, //nXOff,nYOff:从左上角坐标point(nXOff,nYOff)处读取图像数据 width, height, //nXSize,nXSize:要读取的图像数据尺寸,注意可以不是band的实际尺寸,这样就是读取roi区域数据 img[i - 1], //pData:读取的数据即将存储的目的地址。 widthDst, heightDst, //nBufXSize,nBufYSize:目的地址处图像的尺寸,如果与roi尺寸不一致,则缩放。 nDataType, //eBufType:读取图像后,将要存储为的类型 0, //nPixelSpace:控制同一行相邻像素间隔,0代表使用目的数据类型大小 0); //nLineSpace:控制相邻行的行间隔,0代表使用[目的数据类型大小 * nXsize] } GDALClose(poDataset); //将多个通道组合成单个输出通道 *pImageData = new unsigned char[widthDst*heightDst* nBandNum * nBPB]; for (int k = 0; k < nBandNum; ++k) { unsigned char* pBandData = img[k]; for (int j = 0; j < heightDst; ++j) { unsigned char* pRowReadData = pBandData + j * widthDst * nBPB; unsigned char* pRowWriteData = *pImageData + j * widthDst * nBandNum * nBPB; for (int i = 0; i < widthDst; ++i) { unsigned char* pColReadData = pRowReadData + i * nBPB; unsigned char* pColWriteData = pRowWriteData + i * nBandNum * nBPB; //赋值读取 memcpy(pColWriteData + k * nBPB, pColReadData, nBPB); } } } for (i = 0; i < nBandNum; ++i) { delete[] img[i]; img[i] = nullptr; } delete[]img; img = nullptr; return true; } bool CGdalUser::WriteImageGDAL(const char* pDstImgFileName, unsigned char *pImageData, GDALDataType nDataType, int width, int height, int nChannels) { if ((pDstImgFileName == NULL || pImageData == NULL || width <1 || height < 1 || nChannels < 1)) { return false; } GDALAllRegister(); char *GType = NULL; GType = findImageTypeGDAL((char*)pDstImgFileName); if (GType == NULL) { return false; } GDALDriver *pMemDriver = NULL; pMemDriver = GetGDALDriverManager()->GetDriverByName("MEM"); if (pMemDriver == NULL) { return false; } if (nDataType == GDT_Unknown) { nDataType = GDT_Byte; } int nBPB = GetBPB(nDataType); GDALDataset* pMemDataSet = pMemDriver->Create("", width, height, nChannels, nDataType, NULL); GDALRasterBand *pBand = NULL; int nLineCount = width * nChannels * nBPB; unsigned char *ptr1 = (unsigned char *)pImageData; for (int i = 1; i <= nChannels; i++) { //按顺序存入,如果是BGR需要在外部进行波段转换 pBand = pMemDataSet->GetRasterBand(i); pBand->RasterIO(GF_Write, 0, 0, width, height, ptr1 + (i - 1) * nBPB, width, height, nDataType, nChannels * nBPB, nLineCount); } GDALDriver *pDstDriver = NULL; pDstDriver = (GDALDriver *)GDALGetDriverByName(GType); if (pDstDriver == NULL) { return false; } GDALDataset* Dstds = pDstDriver->CreateCopy(pDstImgFileName, pMemDataSet, FALSE, NULL, NULL, NULL); GDALClose(pMemDataSet); GDALClose(Dstds); return Dstds != nullptr; } bool CGdalUser::ReadImage(int nStartCol, int nStartRow, int nWidth, int nHeight, unsigned char* pData, int nBufferWidth, int nBufferHeight) { //-1代表读取所有通道 int nSrcSkip = m_nBandNum == 1 ? 0 : -1; return ReadImg(nStartCol, nStartRow, nStartCol + nWidth, nStartRow + nHeight, pData, nBufferWidth, nBufferHeight, m_nBandNum, 0, 0, nBufferWidth, nBufferHeight, nSrcSkip, 0) == 0; } bool CGdalUser::WriteImage(int nStartCol, int nStartRow, int nWidth, int nHeight, unsigned char* pData, int nBufferWidth, int nBufferHeight) { //-1代表写入所有通道 int nSrcSkip = m_nBandNum == 1 ? 0 : -1; return WriteImg(nStartCol, nStartRow, nStartCol + nWidth, nStartRow + nHeight, pData, nBufferWidth, nBufferHeight, m_nBandNum, 0, 0, nBufferWidth, nBufferHeight, nSrcSkip, 0) == 0; } int CGdalUser::ReadImg(int nSrcLeft, int nSrcTop, int nSrcRight, int nSrcBottom, unsigned char* pBuf, int nBufWid, int nBufHeight, int nBandNum, int nDestLeft, int nDestTop, int nDestRight, int nDestBottom, int nSrcSkip, int nDestSkip) { int m_nWidth = m_nImgWidth; int m_nHeight = m_nImgHeight; double lfScale = (nDestRight - nDestLeft) / (double)(nSrcRight - nSrcLeft); if (nSrcLeft >= m_nWidth || nSrcTop >= m_nHeight || nSrcRight <= 0 || nSrcBottom <= 0) { return 1; } int nStartRowOffset = 0, nStartColOffset = 0, nEndRowOffset = 0, nEndColOffset = 0; if (nSrcLeft < 0) { nStartColOffset = -nSrcLeft; } if (nSrcTop < 0) { nStartRowOffset = -nSrcTop; } if (nSrcRight > m_nWidth) { nEndColOffset = m_nWidth - nSrcRight; } if (nSrcBottom > m_nHeight) { nEndRowOffset = m_nHeight - nSrcBottom; } nSrcLeft += nStartColOffset; nSrcRight += nEndColOffset; nSrcTop += nStartRowOffset; nSrcBottom += nEndRowOffset; nDestLeft += int(nStartColOffset*lfScale); nDestRight += int(nEndColOffset*lfScale); nDestTop += int(nStartRowOffset*lfScale); nDestBottom += int(nEndRowOffset*lfScale); if (nSrcSkip == -1) { if (nBandNum != m_nBandNum) { return 1; } int *bandmap = new int[nBandNum]; for (int i = 0; i < nBandNum; ++i) { bandmap[i] = i + 1; } if (!m_bTranto8bit) { CPLErr er = m_poDataset->RasterIO(GF_Read, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, pBuf + (nDestBottom - 1) * nBufWid * m_nBPP + nDestLeft * m_nBPP, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, nBandNum, bandmap, m_nBPP, -m_nBPP * nBufWid, m_nBPB); if (CE_Failure == er) { return 1; } } else { unsigned char *temBuf = new unsigned char[m_nOldBytesPerBand * m_nBandNum*nBufHeight * nBufWid]; memset(temBuf, 0, m_nOldBytesPerBand * m_nBandNum * nBufHeight * nBufWid); CPLErr er = m_poDataset->RasterIO(GF_Read, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, temBuf + (nDestBottom - 1) * nBufWid * m_nOldBytesPerBand*nBandNum + nDestLeft * m_nOldBytesPerBand*nBandNum, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, nBandNum, bandmap, m_nOldBytesPerBand*nBandNum, -m_nOldBytesPerBand*nBandNum * nBufWid, m_nOldBytesPerBand); if (CE_Failure == er) { return 1; } switch (m_nDataType) { case GDT_UInt16: { unsigned short* pp = (unsigned short*)temBuf; for (int j = nDestTop; j < nDestBottom; ++j) { int nRowOffset = j * nBufWid * nBandNum; unsigned char *pBufferIndex = pBuf + nRowOffset; unsigned short *ppIndex = pp + nRowOffset; for (int i = nDestLeft; i < nDestRight; ++i) { int nColOffset = i * nBandNum; unsigned char *pSubBufferIndex = pBufferIndex + nColOffset; unsigned short *ppSubIndex = ppIndex + nColOffset; int bBackGround = TRUE; for (int nb = 0; nb < nBandNum; ++nb) { if (ppSubIndex[nb] != 0) { bBackGround = FALSE; break; } } if (bBackGround == TRUE) { memset(pSubBufferIndex, 0, nBandNum); } else { for (int nb = 0; nb < nBandNum; ++nb) { pSubBufferIndex[nb] = m_plut[nb * 65536 + ppSubIndex[nb]]; } } } } break; } case GDT_Int16: { short* pp = (short*)temBuf; for (int j = nDestTop; j < nDestBottom; ++j) { for (int i = nDestLeft; i < nDestRight; ++i) { for (int nb = 0; nb < m_nBandNum; ++nb) { pBuf[j*nBufWid*nBandNum + i*nBandNum + nb] = m_plut[nb * 65536 + pp[j*nBufWid*nBandNum + i*nBandNum + nb]]; } } } break; } } delete[]temBuf; temBuf = NULL; } delete[] bandmap; bandmap = NULL; } else { if (nDestSkip > nBandNum - 1) { return 1; } if (!m_bTranto8bit) { CPLErr er = m_poDataset->GetRasterBand(nSrcSkip + 1)->RasterIO(GF_Read, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, pBuf + (nDestBottom - 1) * nBufWid * nBandNum* m_nBPB + nDestLeft * nBandNum * m_nBPB + nDestSkip * m_nBPB, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, nBandNum * m_nBPB, -nBandNum * m_nBPB * nBufWid); if (CE_Failure == er) { return 1; } } else { unsigned char *temBuf = new unsigned char[m_nOldBytesPerBand*nBufHeight*nBufWid]; CPLErr er = m_poDataset->GetRasterBand(nSrcSkip + 1)->RasterIO(GF_Read, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, temBuf + (nDestBottom - 1) * nBufWid * m_nOldBytesPerBand + nDestLeft * m_nOldBytesPerBand, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, m_nOldBytesPerBand, -m_nOldBytesPerBand * nBufWid); if (CE_Failure == er) { return 1; } switch (m_nDataType) { case GDT_UInt16: { unsigned short* pp = (unsigned short*)temBuf; for (int j = nDestTop; j < nDestBottom; ++j) { for (int i = nDestLeft; i < nDestRight; ++i) { pBuf[j*nBufWid*nBandNum + i*nBandNum + nDestSkip] = m_plut[nSrcSkip * 65536 + pp[j*nBufWid + i]]; } } break; } case GDT_Int16: { short* pp = (short*)temBuf; for (int j = nDestTop; j < nDestBottom; ++j) { for (int i = nDestLeft; i < nDestRight; ++i) { pBuf[j*nBufWid*nBandNum + i*nBandNum + nDestSkip] = m_plut[nSrcSkip * 65536 + pp[j*nBufWid + i]]; } } break; } } delete[]temBuf; temBuf = NULL; } } return 0; } int CGdalUser::WriteImg(int nSrcLeft, int nSrcTop, int nSrcRight, int nSrcBottom, unsigned char* pBuf, int nBufWid, int nBufHeight, int nBandNum, int nDestLeft, int nDestTop, int nDestRight, int nDestBottom, int nSrcSkip, int nDestSkip) { int m_nWidth = m_nImgWidth; int m_nHeight = m_nImgHeight; double lfScale = (nDestRight - nDestLeft) / (double)(nSrcRight - nSrcLeft); if (nSrcLeft >= m_nWidth || nSrcTop >= m_nHeight || nSrcRight <= 0 || nSrcBottom <= 0) { return 1; } int nStartRowOffset = 0, nStartColOffset = 0, nEndRowOffset = 0, nEndColOffset = 0; if (nSrcLeft < 0) { nStartColOffset = -nSrcLeft; } if (nSrcTop < 0) { nStartRowOffset = -nSrcTop; } if (nSrcRight > m_nWidth) { nEndColOffset = m_nWidth - nSrcRight; } if (nSrcBottom > m_nHeight) { nEndRowOffset = m_nHeight - nSrcBottom; } nSrcLeft += nStartColOffset; nSrcRight += nEndColOffset; nSrcTop += nStartRowOffset; nSrcBottom += nEndRowOffset; nDestLeft += int(nStartColOffset*lfScale); nDestRight += int(nEndColOffset*lfScale); nDestTop += int(nStartRowOffset*lfScale); nDestBottom += int(nEndRowOffset*lfScale); if (nSrcSkip == -1) { if (nBandNum != m_nBandNum) { return 1; } int *bandmap = new int[nBandNum]; for (int i = 0; i < nBandNum; ++i) { bandmap[i] = i + 1; } CPLErr er = m_poDataset->RasterIO(GF_Write, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, pBuf + (nDestBottom - 1) * nBufWid * m_nBPP + nDestLeft * m_nBPP, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, nBandNum, bandmap, m_nBPP, -m_nBPP * nBufWid, m_nBPB); if (CE_Failure == er) { return 1; } delete[] bandmap; bandmap = NULL; } else { if (nDestSkip > nBandNum - 1) { return 1; } CPLErr er = m_poDataset->GetRasterBand(nSrcSkip + 1)->RasterIO(GF_Write, nSrcLeft, m_nHeight - nSrcBottom, nSrcRight - nSrcLeft, nSrcBottom - nSrcTop, pBuf + (nDestBottom - 1) * nBufWid * nBandNum* m_nBPB + nDestLeft * nBandNum * m_nBPB + nDestSkip * m_nBPB, nDestRight - nDestLeft, nDestBottom - nDestTop, m_nDataType, nBandNum * m_nBPB, -nBandNum * m_nBPB * nBufWid); if (CE_Failure == er) { return 1; } } return 0; } char* CGdalUser::findImageTypeGDAL(char *pDstImgFileName) { char* cf = strrchr(pDstImgFileName, '.'); if (cf == nullptr) { return nullptr; } char *dstExtension = strlwr( cf + 1); char *Gtype = NULL; if (0 == strcmp(dstExtension, "bmp")) Gtype = "BMP"; else if (0 == strcmp(dstExtension, "jpg") || 0 == strcmp(dstExtension, "jpeg")) Gtype = "JPEG"; else if (0 == strcmp(dstExtension, "png")) Gtype = "PNG"; else if (0 == strcmp(dstExtension, "tif")) Gtype = "GTiff"; else if (0 == strcmp(dstExtension, "gif")) Gtype = "GIF"; //以下是不常用的格式 else if (0 == strcmp(dstExtension, "img")) Gtype = "HFA"; else if (0 == strcmp(dstExtension, "bt")) Gtype = "BT"; else if (0 == strcmp(dstExtension, "ecw")) Gtype = "ECW"; else if (0 == strcmp(dstExtension, "fits")) Gtype = "FITS"; else if (0 == strcmp(dstExtension, "hdf")) Gtype = "HDF4"; else if (0 == strcmp(dstExtension, "hdr")) Gtype = "EHdr"; else Gtype = nullptr; return Gtype; } int CGdalUser::GetBPB(const GDALDataType& nDataType) { int nBPB = 0; switch (nDataType) { case 1: { //nDataType = GDT_Byte; nBPB = 1; break; } case 2: { //nDataType = GDT_UInt16; nBPB = 2; break; } case 3: { //nDataType = GDT_Int16; nBPB = 2; break; } case 4: { //nDataType = GDT_UInt32; nBPB = 4; break; } case 5: { //nDataType = GDT_Int32; nBPB = 4; break; } case 6: { //nDataType = GDT_Float32; nBPB = 4; break; } case 7: { //nDataType = GDT_Float64; nBPB = 8; break; } default: return nBPB; } return nBPB; } int CGdalUser::ReseqChannels(unsigned char* pData, const int& nRows, const int& nCols, const int& nBandNum, const int& nBPB, int arrNewSeq[]) { if (pData == nullptr || nRows <= 0 || nCols <= 0 || nBandNum <= 0 || nBPB <= 0) { return -1; } unsigned char* pTmp = nullptr; const int& nBufferSize = nBandNum * nBPB; pTmp = new unsigned char[nBufferSize]; //memset(pTmp, 0, nBufferSize); for (int j = 0; j < nRows; ++j) { unsigned char* pRowData = pData + j * nCols * nBandNum * nBPB; for (int i = 0; i < nCols; ++i) { unsigned char* pColData = pRowData + i * nBandNum * nBPB; for (int k = 0; k < nBandNum; ++k) { memcpy(pTmp + k * nBPB, pColData + arrNewSeq[k] * nBPB, nBPB); } for (int k = 0; k < nBandNum; ++k) { memcpy(pColData + k * nBPB, pTmp + k * nBPB, nBPB); } } } if (pTmp) { delete[] pTmp; pTmp = nullptr; } return 0; } int CGdalUser::VerticalReverse(unsigned char* pData, const int& nRows, const int& nCols, const int& nBandNum, const int& nBPB) { if (pData == nullptr || nRows <= 0 || nCols <= 0 || nBandNum <= 0 || nBPB <= 0) { return -1; } unsigned char* pTmp = nullptr; const int& nBufferSize = nRows * nCols * nBandNum * nBPB; pTmp = new unsigned char[nBufferSize]; //memset(pTmp, 0, nBufferSize); memcpy(pTmp, pData, nBufferSize); for (int j = 0; j < nRows; ++j) { unsigned char* pRowReadData = pTmp + (nRows - 1 - j) * nCols * nBandNum * nBPB; unsigned char* pRowWriteData = pData + j * nCols * nBandNum * nBPB; for (int i = 0; i < nCols; ++i) { unsigned char* pColReadData = pRowReadData + i * nBandNum * nBPB; unsigned char* pColWriteData = pRowWriteData + i * nBandNum * nBPB; for (int k = 0; k < nBandNum; ++k) { memcpy(pColWriteData + k * nBPB, pColReadData + k * nBPB, nBPB); } } } if (pTmp) { delete[] pTmp; pTmp = nullptr; } return 0; }