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 : public: 33 : CEOSDataset(); 34 : ~CEOSDataset(); 35 : static GDALDataset *Open(GDALOpenInfo *); 36 : }; 37 : 38 : /************************************************************************/ 39 : /* ==================================================================== */ 40 : /* CEOSRasterBand */ 41 : /* ==================================================================== */ 42 : /************************************************************************/ 43 : 44 : class CEOSRasterBand final : public GDALPamRasterBand 45 : { 46 : friend class CEOSDataset; 47 : 48 : public: 49 : CEOSRasterBand(CEOSDataset *, int); 50 : 51 : CPLErr IReadBlock(int, int, void *) override; 52 : }; 53 : 54 : /************************************************************************/ 55 : /* CEOSRasterBand() */ 56 : /************************************************************************/ 57 : 58 8 : CEOSRasterBand::CEOSRasterBand(CEOSDataset *poDSIn, int nBandIn) 59 : 60 : { 61 8 : poDS = poDSIn; 62 8 : nBand = nBandIn; 63 : 64 8 : eDataType = GDT_Byte; 65 : 66 8 : nBlockXSize = poDS->GetRasterXSize(); 67 8 : nBlockYSize = 1; 68 8 : } 69 : 70 : /************************************************************************/ 71 : /* IReadBlock() */ 72 : /************************************************************************/ 73 : 74 3 : CPLErr CEOSRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff, 75 : void *pImage) 76 : { 77 3 : CEOSDataset *poCEOS_DS = (CEOSDataset *)poDS; 78 : 79 3 : CPLAssert(nBlockXOff == 0); 80 : 81 3 : return CEOSReadScanline(poCEOS_DS->psCEOS, nBand, nBlockYOff + 1, pImage); 82 : } 83 : 84 : /************************************************************************/ 85 : /* ==================================================================== */ 86 : /* CEOSDataset */ 87 : /* ==================================================================== */ 88 : /************************************************************************/ 89 : 90 : /************************************************************************/ 91 : /* CEOSDataset() */ 92 : /************************************************************************/ 93 : 94 2 : CEOSDataset::CEOSDataset() : psCEOS(nullptr) 95 : { 96 2 : } 97 : 98 : /************************************************************************/ 99 : /* ~CEOSDataset() */ 100 : /************************************************************************/ 101 : 102 4 : CEOSDataset::~CEOSDataset() 103 : 104 : { 105 2 : FlushCache(true); 106 2 : if (psCEOS) 107 2 : CEOSClose(psCEOS); 108 4 : } 109 : 110 : /************************************************************************/ 111 : /* Open() */ 112 : /************************************************************************/ 113 : 114 35863 : GDALDataset *CEOSDataset::Open(GDALOpenInfo *poOpenInfo) 115 : 116 : { 117 : /* -------------------------------------------------------------------- */ 118 : /* Before trying CEOSOpen() we first verify that the first */ 119 : /* record is in fact a CEOS file descriptor record. */ 120 : /* -------------------------------------------------------------------- */ 121 35863 : if (poOpenInfo->nHeaderBytes < 100) 122 29022 : return nullptr; 123 : 124 6841 : if (poOpenInfo->pabyHeader[4] != 0x3f || 125 5 : poOpenInfo->pabyHeader[5] != 0xc0 || 126 4 : poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12) 127 6837 : return nullptr; 128 : 129 : /* -------------------------------------------------------------------- */ 130 : /* Try opening the dataset. */ 131 : /* -------------------------------------------------------------------- */ 132 4 : CEOSImage *psCEOS = CEOSOpen(poOpenInfo->pszFilename, "rb"); 133 4 : if (psCEOS == nullptr) 134 2 : return nullptr; 135 : 136 2 : if (psCEOS->nBitsPerPixel != 8) 137 : { 138 0 : CPLError(CE_Failure, CPLE_NotSupported, 139 : "The CEOS driver cannot handle nBitsPerPixel = %d", 140 : psCEOS->nBitsPerPixel); 141 0 : CEOSClose(psCEOS); 142 0 : return nullptr; 143 : } 144 : 145 4 : if (!GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) || 146 2 : !GDALCheckBandCount(psCEOS->nBands, FALSE)) 147 : { 148 0 : CEOSClose(psCEOS); 149 0 : return nullptr; 150 : } 151 : 152 : /* -------------------------------------------------------------------- */ 153 : /* Confirm the requested access is supported. */ 154 : /* -------------------------------------------------------------------- */ 155 2 : if (poOpenInfo->eAccess == GA_Update) 156 : { 157 0 : CEOSClose(psCEOS); 158 0 : CPLError(CE_Failure, CPLE_NotSupported, 159 : "The CEOS driver does not support update access to existing" 160 : " datasets.\n"); 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 1595 : void GDALRegister_CEOS() 203 : 204 : { 205 1595 : if (GDALGetDriverByName("CEOS") != nullptr) 206 302 : return; 207 : 208 1293 : GDALDriver *poDriver = new GDALDriver(); 209 : 210 1293 : poDriver->SetDescription("CEOS"); 211 1293 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 212 1293 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "CEOS Image"); 213 1293 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/ceos.html"); 214 1293 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 215 : 216 1293 : poDriver->pfnOpen = CEOSDataset::Open; 217 : 218 1293 : GetGDALDriverManager()->RegisterDriver(poDriver); 219 : }