Changeset 14792

Show
Ignore:
Timestamp:
06/30/08 17:04:49 (5 months ago)
Author:
rouault
Message:

Use new proxy API instead of RPFTOCGDALDatasetCache

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gdal/frmts/nitf/rpftocdataset.cpp

    r14557 r14792  
    2929 
    3030#include "gdal_pam.h" 
     31#include "gdal_proxy.h" 
    3132#include "rpftoclib.h" 
    3233#include "ogr_spatialref.h" 
     
    200201                                                  const RPFTocEntry* entry, int isRGBA); 
    201202}; 
    202          
    203 /************************************************************************/ 
    204 /* ==================================================================== */ 
    205 /*                            RPFTOCGDALDatasetCache                      */ 
    206 /* ==================================================================== */ 
    207 /************************************************************************/ 
    208  
    209 class RPFTOCGDALDatasetCache; 
    210 static RPFTOCGDALDatasetCache* singleton = NULL; 
    211 static int refCount = 0; 
    212 static void* RPFTOCCacheMutex = NULL; 
    213  
    214 typedef struct 
    215 { 
    216     const char* fileName; 
    217     GDALDataset* ds; 
    218 } CacheEntry; 
    219  
    220 /* This class is a singleton that maintains a pool of opened datasets */ 
    221 /* This is to handle efficiently a potential huge number of NITF tiles */ 
    222 /* inside a RPFTOC product */ 
    223 /* The cache uses a LRU strategy */ 
    224 class RPFTOCGDALDatasetCache 
    225 { 
    226     int size; 
    227     CacheEntry* entries; 
    228  
    229     RPFTOCGDALDatasetCache(int size) 
    230     { 
    231         this->size = size; 
    232         entries = (CacheEntry*)CPLMalloc(size * sizeof(CacheEntry)); 
    233         memset(entries, 0, size * sizeof(CacheEntry)); 
    234  
    235     } 
    236  
    237     ~RPFTOCGDALDatasetCache() 
    238     { 
    239         int i; 
    240         for(i=0;i<size;i++) 
    241         { 
    242             if (entries[i].ds) 
    243             { 
    244                 GDALClose(entries[i].ds); 
    245             } 
    246         } 
    247         CPLFree(entries); 
    248     } 
    249      
    250     GDALDataset* _GetDataset(const char* fileName) 
    251     { 
    252         int i; 
    253         for(i=0;i<size;i++) 
    254         { 
    255             if (entries[i].fileName == NULL) 
    256             { 
    257                 if (i != 0) 
    258                     memmove(&entries[1], &entries[0], sizeof(CacheEntry) * i); 
    259                 entries[0].fileName = fileName; 
    260                 entries[0].ds = (GDALDataset *) GDALOpenShared( fileName, GA_ReadOnly ); 
    261                 return entries[0].ds; 
    262             } 
    263             /* Optimization here : we can compare the strings by address.... */ 
    264             else if (entries[i].fileName == fileName) 
    265             { 
    266                 if (i != 0) 
    267                 { 
    268                     GDALDataset* ds = entries[i].ds; 
    269                     memmove(&entries[1], &entries[0], sizeof(CacheEntry) * i); 
    270                     entries[0].ds = ds; 
    271                     entries[0].fileName = fileName; 
    272                 } 
    273                 return entries[0].ds; 
    274             } 
    275         } 
    276         GDALClose(entries[size-1].ds); 
    277         memmove(&entries[1], &entries[0], sizeof(CacheEntry) * (size-1)); 
    278         entries[0].fileName = fileName; 
    279         entries[0].ds = (GDALDataset *) GDALOpenShared( fileName, GA_ReadOnly ); 
    280         return entries[0].ds; 
    281     } 
    282  
    283     public: 
    284         static void Ref() 
    285         { 
    286             CPLMutexHolderD( &RPFTOCCacheMutex ); 
    287             if (singleton == NULL) 
    288                 singleton = new RPFTOCGDALDatasetCache(100); 
    289             refCount++; 
    290         } 
    291  
    292         static void Unref() 
    293         { 
    294             CPLMutexHolderD( &RPFTOCCacheMutex ); 
    295             refCount--; 
    296             if (refCount == 0) 
    297             { 
    298                 delete singleton; 
    299                 singleton = NULL; 
    300             } 
    301         } 
    302  
    303         static GDALDataset* GetDataset(const char* fileName) 
    304         { 
    305             CPLMutexHolderD( &RPFTOCCacheMutex ); 
    306             if (! singleton) return NULL; 
    307             GDALDataset* ds = singleton->_GetDataset(fileName); 
    308             ds->Reference(); 
    309             return ds; 
    310         } 
    311  
    312         static void ReleaseDataset(GDALDataset* ds) 
    313         { 
    314             CPLMutexHolderD( &RPFTOCCacheMutex ); 
    315             ds->Dereference(); 
    316         } 
    317 }; 
    318  
    319203 
    320204/************************************************************************/ 
     
    324208/************************************************************************/ 
    325209 
    326 class RPFTOCProxyRasterDataSet : public GDALDataset 
    327 
    328     char* fileName; 
    329      
     210class RPFTOCProxyRasterDataSet : public GDALProxyPoolDataset 
     211
    330212    /* The following parameters are only for sanity checking */ 
    331213    int checkDone; 
    332214    int checkOK; 
    333     const char* projectionRef; 
    334215    double nwLong, nwLat; 
    335216    GDALColorTable* colorTableRef; 
     
    337218    double noDataValue; 
    338219    RPFTOCSubDataset* subdataset; 
    339      
     220 
    340221    public: 
    341222        RPFTOCProxyRasterDataSet(RPFTOCSubDataset* subdataset, 
     
    346227                                 int nBands); 
    347228 
    348         ~RPFTOCProxyRasterDataSet() 
    349         { 
    350             if (fileName) 
    351                 CPLFree(fileName); 
    352         } 
    353          
    354229        void SetNoDataValue(double noDataValue) { 
    355230            this->noDataValue = noDataValue; 
    356231            bHasNoDataValue = TRUE; 
    357232        } 
    358          
     233 
    359234        double GetNoDataValue(int* bHasNoDataValue) 
    360235        { 
     
    362237                *bHasNoDataValue = this->bHasNoDataValue; 
    363238            return noDataValue; 
    364         }  
    365          
     239        } 
     240 
     241        GDALDataset* GetUnderlyingDataset() { return GDALProxyPoolDataset::GetUnderlyingDataset(); } 
     242 
    366243        void SetReferenceColorTable(GDALColorTable* colorTableRef) { this->colorTableRef = colorTableRef;} 
    367          
     244 
    368245        const GDALColorTable* GetReferenceColorTable() { return colorTableRef; } 
    369246 
    370         const char* GetFileName() { return fileName; } 
    371          
    372247        int SanityCheckOK(GDALDataset* sourceDS); 
    373          
     248 
    374249        RPFTOCSubDataset* GetSubDataset() { return subdataset; } 
    375250}; 
     
    391266 
    392267    public: 
    393         RPFTOCProxyRasterBandRGBA(int nRasterXSize, int nRasterYSize
     268        RPFTOCProxyRasterBandRGBA(GDALProxyPoolDataset* poDS, int nBand
    394269                                  int nBlockXSize, int nBlockYSize) 
    395270        { 
    396             RPFTOCGDALDatasetCache::Ref()
    397             this->eAccess = GA_ReadOnly
    398             this->eDataType = GDT_Byte
     271            this->poDS = poDS
     272            nRasterXSize = poDS->GetRasterXSize()
     273            nRasterYSize = poDS->GetRasterYSize()
    399274            this->nBlockXSize = nBlockXSize; 
    400275            this->nBlockYSize = nBlockYSize; 
    401             this->nRasterXSize = nRasterXSize; 
    402             this->nRasterYSize = nRasterYSize
     276            eDataType = GDT_Byte; 
     277            this->nBand = nBand
    403278            blockByteSize = nBlockXSize * nBlockYSize; 
    404279            initDone = FALSE; 
    405280        } 
    406281 
    407         ~RPFTOCProxyRasterBandRGBA() 
    408         { 
    409             RPFTOCGDALDatasetCache::Unref(); 
    410         } 
    411          
    412282        virtual GDALColorInterp GetColorInterpretation() 
    413283        { 
     
    460330    CPLErr ret; 
    461331    RPFTOCProxyRasterDataSet* proxyDS = (RPFTOCProxyRasterDataSet*)poDS; 
    462     const char* fileName = proxyDS->GetFileName(); 
    463     GDALDataset* ds = RPFTOCGDALDatasetCache::GetDataset(fileName); 
     332    GDALDataset* ds = proxyDS->GetUnderlyingDataset(); 
    464333    if (ds) 
    465334    { 
    466335        if (proxyDS->SanityCheckOK(ds) == FALSE) 
    467336        { 
    468             RPFTOCGDALDatasetCache::ReleaseDataset(ds); 
    469337            return CE_Failure; 
    470338        } 
     
    500368        /* computing the R tile, the G tile, the B tile and the A tile */ 
    501369        void* cachedImage = 
    502                 proxyDS->GetSubDataset()->GetCachedTile(fileName, nBlockXOff, nBlockYOff); 
     370                proxyDS->GetSubDataset()->GetCachedTile(GetDescription(), nBlockXOff, nBlockYOff); 
    503371        if (cachedImage == NULL) 
    504372        { 
    505373            CPLDebug("RPFTOC", "Read (%d, %d) of band %d, of file %s", 
    506                      nBlockXOff, nBlockYOff, nBand, fileName); 
     374                     nBlockXOff, nBlockYOff, nBand, GetDescription()); 
    507375            ret = srcBand->ReadBlock(nBlockXOff, nBlockYOff, pImage); 
    508376            if (ret == CE_None) 
    509377            { 
    510378                proxyDS->GetSubDataset()->SetCachedTile 
    511                         (fileName, nBlockXOff, nBlockYOff, pImage, blockByteSize); 
     379                        (GetDescription(), nBlockXOff, nBlockYOff, pImage, blockByteSize); 
    512380                Expand(pImage, pImage); 
    513381            } 
     
    543411        ret = CE_Failure; 
    544412 
    545     RPFTOCGDALDatasetCache::ReleaseDataset(ds); 
    546  
    547413    return ret; 
    548414} 
     
    562428 
    563429    public: 
    564         RPFTOCProxyRasterBandPalette(int nRasterXSize, int nRasterYSize
     430        RPFTOCProxyRasterBandPalette(GDALProxyPoolDataset* poDS, int nBand
    565431                                     int nBlockXSize, int nBlockYSize) 
    566432        { 
    567             RPFTOCGDALDatasetCache::Ref()
    568             this->eAccess = GA_ReadOnly
    569             this->eDataType = GDT_Byte
     433            this->poDS = poDS
     434            nRasterXSize = poDS->GetRasterXSize()
     435            nRasterYSize = poDS->GetRasterYSize()
    570436            this->nBlockXSize = nBlockXSize; 
    571437            this->nBlockYSize = nBlockYSize; 
    572             this->nRasterXSize = nRasterXSize; 
    573             this->nRasterYSize = nRasterYSize
     438            eDataType = GDT_Byte; 
     439            this->nBand = nBand
    574440            blockByteSize = nBlockXSize * nBlockYSize; 
    575441            initDone = FALSE; 
    576442        } 
    577443 
    578         ~RPFTOCProxyRasterBandPalette() 
    579         { 
    580             RPFTOCGDALDatasetCache::Unref(); 
    581         } 
    582          
    583444        virtual GDALColorInterp GetColorInterpretation() 
    584445        { 
    585446            return GCI_PaletteIndex; 
    586447        } 
    587          
     448 
    588449        virtual double GetNoDataValue(int* bHasNoDataValue) 
    589450        { 
    590451            return ((RPFTOCProxyRasterDataSet*)poDS)->GetNoDataValue(bHasNoDataValue); 
    591452        } 
    592          
     453 
    593454        virtual GDALColorTable *GetColorTable() 
    594455        { 
     
    610471    CPLErr ret; 
    611472    RPFTOCProxyRasterDataSet* proxyDS = (RPFTOCProxyRasterDataSet*)poDS; 
    612     const char* fileName = proxyDS->GetFileName(); 
    613     GDALDataset* ds = RPFTOCGDALDatasetCache::GetDataset(fileName); 
     473    GDALDataset* ds = proxyDS->GetUnderlyingDataset(); 
    614474    if (ds) 
    615475    { 
    616476        if (proxyDS->SanityCheckOK(ds) == FALSE) 
    617477        { 
    618             RPFTOCGDALDatasetCache::ReleaseDataset(ds); 
    619478            return CE_Failure; 
    620479        } 
     
    633492                    CPLError( CE_Failure, CPLE_AppDefined, 
    634493                              "Palette for %s is different from reference palette. " 
    635                               "Coudln't remap exactly all colors. Trying to find closest matches.\n", fileName); 
     494                              "Coudln't remap exactly all colors. Trying to find closest matches.\n", GetDescription()); 
    636495                } 
    637496            } 
     
    658517        ret = CE_Failure; 
    659518 
    660     RPFTOCGDALDatasetCache::ReleaseDataset(ds); 
    661  
    662519    return ret; 
    663520} 
     
    673530         int nBlockXSize, int nBlockYSize, 
    674531         const char* projectionRef, double nwLong, double nwLat, 
    675          int nBands) 
     532         int nBands) : 
     533            /* Mark as shared since the VRT will take several references if we are in RGBA mode (4 bands for this dataset) */ 
     534                GDALProxyPoolDataset(fileName, nRasterXSize, nRasterYSize, GA_ReadOnly, TRUE, projectionRef) 
    676535{ 
    677536    int i; 
    678537    this->subdataset = subdataset; 
    679     this->fileName = CPLStrdup(fileName); 
    680     this->nRasterXSize = nRasterXSize; 
    681     this->nRasterYSize = nRasterYSize; 
    682     this->eAccess = GA_ReadOnly; 
    683     this->projectionRef = projectionRef; 
    684538    this->nwLong = nwLong; 
    685539    this->nwLat = nwLat; 
     
    687541    noDataValue = 0; 
    688542    colorTableRef = NULL; 
    689     bShared = TRUE; 
     543 
    690544    checkDone = FALSE; 
    691545    checkOK = FALSE; 
     
    694548        for(i=0;i<4;i++) 
    695549        { 
    696             SetBand(i+1, new RPFTOCProxyRasterBandRGBA(nRasterXSize, nRasterYSize, nBlockXSize, nBlockYSize)); 
     550            SetBand(i + 1, new RPFTOCProxyRasterBandRGBA(this, i+1, nBlockXSize, nBlockYSize)); 
    697551        } 
    698552    } 
    699553    else 
    700         SetBand(1, new RPFTOCProxyRasterBandPalette(nRasterXSize, nRasterYSize, nBlockXSize, nBlockYSize)); 
     554        SetBand(1, new RPFTOCProxyRasterBandPalette(this, 1, nBlockXSize, nBlockYSize)); 
    701555} 
    702556 
     
    705559/************************************************************************/ 
    706560 
    707 #define WARN_CHECK_DS(x) do { if (!(x)) { CPLError(CE_Warning, CPLE_AppDefined, "For %s, assert '" #x "' failed", fileName); checkOK = FALSE; } } while(0) 
     561#define WARN_CHECK_DS(x) do { if (!(x)) { CPLError(CE_Warning, CPLE_AppDefined, "For %s, assert '" #x "' failed", GetDescription()); checkOK = FALSE; } } while(0) 
    708562 
    709563int RPFTOCProxyRasterDataSet::SanityCheckOK(GDALDataset* sourceDS) 
     
    726580    WARN_CHECK_DS(sourceDS->GetRasterXSize() == nRasterXSize); 
    727581    WARN_CHECK_DS(sourceDS->GetRasterYSize() == nRasterYSize); 
    728     WARN_CHECK_DS(EQUAL(sourceDS->GetProjectionRef(), projectionRef)); 
     582    WARN_CHECK_DS(EQUAL(sourceDS->GetProjectionRef(), GetProjectionRef())); 
    729583    sourceDS->GetRasterBand(1)->GetBlockSize(&src_nBlockXSize, &src_nBlockYSize); 
    730584    GetRasterBand(1)->GetBlockSize(&nBlockXSize, &nBlockYSize);