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 : * Permission is hereby granted, free of charge, to any person obtaining a 12 : * copy of this software and associated documentation files (the "Software"), 13 : * to deal in the Software without restriction, including without limitation 14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 : * and/or sell copies of the Software, and to permit persons to whom the 16 : * Software is furnished to do so, subject to the following conditions: 17 : * 18 : * The above copyright notice and this permission notice shall be included 19 : * in all copies or substantial portions of the Software. 20 : * 21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 : * DEALINGS IN THE SOFTWARE. 28 : ****************************************************************************/ 29 : 30 : #include "ceosopen.h" 31 : #include "gdal_frmts.h" 32 : #include "gdal_pam.h" 33 : 34 : /************************************************************************/ 35 : /* ==================================================================== */ 36 : /* CEOSDataset */ 37 : /* ==================================================================== */ 38 : /************************************************************************/ 39 : 40 : class CEOSRasterBand; 41 : 42 : class CEOSDataset final : public GDALPamDataset 43 : { 44 : friend class CEOSRasterBand; 45 : 46 : CEOSImage *psCEOS; 47 : 48 : public: 49 : CEOSDataset(); 50 : ~CEOSDataset(); 51 : static GDALDataset *Open(GDALOpenInfo *); 52 : }; 53 : 54 : /************************************************************************/ 55 : /* ==================================================================== */ 56 : /* CEOSRasterBand */ 57 : /* ==================================================================== */ 58 : /************************************************************************/ 59 : 60 : class CEOSRasterBand final : public GDALPamRasterBand 61 : { 62 : friend class CEOSDataset; 63 : 64 : public: 65 : CEOSRasterBand(CEOSDataset *, int); 66 : 67 : CPLErr IReadBlock(int, int, void *) override; 68 : }; 69 : 70 : /************************************************************************/ 71 : /* CEOSRasterBand() */ 72 : /************************************************************************/ 73 : 74 8 : CEOSRasterBand::CEOSRasterBand(CEOSDataset *poDSIn, int nBandIn) 75 : 76 : { 77 8 : poDS = poDSIn; 78 8 : nBand = nBandIn; 79 : 80 8 : eDataType = GDT_Byte; 81 : 82 8 : nBlockXSize = poDS->GetRasterXSize(); 83 8 : nBlockYSize = 1; 84 8 : } 85 : 86 : /************************************************************************/ 87 : /* IReadBlock() */ 88 : /************************************************************************/ 89 : 90 3 : CPLErr CEOSRasterBand::IReadBlock(CPL_UNUSED int nBlockXOff, int nBlockYOff, 91 : void *pImage) 92 : { 93 3 : CEOSDataset *poCEOS_DS = (CEOSDataset *)poDS; 94 : 95 3 : CPLAssert(nBlockXOff == 0); 96 : 97 3 : return CEOSReadScanline(poCEOS_DS->psCEOS, nBand, nBlockYOff + 1, pImage); 98 : } 99 : 100 : /************************************************************************/ 101 : /* ==================================================================== */ 102 : /* CEOSDataset */ 103 : /* ==================================================================== */ 104 : /************************************************************************/ 105 : 106 : /************************************************************************/ 107 : /* CEOSDataset() */ 108 : /************************************************************************/ 109 : 110 2 : CEOSDataset::CEOSDataset() : psCEOS(nullptr) 111 : { 112 2 : } 113 : 114 : /************************************************************************/ 115 : /* ~CEOSDataset() */ 116 : /************************************************************************/ 117 : 118 4 : CEOSDataset::~CEOSDataset() 119 : 120 : { 121 2 : FlushCache(true); 122 2 : if (psCEOS) 123 2 : CEOSClose(psCEOS); 124 4 : } 125 : 126 : /************************************************************************/ 127 : /* Open() */ 128 : /************************************************************************/ 129 : 130 34021 : GDALDataset *CEOSDataset::Open(GDALOpenInfo *poOpenInfo) 131 : 132 : { 133 : /* -------------------------------------------------------------------- */ 134 : /* Before trying CEOSOpen() we first verify that the first */ 135 : /* record is in fact a CEOS file descriptor record. */ 136 : /* -------------------------------------------------------------------- */ 137 34021 : if (poOpenInfo->nHeaderBytes < 100) 138 27597 : return nullptr; 139 : 140 6424 : if (poOpenInfo->pabyHeader[4] != 0x3f || 141 5 : poOpenInfo->pabyHeader[5] != 0xc0 || 142 4 : poOpenInfo->pabyHeader[6] != 0x12 || poOpenInfo->pabyHeader[7] != 0x12) 143 6420 : return nullptr; 144 : 145 : /* -------------------------------------------------------------------- */ 146 : /* Try opening the dataset. */ 147 : /* -------------------------------------------------------------------- */ 148 4 : CEOSImage *psCEOS = CEOSOpen(poOpenInfo->pszFilename, "rb"); 149 4 : if (psCEOS == nullptr) 150 2 : return nullptr; 151 : 152 2 : if (psCEOS->nBitsPerPixel != 8) 153 : { 154 0 : CPLError(CE_Failure, CPLE_NotSupported, 155 : "The CEOS driver cannot handle nBitsPerPixel = %d", 156 : psCEOS->nBitsPerPixel); 157 0 : CEOSClose(psCEOS); 158 0 : return nullptr; 159 : } 160 : 161 4 : if (!GDALCheckDatasetDimensions(psCEOS->nPixels, psCEOS->nBands) || 162 2 : !GDALCheckBandCount(psCEOS->nBands, FALSE)) 163 : { 164 0 : CEOSClose(psCEOS); 165 0 : return nullptr; 166 : } 167 : 168 : /* -------------------------------------------------------------------- */ 169 : /* Confirm the requested access is supported. */ 170 : /* -------------------------------------------------------------------- */ 171 2 : if (poOpenInfo->eAccess == GA_Update) 172 : { 173 0 : CEOSClose(psCEOS); 174 0 : CPLError(CE_Failure, CPLE_NotSupported, 175 : "The CEOS driver does not support update access to existing" 176 : " datasets.\n"); 177 0 : return nullptr; 178 : } 179 : /* -------------------------------------------------------------------- */ 180 : /* Create a corresponding GDALDataset. */ 181 : /* -------------------------------------------------------------------- */ 182 2 : CEOSDataset *poDS = new CEOSDataset(); 183 : 184 2 : poDS->psCEOS = psCEOS; 185 : 186 : /* -------------------------------------------------------------------- */ 187 : /* Capture some information from the file that is of interest. */ 188 : /* -------------------------------------------------------------------- */ 189 2 : poDS->nRasterXSize = psCEOS->nPixels; 190 2 : poDS->nRasterYSize = psCEOS->nLines; 191 : 192 : /* -------------------------------------------------------------------- */ 193 : /* Create band information objects. */ 194 : /* -------------------------------------------------------------------- */ 195 2 : poDS->nBands = psCEOS->nBands; 196 : 197 10 : for (int i = 0; i < poDS->nBands; i++) 198 8 : poDS->SetBand(i + 1, new CEOSRasterBand(poDS, i + 1)); 199 : 200 : /* -------------------------------------------------------------------- */ 201 : /* Initialize any PAM information. */ 202 : /* -------------------------------------------------------------------- */ 203 2 : poDS->SetDescription(poOpenInfo->pszFilename); 204 2 : poDS->TryLoadXML(); 205 : 206 : /* -------------------------------------------------------------------- */ 207 : /* Check for overviews. */ 208 : /* -------------------------------------------------------------------- */ 209 2 : poDS->oOvManager.Initialize(poDS, poOpenInfo->pszFilename); 210 : 211 2 : return poDS; 212 : } 213 : 214 : /************************************************************************/ 215 : /* GDALRegister_GTiff() */ 216 : /************************************************************************/ 217 : 218 1509 : void GDALRegister_CEOS() 219 : 220 : { 221 1509 : if (GDALGetDriverByName("CEOS") != nullptr) 222 295 : return; 223 : 224 1214 : GDALDriver *poDriver = new GDALDriver(); 225 : 226 1214 : poDriver->SetDescription("CEOS"); 227 1214 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 228 1214 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "CEOS Image"); 229 1214 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/ceos.html"); 230 1214 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 231 : 232 1214 : poDriver->pfnOpen = CEOSDataset::Open; 233 : 234 1214 : GetGDALDriverManager()->RegisterDriver(poDriver); 235 : }