Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: CEOS Translator 4 : * Purpose: GDALDataset driver for CEOS translator. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1999, Frank Warmerdam 9 : * Copyright (c) 2009-2010, Even Rouault <even dot rouault at spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "ceosopen.h" 15 : #include "gdal_frmts.h" 16 : #include "gdal_pam.h" 17 : 18 : /************************************************************************/ 19 : /* ==================================================================== */ 20 : /* CEOSDataset */ 21 : /* ==================================================================== */ 22 : /************************************************************************/ 23 : 24 : class CEOSRasterBand; 25 : 26 : class CEOSDataset final : public GDALPamDataset 27 : { 28 : friend class CEOSRasterBand; 29 : 30 : CEOSImage *psCEOS; 31 : 32 : CPL_DISALLOW_COPY_ASSIGN(CEOSDataset) 33 : 34 : public: 35 : CEOSDataset(); 36 : ~CEOSDataset(); 37 : static GDALDataset *Open(GDALOpenInfo *); 38 : }; 39 : 40 : /************************************************************************/ 41 : /* ==================================================================== */ 42 : /* CEOSRasterBand */ 43 : /* ==================================================================== */ 44 : /************************************************************************/ 45 : 46 : class CEOSRasterBand final : public GDALPamRasterBand 47 : { 48 : friend class CEOSDataset; 49 : 50 : public: 51 : CEOSRasterBand(CEOSDataset *, int); 52 : 53 : CPLErr IReadBlock(int, int, void *) override; 54 : }; 55 : 56 : /************************************************************************/ 57 : /* CEOSRasterBand() */ 58 : /************************************************************************/ 59 : 60 8 : CEOSRasterBand::CEOSRasterBand(CEOSDataset *poDSIn, int nBandIn) 61 : 62 : { 63 8 : poDS = poDSIn; 64 8 : nBand = nBandIn; 65 : 66 8 : eDataType = GDT_Byte; 67 : 68 8 : nBlockXSize = poDS->GetRasterXSize(); 69 8 : nBlockYSize = 1; 70 8 : } 71 : 72 : /************************************************************************/ 73 : /* IReadBlock() */ 74 : /************************************************************************/ 75 : 76 3 : CPLErr CEOSRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff, 77 : void *pImage) 78 : { 79 3 : CEOSDataset *poCEOS_DS = cpl::down_cast<CEOSDataset *>(poDS); 80 : 81 3 : CPLAssert(nBlockXOff == 0); 82 : 83 3 : return CEOSReadScanline(poCEOS_DS->psCEOS, nBand, nBlockYOff + 1, pImage); 84 : } 85 : 86 : /************************************************************************/ 87 : /* ==================================================================== */ 88 : /* CEOSDataset */ 89 : /* ==================================================================== */ 90 : /************************************************************************/ 91 : 92 : /************************************************************************/ 93 : /* CEOSDataset() */ 94 : /************************************************************************/ 95 : 96 2 : CEOSDataset::CEOSDataset() : psCEOS(nullptr) 97 : { 98 2 : } 99 : 100 : /************************************************************************/ 101 : /* ~CEOSDataset() */ 102 : /************************************************************************/ 103 : 104 4 : CEOSDataset::~CEOSDataset() 105 : 106 : { 107 2 : FlushCache(true); 108 2 : if (psCEOS) 109 2 : CEOSClose(psCEOS); 110 4 : } 111 : 112 : /************************************************************************/ 113 : /* Open() */ 114 : /************************************************************************/ 115 : 116 38285 : GDALDataset *CEOSDataset::Open(GDALOpenInfo *poOpenInfo) 117 : 118 : { 119 : /* -------------------------------------------------------------------- */ 120 : /* Before trying CEOSOpen() we first verify that the first */ 121 : /* record is in fact a CEOS file descriptor record. */ 122 : /* -------------------------------------------------------------------- */ 123 38285 : if (poOpenInfo->nHeaderBytes < 100) 124 31608 : return nullptr; 125 : 126 6677 : if (poOpenInfo->pabyHeader[4] != 0x3f || 127 5 : poOpenInfo->pabyHeader[5] != 0xc0 || 128 4 : poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12) 129 6673 : return nullptr; 130 : 131 : /* -------------------------------------------------------------------- */ 132 : /* Try opening the dataset. */ 133 : /* -------------------------------------------------------------------- */ 134 4 : CEOSImage *psCEOS = CEOSOpen(poOpenInfo->pszFilename, "rb"); 135 4 : if (psCEOS == nullptr) 136 2 : return nullptr; 137 : 138 2 : if (psCEOS->nBitsPerPixel != 8) 139 : { 140 0 : CPLError(CE_Failure, CPLE_NotSupported, 141 : "The CEOS driver cannot handle nBitsPerPixel = %d", 142 : psCEOS->nBitsPerPixel); 143 0 : CEOSClose(psCEOS); 144 0 : return nullptr; 145 : } 146 : 147 4 : if (!GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) || 148 2 : !GDALCheckBandCount(psCEOS->nBands, FALSE)) 149 : { 150 0 : CEOSClose(psCEOS); 151 0 : return nullptr; 152 : } 153 : 154 : /* -------------------------------------------------------------------- */ 155 : /* Confirm the requested access is supported. */ 156 : /* -------------------------------------------------------------------- */ 157 2 : if (poOpenInfo->eAccess == GA_Update) 158 : { 159 0 : CEOSClose(psCEOS); 160 0 : ReportUpdateNotSupportedByDriver("CEOS"); 161 0 : return nullptr; 162 : } 163 : /* -------------------------------------------------------------------- */ 164 : /* Create a corresponding GDALDataset. */ 165 : /* -------------------------------------------------------------------- */ 166 2 : CEOSDataset *poDS = new CEOSDataset(); 167 : 168 2 : poDS->psCEOS = psCEOS; 169 : 170 : /* -------------------------------------------------------------------- */ 171 : /* Capture some information from the file that is of interest. */ 172 : /* -------------------------------------------------------------------- */ 173 2 : poDS->nRasterXSize = psCEOS->nPixels; 174 2 : poDS->nRasterYSize = psCEOS->nLines; 175 : 176 : /* -------------------------------------------------------------------- */ 177 : /* Create band information objects. */ 178 : /* -------------------------------------------------------------------- */ 179 2 : poDS->nBands = psCEOS->nBands; 180 : 181 10 : for (int i = 0; i < poDS->nBands; i++) 182 8 : poDS->SetBand(i + 1, new CEOSRasterBand(poDS, i + 1)); 183 : 184 : /* -------------------------------------------------------------------- */ 185 : /* Initialize any PAM information. */ 186 : /* -------------------------------------------------------------------- */ 187 2 : poDS->SetDescription(poOpenInfo->pszFilename); 188 2 : poDS->TryLoadXML(); 189 : 190 : /* -------------------------------------------------------------------- */ 191 : /* Check for overviews. */ 192 : /* -------------------------------------------------------------------- */ 193 2 : poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); 194 : 195 2 : return poDS; 196 : } 197 : 198 : /************************************************************************/ 199 : /* GDALRegister_GTiff() */ 200 : /************************************************************************/ 201 : 202 1911 : void GDALRegister_CEOS() 203 : 204 : { 205 1911 : if (GDALGetDriverByName("CEOS") != nullptr) 206 282 : return; 207 : 208 1629 : GDALDriver *poDriver = new GDALDriver(); 209 : 210 1629 : poDriver->SetDescription("CEOS"); 211 1629 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 212 1629 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "CEOS Image"); 213 1629 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/ceos.html"); 214 1629 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 215 : 216 1629 : poDriver->pfnOpen = CEOSDataset::Open; 217 : 218 1629 : GetGDALDriverManager()->RegisterDriver(poDriver); 219 : }