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 36425 : 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 36425 : if (poOpenInfo->nHeaderBytes < 100) 122 29552 : return nullptr; 123 : 124 6873 : if (poOpenInfo->pabyHeader[4] != 0x3f || 125 5 : poOpenInfo->pabyHeader[5] != 0xc0 || 126 4 : poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12) 127 6869 : 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 : ReportUpdateNotSupportedByDriver("CEOS"); 159 0 : return nullptr; 160 : } 161 : /* -------------------------------------------------------------------- */ 162 : /* Create a corresponding GDALDataset. */ 163 : /* -------------------------------------------------------------------- */ 164 2 : CEOSDataset *poDS = new CEOSDataset(); 165 : 166 2 : poDS->psCEOS = psCEOS; 167 : 168 : /* -------------------------------------------------------------------- */ 169 : /* Capture some information from the file that is of interest. */ 170 : /* -------------------------------------------------------------------- */ 171 2 : poDS->nRasterXSize = psCEOS->nPixels; 172 2 : poDS->nRasterYSize = psCEOS->nLines; 173 : 174 : /* -------------------------------------------------------------------- */ 175 : /* Create band information objects. */ 176 : /* -------------------------------------------------------------------- */ 177 2 : poDS->nBands = psCEOS->nBands; 178 : 179 10 : for (int i = 0; i < poDS->nBands; i++) 180 8 : poDS->SetBand(i + 1, new CEOSRasterBand(poDS, i + 1)); 181 : 182 : /* -------------------------------------------------------------------- */ 183 : /* Initialize any PAM information. */ 184 : /* -------------------------------------------------------------------- */ 185 2 : poDS->SetDescription(poOpenInfo->pszFilename); 186 2 : poDS->TryLoadXML(); 187 : 188 : /* -------------------------------------------------------------------- */ 189 : /* Check for overviews. */ 190 : /* -------------------------------------------------------------------- */ 191 2 : poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); 192 : 193 2 : return poDS; 194 : } 195 : 196 : /************************************************************************/ 197 : /* GDALRegister_GTiff() */ 198 : /************************************************************************/ 199 : 200 1686 : void GDALRegister_CEOS() 201 : 202 : { 203 1686 : if (GDALGetDriverByName("CEOS") != nullptr) 204 302 : return; 205 : 206 1384 : GDALDriver *poDriver = new GDALDriver(); 207 : 208 1384 : poDriver->SetDescription("CEOS"); 209 1384 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 210 1384 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "CEOS Image"); 211 1384 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/ceos.html"); 212 1384 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 213 : 214 1384 : poDriver->pfnOpen = CEOSDataset::Open; 215 : 216 1384 : GetGDALDriverManager()->RegisterDriver(poDriver); 217 : }