#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;
}