Line data Source code
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 4030 : static bool IsLerc1(const char *s)
58 : {
59 : static const char L1sig[] = "CntZImage ";
60 4030 : return !strncmp(s, L1sig, sizeof(L1sig) - 1);
61 : }
62 :
63 4020 : static bool IsLerc2(const char *s)
64 : {
65 : static const char L2sig[] = "Lerc2 ";
66 4020 : return !strncmp(s, L2sig, sizeof(L2sig) - 1);
67 : }
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 59972 : int MRFDriverIdentify(GDALOpenInfo *poOpenInfo)
81 :
82 : {
83 59972 : if (STARTS_WITH(poOpenInfo->pszFilename, "<MRF_META>"))
84 0 : return TRUE;
85 :
86 119940 : CPLString fn(poOpenInfo->pszFilename);
87 59972 : if (fn.find(":MRF:") != std::string::npos)
88 10 : return TRUE;
89 :
90 59957 : if (poOpenInfo->nHeaderBytes < 10)
91 55494 : return FALSE;
92 :
93 4463 : const char *pszHeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader);
94 4463 : fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes);
95 4464 : if (STARTS_WITH(fn, "<MRF_META>"))
96 434 : return TRUE;
97 :
98 : #if defined(LERC) // Could be single LERC tile
99 4030 : if (IsLerc1(fn) || IsLerc2(fn))
100 12 : return TRUE;
101 : #endif
102 :
103 : // accept a tar file if the first file has no folder look like an MRF
104 3807 : if (poOpenInfo->eAccess == GA_ReadOnly && fn.size() > 600 &&
105 2647 : (fn[262] == 0 || fn[262] == 32) && STARTS_WITH(fn + 257, "ustar") &&
106 7827 : strlen(CPLGetPathSafe(fn).c_str()) == 0 &&
107 2 : STARTS_WITH(fn + 512, "<MRF_META>"))
108 : {
109 2 : return TRUE;
110 : }
111 :
112 4016 : return FALSE;
113 : }
114 :
115 : /************************************************************************/
116 : /* MRFDriverSetCommonMetadata() */
117 : /************************************************************************/
118 :
119 1755 : void MRFDriverSetCommonMetadata(GDALDriver *poDriver)
120 : {
121 1755 : poDriver->SetDescription(DRIVER_NAME);
122 1755 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format");
123 1755 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html");
124 1755 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf");
125 1755 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
126 1755 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");
127 :
128 1755 : poDriver->SetMetadataItem(
129 : GDAL_DMD_OPENOPTIONLIST,
130 : "<OpenOptionList>"
131 : " <Option name='NOERRORS' type='boolean' description='Ignore "
132 : "decompression errors' default='FALSE'/>"
133 : " <Option name='ZSLICE' type='int' description='For a third "
134 : "dimension MRF, pick a slice' default='0'/>"
135 1755 : "</OpenOptionList>");
136 :
137 : // These will need to be revisited, do we support complex data types too?
138 1755 : poDriver->SetMetadataItem(
139 : GDAL_DMD_CREATIONDATATYPES,
140 1755 : "Byte Int8 Int16 UInt16 Int32 UInt32 Int64 UInt64 Float32 Float64");
141 :
142 1755 : poDriver->pfnIdentify = MRFDriverIdentify;
143 1755 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
144 1755 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
145 1755 : poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
146 1755 : }
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
|