Changeset 11617

Show
Ignore:
Timestamp:
06/07/07 14:05:35 (1 year ago)
Author:
warmerdam
Message:

add support for multi-tile grids (#1198)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.4/gdal/frmts/aigrid/GNUmakefile

    r9480 r11617  
    1010 
    1111clean: 
    12         rm -f *.o aitest $(OBJ) 
     12        rm -f *.o aitest $(OBJ) $(O_OBJ) 
    1313 
    1414aitest: aitest.o $(AIGOBJ) 
  • branches/1.4/gdal/frmts/aigrid/aigopen.c

    r10646 r11617  
    4040{ 
    4141    AIGInfo_t   *psInfo; 
    42     char        *pszHDRFilename; 
    4342    char        *pszCoverName; 
    4443 
     
    8685 
    8786/* -------------------------------------------------------------------- */ 
    88 /*      Open the file w001001.adf file itself.                          */ 
    89 /* -------------------------------------------------------------------- */ 
    90     pszHDRFilename = (char *) CPLMalloc(strlen(pszCoverName)+40); 
    91     sprintf( pszHDRFilename, "%s/w001001.adf", pszCoverName ); 
    92  
    93     psInfo->fpGrid = AIGLLOpen( pszHDRFilename, "rb" ); 
    94      
    95     if( psInfo->fpGrid == NULL ) 
    96     { 
    97         CPLError( CE_Failure, CPLE_OpenFailed, 
    98                   "Failed to open grid file:\n%s\n", 
    99                   pszHDRFilename ); 
    100  
    101         CPLFree( psInfo ); 
    102         CPLFree( pszHDRFilename ); 
    103         CPLFree( pszCoverName ); 
    104         return( NULL ); 
    105     } 
    106  
    107     CPLFree( pszHDRFilename ); 
    108     pszHDRFilename = NULL; 
    109      
    110 /* -------------------------------------------------------------------- */ 
    111 /*      Read the block index file.                                      */ 
    112 /* -------------------------------------------------------------------- */ 
    113     if( AIGReadBlockIndex( pszCoverName, psInfo ) != CE_None ) 
    114     { 
    115         VSIFCloseL( psInfo->fpGrid ); 
    116          
    117         CPLFree( psInfo ); 
     87/*      Read the extents.                                               */ 
     88/* -------------------------------------------------------------------- */ 
     89    if( AIGReadBounds( pszCoverName, psInfo ) != CE_None ) 
     90    { 
     91        AIGClose( psInfo ); 
    11892        return NULL; 
    11993    } 
    12094 
    12195/* -------------------------------------------------------------------- */ 
    122 /*      Read the extents.                                               */ 
    123 /* -------------------------------------------------------------------- */ 
    124     if( AIGReadBounds( pszCoverName, psInfo ) != CE_None ) 
    125     { 
    126         VSIFCloseL( psInfo->fpGrid ); 
    127          
    128         CPLFree( psInfo ); 
    129         return NULL; 
    130     } 
    131  
    132 /* -------------------------------------------------------------------- */ 
    133 /*      Read the statistics.                                            */ 
    134 /* -------------------------------------------------------------------- */ 
    135     if( AIGReadStatistics( pszCoverName, psInfo ) != CE_None ) 
    136     { 
    137         VSIFCloseL( psInfo->fpGrid ); 
    138          
    139         CPLFree( psInfo ); 
    140         return NULL; 
    141     } 
    142  
    143 /* -------------------------------------------------------------------- */ 
    144 /*      Compute the number of pixels and lines.                         */ 
     96/*      Compute the number of pixels and lines, and the number of       */ 
     97/*      tile files.                                                     */ 
    14598/* -------------------------------------------------------------------- */ 
    14699    psInfo->nPixels = (int) 
     
    150103        ((psInfo->dfURY - psInfo->dfLLY + 0.5 * psInfo->dfCellSizeY)  
    151104                / psInfo->dfCellSizeY); 
     105 
     106    psInfo->nTileXSize = psInfo->nBlockXSize * psInfo->nBlocksPerRow; 
     107    psInfo->nTileYSize = psInfo->nBlockYSize * psInfo->nBlocksPerColumn; 
     108 
     109    psInfo->nTilesPerRow = (psInfo->nPixels-1) / psInfo->nTileXSize + 1; 
     110    psInfo->nTilesPerColumn = (psInfo->nLines-1) / psInfo->nTileYSize + 1; 
     111 
     112/* -------------------------------------------------------------------- */ 
     113/*      Setup tile infos, but defer reading of tile data.               */ 
     114/* -------------------------------------------------------------------- */ 
     115    psInfo->pasTileInfo = (AIGTileInfo *)  
     116        CPLCalloc(sizeof(AIGTileInfo), 
     117                  psInfo->nTilesPerRow * psInfo->nTilesPerColumn); 
     118/* -------------------------------------------------------------------- */ 
     119/*      Read the statistics.                                            */ 
     120/* -------------------------------------------------------------------- */ 
     121    if( AIGReadStatistics( pszCoverName, psInfo ) != CE_None ) 
     122    { 
     123        AIGClose( psInfo ); 
     124        return NULL; 
     125    } 
     126 
     127    return( psInfo ); 
     128} 
     129 
     130/************************************************************************/ 
     131/*                           AIGAccessTile()                            */ 
     132/************************************************************************/ 
     133 
     134CPLErr AIGAccessTile( AIGInfo_t *psInfo, int iTileX, int iTileY ) 
     135 
     136{ 
     137    char szBasename[20]; 
     138    char *pszFilename; 
     139    AIGTileInfo *psTInfo; 
     140 
     141/* -------------------------------------------------------------------- */ 
     142/*      Identify our tile.                                              */ 
     143/* -------------------------------------------------------------------- */ 
     144    if( iTileX < 0 || iTileX >= psInfo->nTilesPerRow 
     145        || iTileY < 0 || iTileY >= psInfo->nTilesPerColumn ) 
     146    { 
     147        CPLAssert( FALSE ); 
     148        return CE_Failure; 
     149    } 
     150 
     151    psTInfo = psInfo->pasTileInfo + iTileX + iTileY * psInfo->nTilesPerRow; 
     152 
     153    if( psTInfo->fpGrid != NULL ) 
     154        return CE_None; 
     155 
     156/* -------------------------------------------------------------------- */ 
     157/*      Compute the basename.                                           */ 
     158/* -------------------------------------------------------------------- */ 
     159    if( iTileY == 0 ) 
     160        sprintf( szBasename, "w%03d001", iTileX + 1 ); 
     161    else if( iTileY == 1 ) 
     162        sprintf( szBasename, "w%03d000", iTileX + 1 ); 
     163    else 
     164        sprintf( szBasename, "z%03d%03d", iTileX + 1, iTileY - 1 ); 
    152165     
    153     return( psInfo ); 
     166/* -------------------------------------------------------------------- */ 
     167/*      Open the file w001001.adf file itself.                          */ 
     168/* -------------------------------------------------------------------- */ 
     169    pszFilename = (char *) CPLMalloc(strlen(psInfo->pszCoverName)+40); 
     170    sprintf( pszFilename, "%s/%s.adf", psInfo->pszCoverName, szBasename ); 
     171 
     172    psTInfo->fpGrid = AIGLLOpen( pszFilename, "rb" ); 
     173     
     174    if( psTInfo->fpGrid == NULL ) 
     175    { 
     176        CPLError( CE_Failure, CPLE_OpenFailed, 
     177                  "Failed to open grid file:\n%s\n", 
     178                  pszFilename ); 
     179        return CE_Failure; 
     180    } 
     181 
     182    CPLFree( pszFilename ); 
     183    pszFilename = NULL; 
     184     
     185/* -------------------------------------------------------------------- */ 
     186/*      Read the block index file.                                      */ 
     187/* -------------------------------------------------------------------- */ 
     188    return AIGReadBlockIndex( psInfo, psTInfo, szBasename ); 
    154189} 
    155190 
     
    164199    int         nBlockID; 
    165200    CPLErr      eErr; 
     201    int         iTileX, iTileY; 
     202    AIGTileInfo *psTInfo; 
     203 
     204/* -------------------------------------------------------------------- */ 
     205/*      Compute our tile, and ensure it is accessable (open).  Then     */ 
     206/*      reduce block x/y values to be the block within that tile.       */ 
     207/* -------------------------------------------------------------------- */ 
     208    iTileX = nBlockXOff / psInfo->nBlocksPerRow; 
     209    iTileY = nBlockYOff / psInfo->nBlocksPerColumn; 
     210 
     211    eErr = AIGAccessTile( psInfo, iTileX, iTileY ); 
     212    if( eErr != CE_None ) 
     213        return eErr; 
     214 
     215    psTInfo = psInfo->pasTileInfo + iTileX + iTileY * psInfo->nTilesPerRow; 
     216 
     217    nBlockXOff -= iTileX * psInfo->nBlocksPerRow; 
     218    nBlockYOff -= iTileY * psInfo->nBlocksPerColumn; 
    166219 
    167220/* -------------------------------------------------------------------- */ 
     
    177230    } 
    178231 
    179     if( nBlockID >= psInfo->nBlocks ) 
     232    if( nBlockID >= psTInfo->nBlocks ) 
    180233    { 
    181234        int i; 
     
    191244/*      Read block.                                                     */ 
    192245/* -------------------------------------------------------------------- */ 
    193     eErr = AIGReadBlock( psInfo->fpGrid, 
    194                          psInfo->panBlockOffset[nBlockID], 
    195                          psInfo->panBlockSize[nBlockID], 
     246    eErr = AIGReadBlock( psTInfo->fpGrid, 
     247                         psTInfo->panBlockOffset[nBlockID], 
     248                         psTInfo->panBlockSize[nBlockID], 
    196249                         psInfo->nBlockXSize, psInfo->nBlockYSize, 
    197250                         panData, psInfo->nCellType ); 
     
    224277    int         nBlockID; 
    225278    CPLErr      eErr; 
     279    int         iTileX, iTileY; 
     280    AIGTileInfo *psTInfo; 
     281 
     282/* -------------------------------------------------------------------- */ 
     283/*      Compute our tile, and ensure it is accessable (open).  Then     */ 
     284/*      reduce block x/y values to be the block within that tile.       */ 
     285/* -------------------------------------------------------------------- */ 
     286    iTileX = nBlockXOff / psInfo->nBlocksPerRow; 
     287    iTileY = nBlockYOff / psInfo->nBlocksPerColumn; 
     288 
     289    eErr = AIGAccessTile( psInfo, iTileX, iTileY ); 
     290    if( eErr != CE_None ) 
     291        return eErr; 
     292 
     293    psTInfo = psInfo->pasTileInfo + iTileX + iTileY * psInfo->nTilesPerRow; 
     294 
     295    nBlockXOff -= iTileX * psInfo->nBlocksPerRow; 
     296    nBlockYOff -= iTileY * psInfo->nBlocksPerColumn; 
    226297 
    227298/* -------------------------------------------------------------------- */ 
     
    237308    } 
    238309 
    239     if( nBlockID >= psInfo->nBlocks ) 
     310    if( nBlockID >= psTInfo->nBlocks ) 
    240311    { 
    241312        int i; 
     
    251322/*      Read block.                                                     */ 
    252323/* -------------------------------------------------------------------- */ 
    253     eErr = AIGReadBlock( psInfo->fpGrid, 
    254                          psInfo->panBlockOffset[nBlockID], 
    255                          psInfo->panBlockSize[nBlockID], 
     324    eErr = AIGReadBlock( psTInfo->fpGrid, 
     325                         psTInfo->panBlockOffset[nBlockID], 
     326                         psTInfo->panBlockSize[nBlockID], 
    256327                         psInfo->nBlockXSize, psInfo->nBlockYSize, 
    257328                         (GInt32 *) pafData, psInfo->nCellType ); 
     
    281352 
    282353{ 
    283     VSIFCloseL( psInfo->fpGrid ); 
    284  
    285     CPLFree( psInfo->panBlockOffset ); 
    286     CPLFree( psInfo->panBlockSize ); 
     354    int nTileCount = psInfo->nTilesPerRow * psInfo->nTilesPerColumn; 
     355    int iTile; 
     356 
     357    for( iTile = 0; iTile < nTileCount; iTile++ ) 
     358    { 
     359        if( psInfo->pasTileInfo[iTile].fpGrid ) 
     360        { 
     361            VSIFCloseL( psInfo->pasTileInfo[iTile].fpGrid ); 
     362 
     363            CPLFree( psInfo->pasTileInfo[iTile].panBlockOffset ); 
     364            CPLFree( psInfo->pasTileInfo[iTile].panBlockSize ); 
     365        } 
     366    } 
     367 
     368    CPLFree( psInfo->pasTileInfo ); 
    287369    CPLFree( psInfo->pszCoverName ); 
    288370    CPLFree( psInfo ); 
  • branches/1.4/gdal/frmts/aigrid/aigrid.h

    r10646 r11617  
    4242/*      Grid Instance                                                   */ 
    4343/* ==================================================================== */ 
     44 
    4445typedef struct { 
    45     /* Private information */ 
    46      
    4746    int         nBlocks; 
    4847    GUInt32     *panBlockOffset; 
     
    5049 
    5150    FILE        *fpGrid;        /* the w001001.adf file */ 
     51} AIGTileInfo; 
    5252 
     53typedef struct { 
     54    /* Private information */ 
     55     
     56    AIGTileInfo *pasTileInfo; 
     57     
    5358    int         bHasWarned; 
    5459 
     
    6772    int         nBlocksPerRow; 
    6873    int         nBlocksPerColumn; 
     74 
     75    int         nTileXSize; 
     76    int         nTileYSize; 
     77 
     78    int         nTilesPerRow; 
     79    int         nTilesPerColumn; 
    6980 
    7081    double      dfLLX; 
     
    90101/* ==================================================================== */ 
    91102 
     103CPLErr AIGAccessTile( AIGInfo_t *psInfo, int iTileX, int iTileY ); 
    92104CPLErr AIGReadBlock( FILE * fp, GUInt32 nBlockOffset, int nBlockSize, 
    93105                     int nBlockXSize, int nBlockYSize, GInt32 * panData, 
     
    95107 
    96108CPLErr AIGReadHeader( const char *, AIGInfo_t * ); 
    97 CPLErr AIGReadBlockIndex( const char *, AIGInfo_t * ); 
     109CPLErr AIGReadBlockIndex( AIGInfo_t *, AIGTileInfo *,  
     110                          const char *pszBasename ); 
    98111CPLErr AIGReadBounds( const char *, AIGInfo_t * ); 
    99112CPLErr AIGReadStatistics( const char *, AIGInfo_t * ); 
  • branches/1.4/gdal/frmts/aigrid/aitest.c

    r10475 r11617  
    4242{ 
    4343    int         i; 
    44  
    45     for( i = 0; i < psInfo->nBlocks; i++ ) 
     44    AIGTileInfo *psTInfo = psInfo->pasTileInfo + 0; 
     45 
     46    for( i = 0; i < psTInfo->nBlocks; i++ ) 
    4647    { 
    4748        GByte   byMagic; 
     
    5051        const char *pszMessage = ""; 
    5152         
    52         if( psInfo->panBlockSize[i] == 0 ) 
     53        if( psTInfo->panBlockSize[i] == 0 ) 
    5354            continue; 
    5455 
    55         VSIFSeekL( psInfo->fpGrid, psInfo->panBlockOffset[i], SEEK_SET ); 
    56         VSIFReadL( abyBlockSize, 2, 1, psInfo->fpGrid ); 
     56        VSIFSeekL( psTInfo->fpGrid, psTInfo->panBlockOffset[i], SEEK_SET ); 
     57        VSIFReadL( abyBlockSize, 2, 1, psTInfo->fpGrid ); 
    5758 
    5859        if( psInfo->nCellType == AIG_CELLTYPE_INT ) 
    5960        { 
    60             VSIFReadL( &byMagic, 1, 1, psInfo->fpGrid ); 
     61            VSIFReadL( &byMagic, 1, 1, psTInfo->fpGrid ); 
    6162 
    6263            if( byMagic != 0 && byMagic != 0x43 && byMagic != 0x04 
     
    7172            } 
    7273 
    73             if( byMagic == 0 && psInfo->panBlockSize[i] > 8 ) 
     74            if( byMagic == 0 && psTInfo->panBlockSize[i] > 8 ) 
    7475            { 
    7576                pszMessage = "(wrong size for 0x00 block, should be 8 bytes)"; 
     
    7879 
    7980            if( (abyBlockSize[0] * 256 + abyBlockSize[1])*2 !=  
    80                 psInfo->panBlockSize[i] ) 
     81                psTInfo->panBlockSize[i] ) 
    8182            { 
    8283                pszMessage = "(block size in data doesn't match index)"; 
     
    8687        else 
    8788        { 
    88             if( psInfo->panBlockSize[i] != 
     89            if( psTInfo->panBlockSize[i] != 
    8990                psInfo->nBlockXSize*psInfo->nBlockYSize*sizeof(float) ) 
    9091            { 
     
    9798        { 
    9899            printf( " %02x %5d %5d @ %d %s\n", byMagic, i, 
    99                     psInfo->panBlockSize[i], 
    100                     psInfo->panBlockOffset[i], 
     100                    psTInfo->panBlockSize[i], 
     101                    psTInfo->panBlockOffset[i], 
    101102                    pszMessage ); 
    102103        } 
     
    143144    if( psInfo == NULL ) 
    144145        exit( 1 ); 
     146 
     147    AIGAccessTile( psInfo, 0, 0 ); 
    145148 
    146149/* -------------------------------------------------------------------- */ 
     
    184187        int     nBlock = atoi(argv[2]); 
    185188        CPLErr  eErr; 
     189        AIGTileInfo *psTInfo = psInfo->pasTileInfo + 0; 
    186190 
    187191        argv++; 
    188192        argc--; 
    189193         
    190         eErr = AIGReadBlock( psInfo->fpGrid, 
    191                              psInfo->panBlockOffset[nBlock], 
    192                              psInfo->panBlockSize[nBlock], 
     194        eErr = AIGReadBlock( psTInfo->fpGrid, 
     195                             psTInfo->panBlockOffset[nBlock], 
     196                             psTInfo->panBlockSize[nBlock], 
    193197                             psInfo->nBlockXSize, psInfo->nBlockYSize, 
    194198                             panRaster, psInfo->nCellType ); 
  • branches/1.4/gdal/frmts/aigrid/gridlib.c

    r10646 r11617  
    447447            if( nMarker + nPixels > nTotPixels ) 
    448448            { 
     449#ifdef notdef 
    449450                CPLError( CE_Failure, CPLE_AppDefined,  
    450451                          "Run too long in AIGProcessBlock, needed %d values, got %d.",  
    451452                          nTotPixels - nPixels, nMarker ); 
    452453                return CE_Failure; 
     454#endif 
     455                printf( "Too much data, limit data to use\n" ); 
     456                nPixels = nTotPixels - nMarker; 
    453457            } 
    454458         
     
    768772/************************************************************************/ 
    769773 
    770 CPLErr AIGReadBlockIndex( const char * pszCoverName, AIGInfo_t * psInfo ) 
     774CPLErr AIGReadBlockIndex( AIGInfo_t * psInfo, AIGTileInfo *psTInfo,  
     775                          const char *pszBasename ) 
    771776 
    772777{ 
     
    781786/*      Open the file hdr.adf file.                                     */ 
    782787/* -------------------------------------------------------------------- */ 
    783     pszHDRFilename = (char *) CPLMalloc(strlen(pszCoverName)+40); 
    784     sprintf( pszHDRFilename, "%s/w001001x.adf", pszCoverName ); 
     788    pszHDRFilename = (char *) CPLMalloc(strlen(psInfo->pszCoverName)+40); 
     789    sprintf( pszHDRFilename, "%s/%sx.adf", psInfo->pszCoverName, pszBasename ); 
    785790 
    786791    fp = AIGLLOpen( pszHDRFilename, "rb" ); 
     
    836841/*      into the buffer.                                                */ 
    837842/* -------------------------------------------------------------------- */ 
    838     psInfo->nBlocks = (nLength-100) / 8; 
    839     panIndex = (GUInt32 *) CPLMalloc(psInfo->nBlocks * 8); 
     843    psTInfo->nBlocks = (nLength-100) / 8; 
     844    panIndex = (GUInt32 *) CPLMalloc(psTInfo->nBlocks * 8); 
    840845    VSIFSeekL( fp, 100, SEEK_SET ); 
    841     VSIFReadL( panIndex, 8, psInfo->nBlocks, fp ); 
     846    VSIFReadL( panIndex, 8, psTInfo->nBlocks, fp ); 
    842847 
    843848    VSIFCloseL( fp ); 
     
    846851/*      Allocate AIGInfo block info arrays.                             */ 
    847852/* -------------------------------------------------------------------- */ 
    848     psInfo->panBlockOffset = (GUInt32 *) CPLMalloc(4 * psInfo->nBlocks); 
    849     psInfo->panBlockSize = (int *) CPLMalloc(4 * psInfo->nBlocks); 
     853    psTInfo->panBlockOffset = (GUInt32 *) CPLMalloc(4 * psTInfo->nBlocks); 
     854    psTInfo->panBlockSize = (int *) CPLMalloc(4 * psTInfo->nBlocks); 
    850855 
    851856/* -------------------------------------------------------------------- */ 
    852857/*      Populate the block information.                                 */ 
    853858/* -------------------------------------------------------------------- */ 
    854     for( i = 0; i < psInfo->nBlocks; i++ ) 
    855     { 
    856         psInfo->panBlockOffset[i] = CPL_MSBWORD32(panIndex[i*2]) * 2; 
    857         psInfo->panBlockSize[i] = CPL_MSBWORD32(panIndex[i*2+1]) * 2; 
     859    for( i = 0; i < psTInfo->nBlocks; i++ ) 
     860    { 
     861        psTInfo->panBlockOffset[i] = CPL_MSBWORD32(panIndex[i*2]) * 2; 
     862        psTInfo->panBlockSize[i] = CPL_MSBWORD32(panIndex[i*2+1]) * 2; 
    858863    } 
    859864