/src/gdal/frmts/mrf/mrfdrivercore.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2002-2012, California Institute of Technology. |
3 | | * All rights reserved. Based on Government Sponsored Research under contracts |
4 | | * NAS7-1407 and/or NAS7-03001. |
5 | | * |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions are met: |
8 | | * 1. Redistributions of source code must retain the above copyright notice, |
9 | | * this list of conditions and the following disclaimer. |
10 | | * 2. Redistributions in binary form must reproduce the above copyright |
11 | | * notice, this list of conditions and the following disclaimer in the |
12 | | * documentation and/or other materials provided with the distribution. |
13 | | * 3. Neither the name of the California Institute of Technology (Caltech), |
14 | | * its operating division the Jet Propulsion Laboratory (JPL), the National |
15 | | * Aeronautics and Space Administration (NASA), nor the names of its |
16 | | * contributors may be used to endorse or promote products derived from this |
17 | | * software without specific prior written permission. |
18 | | * |
19 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
20 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
21 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE |
23 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
24 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
25 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
27 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
28 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
29 | | * POSSIBILITY OF SUCH DAMAGE. |
30 | | * |
31 | | * Copyright 2014-2021 Esri |
32 | | * |
33 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
34 | | * you may not use this file except in compliance with the License. |
35 | | * You may obtain a copy of the License at |
36 | | * |
37 | | * http://www.apache.org/licenses/LICENSE-2.0 |
38 | | * |
39 | | * Unless required by applicable law or agreed to in writing, software |
40 | | * distributed under the License is distributed on an "AS IS" BASIS, |
41 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
42 | | * See the License for the specific language governing permissions and |
43 | | * limitations under the License. |
44 | | * |
45 | | * Functions used by the driver, should have prototypes in the header file |
46 | | * |
47 | | * Author: Lucian Plesea |
48 | | */ |
49 | | |
50 | | #include "gdal_frmts.h" |
51 | | #include "gdalplugindriverproxy.h" |
52 | | |
53 | | #include "mrfdrivercore.h" |
54 | | #include "cpl_string.h" |
55 | | |
56 | | #if defined(LERC) |
57 | | static bool IsLerc1(const char *s) |
58 | 82.4k | { |
59 | 82.4k | static const char L1sig[] = "CntZImage "; |
60 | 82.4k | return !strncmp(s, L1sig, sizeof(L1sig) - 1); |
61 | 82.4k | } |
62 | | |
63 | | static bool IsLerc2(const char *s) |
64 | 81.8k | { |
65 | 81.8k | static const char L2sig[] = "Lerc2 "; |
66 | 81.8k | return !strncmp(s, L2sig, sizeof(L2sig) - 1); |
67 | 81.8k | } |
68 | | #endif |
69 | | |
70 | | /************************************************************************/ |
71 | | /* MRFDriverIdentify() */ |
72 | | /************************************************************************/ |
73 | | |
74 | | /** |
75 | | *\brief Idenfity a MRF file, lightweight |
76 | | * |
77 | | * Lightweight test, otherwise Open gets called. |
78 | | * |
79 | | */ |
80 | | int MRFDriverIdentify(GDALOpenInfo *poOpenInfo) |
81 | | |
82 | 368k | { |
83 | 368k | if (STARTS_WITH(poOpenInfo->pszFilename, "<MRF_META>")) |
84 | 0 | return TRUE; |
85 | | |
86 | 368k | CPLString fn(poOpenInfo->pszFilename); |
87 | 368k | if (fn.find(":MRF:") != std::string::npos) |
88 | 384 | return TRUE; |
89 | | |
90 | 367k | if (poOpenInfo->nHeaderBytes < 10) |
91 | 269k | return FALSE; |
92 | | |
93 | 98.7k | const char *pszHeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader); |
94 | 98.7k | fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes); |
95 | 98.7k | if (STARTS_WITH(fn, "<MRF_META>")) |
96 | 16.3k | return TRUE; |
97 | | |
98 | 82.4k | #if defined(LERC) // Could be single LERC tile |
99 | 82.4k | if (IsLerc1(fn) || IsLerc2(fn)) |
100 | 7.37k | return TRUE; |
101 | 75.0k | #endif |
102 | | |
103 | | // accept a tar file if the first file has no folder look like an MRF |
104 | 75.0k | if (poOpenInfo->eAccess == GA_ReadOnly && fn.size() > 600 && |
105 | 60.9k | (fn[262] == 0 || fn[262] == 32) && STARTS_WITH(fn + 257, "ustar") && |
106 | 61 | strlen(CPLGetPathSafe(fn).c_str()) == 0 && |
107 | 57 | STARTS_WITH(fn + 512, "<MRF_META>")) |
108 | 54 | { |
109 | 54 | return TRUE; |
110 | 54 | } |
111 | | |
112 | 74.9k | return FALSE; |
113 | 75.0k | } |
114 | | |
115 | | /************************************************************************/ |
116 | | /* MRFDriverSetCommonMetadata() */ |
117 | | /************************************************************************/ |
118 | | |
119 | | void MRFDriverSetCommonMetadata(GDALDriver *poDriver) |
120 | 24 | { |
121 | 24 | poDriver->SetDescription(DRIVER_NAME); |
122 | 24 | poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format"); |
123 | 24 | poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html"); |
124 | 24 | poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf"); |
125 | 24 | poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); |
126 | 24 | poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); |
127 | | |
128 | 24 | poDriver->SetMetadataItem( |
129 | 24 | GDAL_DMD_OPENOPTIONLIST, |
130 | 24 | "<OpenOptionList>" |
131 | 24 | " <Option name='NOERRORS' type='boolean' description='Ignore " |
132 | 24 | "decompression errors' default='FALSE'/>" |
133 | 24 | " <Option name='ZSLICE' type='int' description='For a third " |
134 | 24 | "dimension MRF, pick a slice' default='0'/>" |
135 | 24 | "</OpenOptionList>"); |
136 | | |
137 | | // These will need to be revisited, do we support complex data types too? |
138 | 24 | poDriver->SetMetadataItem( |
139 | 24 | GDAL_DMD_CREATIONDATATYPES, |
140 | 24 | "Byte Int8 Int16 UInt16 Int32 UInt32 Int64 UInt64 Float32 Float64"); |
141 | | |
142 | 24 | poDriver->pfnIdentify = MRFDriverIdentify; |
143 | 24 | poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); |
144 | 24 | poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); |
145 | 24 | poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); |
146 | 24 | } |
147 | | |
148 | | /************************************************************************/ |
149 | | /* DeclareDeferredMRFPlugin() */ |
150 | | /************************************************************************/ |
151 | | |
152 | | #ifdef PLUGIN_FILENAME |
153 | | void DeclareDeferredMRFPlugin() |
154 | | { |
155 | | if (GDALGetDriverByName(DRIVER_NAME) != nullptr) |
156 | | { |
157 | | return; |
158 | | } |
159 | | auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); |
160 | | #ifdef PLUGIN_INSTALLATION_MESSAGE |
161 | | poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, |
162 | | PLUGIN_INSTALLATION_MESSAGE); |
163 | | #endif |
164 | | MRFDriverSetCommonMetadata(poDriver); |
165 | | GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); |
166 | | } |
167 | | #endif |