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