/src/gdal/frmts/raw/eirdataset.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: Erdas EIR Raw Driver |
4 | | * Purpose: Implementation of EIRDataset |
5 | | * Author: Adam Milling, amilling@alumni.uwaterloo.ca |
6 | | * |
7 | | ****************************************************************************** |
8 | | * Copyright (c) 1999, Frank Warmerdam <warmerdam@pobox.com> |
9 | | * Copyright (c) 2009-2010, Even Rouault <even dot rouault at spatialys.com> |
10 | | * |
11 | | * SPDX-License-Identifier: MIT |
12 | | ****************************************************************************/ |
13 | | |
14 | | #include "cpl_string.h" |
15 | | #include "gdal_frmts.h" |
16 | | #include "gdal_priv.h" |
17 | | #include "ogr_spatialref.h" |
18 | | #include "rawdataset.h" |
19 | | |
20 | | #include <limits> |
21 | | |
22 | | /************************************************************************/ |
23 | | /* ==================================================================== */ |
24 | | /* EIRDataset */ |
25 | | /* ==================================================================== */ |
26 | | /************************************************************************/ |
27 | | |
28 | | class EIRDataset final : public RawDataset |
29 | | { |
30 | | friend class RawRasterBand; |
31 | | |
32 | | VSILFILE *fpImage = nullptr; // image data file |
33 | | bool bGotTransform = false; |
34 | | GDALGeoTransform m_gt{}; |
35 | | bool bHDRDirty = false; |
36 | | CPLStringList aosHDR{}; |
37 | | char **papszExtraFiles = nullptr; |
38 | | |
39 | | void ResetKeyValue(const char *pszKey, const char *pszValue); |
40 | | #ifdef unused |
41 | | const char *GetKeyValue(const char *pszKey, const char *pszDefault = ""); |
42 | | #endif |
43 | | |
44 | | CPL_DISALLOW_COPY_ASSIGN(EIRDataset) |
45 | | |
46 | | CPLErr Close(GDALProgressFunc = nullptr, void * = nullptr) override; |
47 | | |
48 | | public: |
49 | | EIRDataset(); |
50 | | ~EIRDataset() override; |
51 | | |
52 | | CPLErr GetGeoTransform(GDALGeoTransform >) const override; |
53 | | |
54 | | char **GetFileList() override; |
55 | | |
56 | | static int Identify(GDALOpenInfo *); |
57 | | static GDALDataset *Open(GDALOpenInfo *); |
58 | | }; |
59 | | |
60 | | /************************************************************************/ |
61 | | /* ==================================================================== */ |
62 | | /* EIRDataset */ |
63 | | /* ==================================================================== */ |
64 | | /************************************************************************/ |
65 | | |
66 | | /************************************************************************/ |
67 | | /* EIRDataset() */ |
68 | | /************************************************************************/ |
69 | | |
70 | 1 | EIRDataset::EIRDataset() = default; |
71 | | |
72 | | /************************************************************************/ |
73 | | /* ~EIRDataset() */ |
74 | | /************************************************************************/ |
75 | | |
76 | | EIRDataset::~EIRDataset() |
77 | | |
78 | 1 | { |
79 | 1 | EIRDataset::Close(); |
80 | 1 | } |
81 | | |
82 | | /************************************************************************/ |
83 | | /* Close() */ |
84 | | /************************************************************************/ |
85 | | |
86 | | CPLErr EIRDataset::Close(GDALProgressFunc, void *) |
87 | 2 | { |
88 | 2 | CPLErr eErr = CE_None; |
89 | 2 | if (nOpenFlags != OPEN_FLAGS_CLOSED) |
90 | 1 | { |
91 | 1 | if (EIRDataset::FlushCache(true) != CE_None) |
92 | 0 | eErr = CE_Failure; |
93 | | |
94 | 1 | if (nBands > 0 && GetAccess() == GA_Update) |
95 | 0 | { |
96 | 0 | RawRasterBand *poBand = |
97 | 0 | cpl::down_cast<RawRasterBand *>(GetRasterBand(1)); |
98 | |
|
99 | 0 | int bNoDataSet = FALSE; |
100 | 0 | const double dfNoData = poBand->GetNoDataValue(&bNoDataSet); |
101 | 0 | if (bNoDataSet) |
102 | 0 | { |
103 | 0 | ResetKeyValue("NODATA", CPLString().Printf("%.8g", dfNoData)); |
104 | 0 | } |
105 | 0 | } |
106 | | |
107 | 1 | if (fpImage) |
108 | 1 | { |
109 | 1 | if (VSIFCloseL(fpImage) != 0) |
110 | 0 | eErr = CE_Failure; |
111 | 1 | } |
112 | | |
113 | 1 | CSLDestroy(papszExtraFiles); |
114 | | |
115 | 1 | if (GDALPamDataset::Close() != CE_None) |
116 | 0 | eErr = CE_Failure; |
117 | 1 | } |
118 | 2 | return eErr; |
119 | 2 | } |
120 | | |
121 | | #ifdef unused |
122 | | /************************************************************************/ |
123 | | /* GetKeyValue() */ |
124 | | /************************************************************************/ |
125 | | |
126 | | const char *EIRDataset::GetKeyValue(const char *pszKey, const char *pszDefault) |
127 | | |
128 | | { |
129 | | const char *const *papszHDR = aosHDR.List(); |
130 | | for (int i = 0; papszHDR[i] != nullptr; i++) |
131 | | { |
132 | | if (EQUALN(pszKey, papszHDR[i], strlen(pszKey)) && |
133 | | isspace((unsigned char)papszHDR[i][strlen(pszKey)])) |
134 | | { |
135 | | const char *pszValue = papszHDR[i] + strlen(pszKey); |
136 | | while (isspace(static_cast<unsigned char>(*pszValue))) |
137 | | pszValue++; |
138 | | |
139 | | return pszValue; |
140 | | } |
141 | | } |
142 | | |
143 | | return pszDefault; |
144 | | } |
145 | | #endif |
146 | | |
147 | | /************************************************************************/ |
148 | | /* ResetKeyValue() */ |
149 | | /* */ |
150 | | /* Replace or add the keyword with the indicated value in the */ |
151 | | /* papszHDR list. */ |
152 | | /************************************************************************/ |
153 | | |
154 | | void EIRDataset::ResetKeyValue(const char *pszKey, const char *pszValue) |
155 | | |
156 | 0 | { |
157 | 0 | if (strlen(pszValue) > 65) |
158 | 0 | { |
159 | 0 | CPLAssert(strlen(pszValue) <= 65); |
160 | 0 | return; |
161 | 0 | } |
162 | | |
163 | 0 | char szNewLine[82] = {'\0'}; |
164 | 0 | snprintf(szNewLine, sizeof(szNewLine), "%-15s%s", pszKey, pszValue); |
165 | |
|
166 | 0 | char **papszHDR = aosHDR.List(); |
167 | 0 | for (int i = aosHDR.size() - 1; i >= 0; i--) |
168 | 0 | { |
169 | 0 | if (EQUALN(papszHDR[i], szNewLine, strlen(pszKey) + 1)) |
170 | 0 | { |
171 | 0 | if (strcmp(papszHDR[i], szNewLine) != 0) |
172 | 0 | { |
173 | 0 | CPLFree(papszHDR[i]); |
174 | 0 | papszHDR[i] = CPLStrdup(szNewLine); |
175 | 0 | bHDRDirty = true; |
176 | 0 | } |
177 | 0 | return; |
178 | 0 | } |
179 | 0 | } |
180 | | |
181 | 0 | bHDRDirty = true; |
182 | 0 | aosHDR.AddString(szNewLine); |
183 | 0 | } |
184 | | |
185 | | /************************************************************************/ |
186 | | /* GetGeoTransform() */ |
187 | | /************************************************************************/ |
188 | | |
189 | | CPLErr EIRDataset::GetGeoTransform(GDALGeoTransform >) const |
190 | | |
191 | 1 | { |
192 | 1 | if (bGotTransform) |
193 | 0 | { |
194 | 0 | gt = m_gt; |
195 | 0 | return CE_None; |
196 | 0 | } |
197 | | |
198 | 1 | return GDALPamDataset::GetGeoTransform(gt); |
199 | 1 | } |
200 | | |
201 | | /************************************************************************/ |
202 | | /* GetFileList() */ |
203 | | /************************************************************************/ |
204 | | |
205 | | char **EIRDataset::GetFileList() |
206 | | |
207 | 2 | { |
208 | | // Main data file, etc. |
209 | 2 | char **papszFileList = GDALPamDataset::GetFileList(); |
210 | | |
211 | | // Header file. |
212 | 2 | papszFileList = CSLInsertStrings(papszFileList, -1, papszExtraFiles); |
213 | | |
214 | 2 | return papszFileList; |
215 | 2 | } |
216 | | |
217 | | /************************************************************************/ |
218 | | /* Identify() */ |
219 | | /************************************************************************/ |
220 | | |
221 | | int EIRDataset::Identify(GDALOpenInfo *poOpenInfo) |
222 | | |
223 | 540k | { |
224 | 540k | if (poOpenInfo->nHeaderBytes < 100) |
225 | 452k | return FALSE; |
226 | | |
227 | 87.7k | if (strstr(reinterpret_cast<const char *>(poOpenInfo->pabyHeader), |
228 | 87.7k | "IMAGINE_RAW_FILE") == nullptr) |
229 | 84.7k | return FALSE; |
230 | | |
231 | 2.95k | return TRUE; |
232 | 87.7k | } |
233 | | |
234 | | /************************************************************************/ |
235 | | /* Open() */ |
236 | | /************************************************************************/ |
237 | | |
238 | | GDALDataset *EIRDataset::Open(GDALOpenInfo *poOpenInfo) |
239 | | |
240 | 1.47k | { |
241 | 1.47k | if (!Identify(poOpenInfo) || poOpenInfo->fpL == nullptr) |
242 | 0 | return nullptr; |
243 | | |
244 | | /* header example and description |
245 | | |
246 | | IMAGINE_RAW_FILE // must be on first line, by itself |
247 | | WIDTH 581 // number of columns in the image |
248 | | HEIGHT 695 // number of rows in the image |
249 | | NUM_LAYERS 3 // number of spectral bands in the image; default 1 |
250 | | PIXEL_FILES raw8_3n_ui_sanjack.bl // raster file |
251 | | // default: same name with no extension |
252 | | FORMAT BIL // BIL BIP BSQ; default BIL |
253 | | DATATYPE U8 // U1 U2 U4 U8 U16 U32 S16 S32 F32 F64; default U8 |
254 | | BYTE_ORDER // LSB MSB; required for U16 U32 S16 S32 F32 F64 |
255 | | DATA_OFFSET // start of image data in raster file; default 0 bytes |
256 | | END_RAW_FILE // end RAW file - stop reading |
257 | | |
258 | | For a true color image with three bands (R, G, B) stored using 8 bits |
259 | | for each pixel in each band, DATA_TYPE equals U8 and NUM_LAYERS equals |
260 | | 3 for a total of 24 bits per pixel. |
261 | | |
262 | | Note that the current version of ERDAS Raw Raster Reader/Writer does |
263 | | not support the LAYER_SKIP_BYTES, RECORD_SKIP_BYTES, TILE_WIDTH and |
264 | | TILE_HEIGHT directives. Since the reader does not read the PIXEL_FILES |
265 | | directive, the reader always assumes that the raw binary file is the |
266 | | dataset, and the name of this file is the name of the header without the |
267 | | extension. Currently, the reader does not support multiple raw binary |
268 | | files in one dataset or a single file with both the header and the raw |
269 | | binary data at the same time. |
270 | | */ |
271 | | |
272 | 1.47k | int nRows = -1; |
273 | 1.47k | int nCols = -1; |
274 | 1.47k | int nBands = 1; |
275 | 1.47k | int nSkipBytes = 0; |
276 | 1.47k | int nLineCount = 0; |
277 | 1.47k | GDALDataType eDataType = GDT_UInt8; |
278 | 1.47k | int nBits = 8; |
279 | 1.47k | char chByteOrder = 'M'; |
280 | 1.47k | char szLayout[10] = "BIL"; |
281 | 1.47k | CPLStringList aosHDR; |
282 | | |
283 | | // default raster file: same name with no extension |
284 | 1.47k | const CPLString osPath = CPLGetPathSafe(poOpenInfo->pszFilename); |
285 | 1.47k | const CPLString osName = CPLGetBasenameSafe(poOpenInfo->pszFilename); |
286 | 1.47k | CPLString osRasterFilename = CPLFormCIFilenameSafe(osPath, osName, ""); |
287 | | |
288 | | // parse the header file |
289 | 1.47k | const char *pszLine = nullptr; |
290 | 1.47k | VSIRewindL(poOpenInfo->fpL); |
291 | 3.43k | while ((pszLine = CPLReadLineL(poOpenInfo->fpL)) != nullptr) |
292 | 3.40k | { |
293 | 3.40k | nLineCount++; |
294 | | |
295 | 3.40k | if ((nLineCount == 1) && !EQUAL(pszLine, "IMAGINE_RAW_FILE")) |
296 | 1.40k | { |
297 | 1.40k | return nullptr; |
298 | 1.40k | } |
299 | | |
300 | 1.99k | if ((nLineCount > 50) || EQUAL(pszLine, "END_RAW_FILE")) |
301 | 28 | { |
302 | 28 | break; |
303 | 28 | } |
304 | | |
305 | 1.96k | if (strlen(pszLine) > 1000) |
306 | 3 | break; |
307 | | |
308 | 1.96k | aosHDR.AddString(pszLine); |
309 | | |
310 | 1.96k | const CPLStringList aosTokens( |
311 | 1.96k | CSLTokenizeStringComplex(pszLine, " \t", TRUE, FALSE)); |
312 | 1.96k | if (aosTokens.size() < 2) |
313 | 1.35k | { |
314 | 1.35k | continue; |
315 | 1.35k | } |
316 | | |
317 | 610 | if (EQUAL(aosTokens[0], "WIDTH")) |
318 | 1 | { |
319 | 1 | nCols = atoi(aosTokens[1]); |
320 | 1 | } |
321 | 609 | else if (EQUAL(aosTokens[0], "HEIGHT")) |
322 | 2 | { |
323 | 2 | nRows = atoi(aosTokens[1]); |
324 | 2 | } |
325 | 607 | else if (EQUAL(aosTokens[0], "NUM_LAYERS")) |
326 | 2 | { |
327 | 2 | nBands = atoi(aosTokens[1]); |
328 | 2 | } |
329 | 605 | else if (EQUAL(aosTokens[0], "PIXEL_FILES")) |
330 | 1 | { |
331 | 1 | if (CPLHasPathTraversal(aosTokens[1])) |
332 | 0 | { |
333 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
334 | 0 | "Path traversal detected in %s", aosTokens[1]); |
335 | 0 | return nullptr; |
336 | 0 | } |
337 | 1 | osRasterFilename = CPLFormCIFilenameSafe(osPath, aosTokens[1], ""); |
338 | 1 | } |
339 | 604 | else if (EQUAL(aosTokens[0], "FORMAT")) |
340 | 0 | { |
341 | 0 | snprintf(szLayout, sizeof(szLayout), "%s", aosTokens[1]); |
342 | 0 | } |
343 | 604 | else if (EQUAL(aosTokens[0], "DATATYPE") || |
344 | 603 | EQUAL(aosTokens[0], "DATA_TYPE")) |
345 | 1 | { |
346 | 1 | if (EQUAL(aosTokens[1], "U1") || EQUAL(aosTokens[1], "U2") || |
347 | 1 | EQUAL(aosTokens[1], "U4") || EQUAL(aosTokens[1], "U8")) |
348 | 1 | { |
349 | 1 | nBits = 8; |
350 | 1 | eDataType = GDT_UInt8; |
351 | 1 | } |
352 | 0 | else if (EQUAL(aosTokens[1], "U16")) |
353 | 0 | { |
354 | 0 | nBits = 16; |
355 | 0 | eDataType = GDT_UInt16; |
356 | 0 | } |
357 | 0 | else if (EQUAL(aosTokens[1], "U32")) |
358 | 0 | { |
359 | 0 | nBits = 32; |
360 | 0 | eDataType = GDT_UInt32; |
361 | 0 | } |
362 | 0 | else if (EQUAL(aosTokens[1], "S16")) |
363 | 0 | { |
364 | 0 | nBits = 16; |
365 | 0 | eDataType = GDT_Int16; |
366 | 0 | } |
367 | 0 | else if (EQUAL(aosTokens[1], "S32")) |
368 | 0 | { |
369 | 0 | nBits = 32; |
370 | 0 | eDataType = GDT_Int32; |
371 | 0 | } |
372 | 0 | else if (EQUAL(aosTokens[1], "F32")) |
373 | 0 | { |
374 | 0 | nBits = 32; |
375 | 0 | eDataType = GDT_Float32; |
376 | 0 | } |
377 | 0 | else if (EQUAL(aosTokens[1], "F64")) |
378 | 0 | { |
379 | 0 | nBits = 64; |
380 | 0 | eDataType = GDT_Float64; |
381 | 0 | } |
382 | 0 | else |
383 | 0 | { |
384 | 0 | CPLError(CE_Failure, CPLE_NotSupported, |
385 | 0 | "EIR driver does not support DATATYPE %s.", |
386 | 0 | aosTokens[1]); |
387 | 0 | return nullptr; |
388 | 0 | } |
389 | 1 | } |
390 | 603 | else if (EQUAL(aosTokens[0], "BYTE_ORDER")) |
391 | 0 | { |
392 | | // M for MSB, L for LSB |
393 | 0 | chByteOrder = static_cast<char>( |
394 | 0 | toupper(static_cast<unsigned char>(aosTokens[1][0]))); |
395 | 0 | } |
396 | 603 | else if (EQUAL(aosTokens[0], "DATA_OFFSET")) |
397 | 1 | { |
398 | 1 | nSkipBytes = atoi(aosTokens[1]); // TBD: is this mapping right? |
399 | 1 | if (nSkipBytes < 0) |
400 | 0 | { |
401 | 0 | return nullptr; |
402 | 0 | } |
403 | 1 | } |
404 | 610 | } |
405 | 67 | CPL_IGNORE_RET_VAL(nBits); |
406 | | |
407 | | /* -------------------------------------------------------------------- */ |
408 | | /* Did we get the required keywords? If not we return with */ |
409 | | /* this never having been considered to be a match. This isn't */ |
410 | | /* an error! */ |
411 | | /* -------------------------------------------------------------------- */ |
412 | 67 | if (nRows <= 0 || nCols <= 0 || nBands <= 0) |
413 | 66 | { |
414 | 66 | return nullptr; |
415 | 66 | } |
416 | | |
417 | 1 | if (!GDALCheckDatasetDimensions(nCols, nRows) || |
418 | 1 | !GDALCheckBandCount(nBands, FALSE)) |
419 | 0 | { |
420 | 0 | return nullptr; |
421 | 0 | } |
422 | | |
423 | | /* -------------------------------------------------------------------- */ |
424 | | /* Confirm the requested access is supported. */ |
425 | | /* -------------------------------------------------------------------- */ |
426 | 1 | if (poOpenInfo->eAccess == GA_Update) |
427 | 0 | { |
428 | 0 | ReportUpdateNotSupportedByDriver("EIR"); |
429 | 0 | return nullptr; |
430 | 0 | } |
431 | | /* -------------------------------------------------------------------- */ |
432 | | /* Create a corresponding GDALDataset. */ |
433 | | /* -------------------------------------------------------------------- */ |
434 | 1 | auto poDS = std::make_unique<EIRDataset>(); |
435 | | |
436 | | /* -------------------------------------------------------------------- */ |
437 | | /* Capture some information from the file that is of interest. */ |
438 | | /* -------------------------------------------------------------------- */ |
439 | 1 | poDS->nRasterXSize = nCols; |
440 | 1 | poDS->nRasterYSize = nRows; |
441 | 1 | poDS->aosHDR = std::move(aosHDR); |
442 | | |
443 | | /* -------------------------------------------------------------------- */ |
444 | | /* Open target binary file. */ |
445 | | /* -------------------------------------------------------------------- */ |
446 | 1 | poDS->fpImage = VSIFOpenL(osRasterFilename.c_str(), "rb"); |
447 | 1 | if (poDS->fpImage == nullptr) |
448 | 0 | { |
449 | 0 | CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open %s: %s", |
450 | 0 | osRasterFilename.c_str(), VSIStrerror(errno)); |
451 | 0 | return nullptr; |
452 | 0 | } |
453 | 1 | poDS->papszExtraFiles = |
454 | 1 | CSLAddString(poDS->papszExtraFiles, osRasterFilename); |
455 | | |
456 | 1 | poDS->eAccess = poOpenInfo->eAccess; |
457 | | |
458 | | /* -------------------------------------------------------------------- */ |
459 | | /* Compute the line offset. */ |
460 | | /* -------------------------------------------------------------------- */ |
461 | 1 | const int nItemSize = GDALGetDataTypeSizeBytes(eDataType); |
462 | 1 | int nPixelOffset = 0; |
463 | 1 | int nLineOffset = 0; |
464 | 1 | vsi_l_offset nBandOffset = 0; |
465 | | |
466 | 1 | if (EQUAL(szLayout, "BIP")) |
467 | 0 | { |
468 | 0 | nPixelOffset = nItemSize * nBands; |
469 | 0 | if (nPixelOffset > INT_MAX / nCols) |
470 | 0 | { |
471 | 0 | return nullptr; |
472 | 0 | } |
473 | 0 | nLineOffset = nPixelOffset * nCols; |
474 | 0 | nBandOffset = static_cast<vsi_l_offset>(nItemSize); |
475 | 0 | } |
476 | 1 | else if (EQUAL(szLayout, "BSQ")) |
477 | 0 | { |
478 | 0 | nPixelOffset = nItemSize; |
479 | 0 | if (nPixelOffset > INT_MAX / nCols) |
480 | 0 | { |
481 | 0 | return nullptr; |
482 | 0 | } |
483 | 0 | nLineOffset = nPixelOffset * nCols; |
484 | 0 | nBandOffset = static_cast<vsi_l_offset>(nLineOffset) * nRows; |
485 | 0 | } |
486 | 1 | else /* assume BIL */ |
487 | 1 | { |
488 | 1 | nPixelOffset = nItemSize; |
489 | 1 | if (nItemSize > INT_MAX / nBands || |
490 | 1 | nItemSize * nBands > INT_MAX / nCols) |
491 | 0 | { |
492 | 0 | return nullptr; |
493 | 0 | } |
494 | 1 | nLineOffset = nItemSize * nBands * nCols; |
495 | 1 | nBandOffset = static_cast<vsi_l_offset>(nItemSize) * nCols; |
496 | 1 | } |
497 | | |
498 | 1 | if (poDS->nBands > 1) |
499 | 0 | { |
500 | 0 | if (nBandOffset > |
501 | 0 | std::numeric_limits<vsi_l_offset>::max() / (poDS->nBands - 1) || |
502 | 0 | static_cast<vsi_l_offset>(nSkipBytes) > |
503 | 0 | std::numeric_limits<vsi_l_offset>::max() - |
504 | 0 | nBandOffset * (poDS->nBands - 1)) |
505 | 0 | { |
506 | 0 | return nullptr; |
507 | 0 | } |
508 | 0 | } |
509 | | |
510 | 1 | if (!RAWDatasetCheckMemoryUsage( |
511 | 1 | poDS->nRasterXSize, poDS->nRasterYSize, nBands, nItemSize, |
512 | 1 | nPixelOffset, nLineOffset, nSkipBytes, nBandOffset, poDS->fpImage)) |
513 | 0 | { |
514 | 0 | return nullptr; |
515 | 0 | } |
516 | | |
517 | 1 | poDS->SetDescription(poOpenInfo->pszFilename); |
518 | 1 | poDS->PamInitialize(); |
519 | | |
520 | | /* -------------------------------------------------------------------- */ |
521 | | /* Create band information objects. */ |
522 | | /* -------------------------------------------------------------------- */ |
523 | 2 | for (int i = 0; i < nBands; i++) |
524 | 1 | { |
525 | 1 | auto poBand = RawRasterBand::Create( |
526 | 1 | poDS.get(), i + 1, poDS->fpImage, nSkipBytes + nBandOffset * i, |
527 | 1 | nPixelOffset, nLineOffset, eDataType, |
528 | 1 | chByteOrder == 'I' || chByteOrder == 'L' |
529 | 1 | ? RawRasterBand::ByteOrder::ORDER_LITTLE_ENDIAN |
530 | 1 | : RawRasterBand::ByteOrder::ORDER_BIG_ENDIAN, |
531 | 1 | RawRasterBand::OwnFP::NO); |
532 | 1 | if (!poBand) |
533 | 0 | return nullptr; |
534 | 1 | poDS->SetBand(i + 1, std::move(poBand)); |
535 | 1 | } |
536 | | |
537 | | /* -------------------------------------------------------------------- */ |
538 | | /* look for a worldfile */ |
539 | | /* -------------------------------------------------------------------- */ |
540 | | |
541 | 1 | if (!poDS->bGotTransform) |
542 | 1 | poDS->bGotTransform = CPL_TO_BOOL(GDALReadWorldFile( |
543 | 1 | poOpenInfo->pszFilename, nullptr, poDS->m_gt.data())); |
544 | | |
545 | 1 | if (!poDS->bGotTransform) |
546 | 1 | poDS->bGotTransform = CPL_TO_BOOL(GDALReadWorldFile( |
547 | 1 | poOpenInfo->pszFilename, "wld", poDS->m_gt.data())); |
548 | | |
549 | | /* -------------------------------------------------------------------- */ |
550 | | /* Initialize any PAM information. */ |
551 | | /* -------------------------------------------------------------------- */ |
552 | 1 | poDS->TryLoadXML(); |
553 | | |
554 | | /* -------------------------------------------------------------------- */ |
555 | | /* Check for overviews. */ |
556 | | /* -------------------------------------------------------------------- */ |
557 | 1 | poDS->oOvManager.Initialize(poDS.get(), poOpenInfo->pszFilename); |
558 | | |
559 | 1 | return poDS.release(); |
560 | 1 | } |
561 | | |
562 | | /************************************************************************/ |
563 | | /* GDALRegister_EIR() */ |
564 | | /************************************************************************/ |
565 | | |
566 | | void GDALRegister_EIR() |
567 | | |
568 | 22 | { |
569 | 22 | if (GDALGetDriverByName("EIR") != nullptr) |
570 | 0 | return; |
571 | | |
572 | 22 | GDALDriver *poDriver = new GDALDriver(); |
573 | | |
574 | 22 | poDriver->SetDescription("EIR"); |
575 | 22 | poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); |
576 | 22 | poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Erdas Imagine Raw"); |
577 | 22 | poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/eir.html"); |
578 | 22 | poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); |
579 | | |
580 | 22 | poDriver->pfnOpen = EIRDataset::Open; |
581 | 22 | poDriver->pfnIdentify = EIRDataset::Identify; |
582 | | |
583 | 22 | GetGDALDriverManager()->RegisterDriver(poDriver); |
584 | 22 | } |