GDALブロック処理の簡単な流れ


GDALブロック処理フロー
GDALライブラリを使用して画像処理アルゴリズムを作成する場合、処理の効率を向上させるためにブロック処理を行うことがよくあります.以下のコードはGDALブロック処理を使用する簡単な例です.
画像ブロックコード
画像ブロックコードは、入出力画像経路のみで、元の画像に対して一定の処理を経て、結果を出力画像に書き込む.ここで、元の画像と結果の画像のサイズは完全に一致します.具体的な流れは以下のコードと中の注釈部分を参照してください.
#include "gdal_priv.h"

bool ImageProcess(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat)
{
    //  GDAL  
    GDALAllRegister();

    //        
    GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
    if (poDriver == NULL)   //        
        return false;

    //      
    GDALDataset *poSrcDS = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
    if (poSrcDS == NULL)    //        
        return false;

    //            
    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    int nBands = poSrcDS->GetRasterCount();

    //            
    double adfGeotransform[6] = { 0 };
    poSrcDS->GetGeoTransform(adfGeotransform);
    //          
    const char* pszProj = poSrcDS->GetProjectionRef();

    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    if (poBand == NULL)    //            
    {
        GDALClose((GDALDatasetH)poSrcDS);
        return false;
    }

    //      ,     1   
    GDALDataset *poDstDS = poDriver->Create(pszDstFile, nXSize, nYSize, 1, GDT_Byte, NULL);
    if (poDstDS == NULL)    //        
    {
        GDALClose((GDALDatasetH)poSrcDS);
        return false;
    }

    //            ,     
    poDstDS->SetGeoTransform(adfGeotransform);
    //          ,     
    poDstDS->SetProjection(pszProj);

    int nBlockSize = 256;     //    

    //        
    unsigned char *pSrcData = new unsigned char[nBlockSize*nBlockSize*nBands];
    //        
    unsigned char *pDstData = new unsigned char[nBlockSize*nBlockSize];

    //            
    int *pBandMaps = new int[nBands];
    for (int b = 0; b < nBands; b++)
        pBandMaps[b] = b + 1;

    //         
    for (int i = 0; i < nYSize; i += nBlockSize)
    {
        for (int j = 0; j < nXSize; j += nBlockSize)
        {
            //             
            int nXBK = nBlockSize;
            int nYBK = nBlockSize;

            //             256,        
            if (i + nBlockSize > nYSize)     //       
                nYBK = nYSize - i;
            if (j + nBlockSize > nXSize)     //       
                nXBK = nXSize - j;

            //       
            poSrcDS->RasterIO(GF_Read, j, i, nXBK, nYBK, pSrcData, nXBK, nYBK, GDT_Byte, nBands, pBandMaps, 0, 0, 0, NULL);

            //             
            //pSrcData           ,     ,    ,    
            //pDstData            ,         

            memcpy(pDstData, pSrcData, sizeof(unsigned char)*nXBK*nYBK);
            //         ,                       

            //      
            poDstDS->RasterIO(GF_Write, j, i, nXBK, nYBK, pDstData, nXBK, nYBK, GDT_Byte, 1, pBandMaps, 0, 0, 0, NULL);
        }
    }

    //       
    delete[]pSrcData;
    delete[]pDstData;
    delete[]pBandMaps;

    //           
    GDALClose((GDALDatasetH)poSrcDS);
    GDALClose((GDALDatasetH)poDstDS);

    return true;
}