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(GDAL_USE_LERC_INTERNAL) 57 5633 : static bool IsLerc1(const char *s) 58 : { 59 : static const char L1sig[] = "CntZImage "; 60 5633 : return !strncmp(s, L1sig, sizeof(L1sig) - 1); 61 : } 62 : #endif 63 : 64 : /************************************************************************/ 65 : /* MRFDriverIdentify() */ 66 : /************************************************************************/ 67 : 68 : /** 69 : *\brief Identify a MRF file, lightweight 70 : * 71 : * Lightweight test, otherwise Open gets called. 72 : * 73 : */ 74 63881 : int MRFDriverIdentify(GDALOpenInfo *poOpenInfo) 75 : 76 : { 77 63881 : if (STARTS_WITH(poOpenInfo->pszFilename, "<MRF_META>")) 78 0 : return TRUE; 79 : 80 127762 : CPLString fn(poOpenInfo->pszFilename); 81 63881 : if (fn.find(":MRF:") != std::string::npos) 82 10 : return TRUE; 83 : 84 63871 : if (poOpenInfo->nHeaderBytes < 10) 85 57804 : return FALSE; 86 : 87 6067 : const char *pszHeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader); 88 6067 : fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes); 89 6067 : if (STARTS_WITH(fn, "<MRF_META>")) 90 434 : return TRUE; 91 : 92 : #if defined(GDAL_USE_LERC_INTERNAL) // Could be single LERC tile 93 5633 : if (IsLerc1(fn)) 94 8 : return TRUE; 95 : #endif 96 : 97 : // accept a tar file if the first file has no folder look like an MRF 98 5486 : if (poOpenInfo->eAccess == GA_ReadOnly && fn.size() > 600 && 99 4200 : (fn[262] == 0 || fn[262] == 32) && STARTS_WITH(fn + 257, "ustar") && 100 11113 : strlen(CPLGetPathSafe(fn).c_str()) == 0 && 101 2 : STARTS_WITH(fn + 512, "<MRF_META>")) 102 : { 103 2 : return TRUE; 104 : } 105 : 106 5623 : return FALSE; 107 : } 108 : 109 : /************************************************************************/ 110 : /* MRFDriverSetCommonMetadata() */ 111 : /************************************************************************/ 112 : 113 1869 : void MRFDriverSetCommonMetadata(GDALDriver *poDriver) 114 : { 115 1869 : poDriver->SetDescription(DRIVER_NAME); 116 1869 : poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format"); 117 1869 : poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html"); 118 1869 : poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf"); 119 1869 : poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES"); 120 1869 : poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES"); 121 : 122 1869 : poDriver->SetMetadataItem( 123 : GDAL_DMD_OPENOPTIONLIST, 124 : "<OpenOptionList>" 125 : " <Option name='NOERRORS' type='boolean' description='Ignore " 126 : "decompression errors' default='FALSE'/>" 127 : " <Option name='ZSLICE' type='int' description='For a third " 128 : "dimension MRF, pick a slice' default='0'/>" 129 1869 : "</OpenOptionList>"); 130 : 131 : // These will need to be revisited, do we support complex data types too? 132 1869 : poDriver->SetMetadataItem( 133 : GDAL_DMD_CREATIONDATATYPES, 134 1869 : "Byte Int8 Int16 UInt16 Int32 UInt32 Int64 UInt64 Float32 Float64"); 135 : 136 1869 : poDriver->pfnIdentify = MRFDriverIdentify; 137 1869 : poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES"); 138 1869 : poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES"); 139 1869 : poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES"); 140 1869 : } 141 : 142 : /************************************************************************/ 143 : /* DeclareDeferredMRFPlugin() */ 144 : /************************************************************************/ 145 : 146 : #ifdef PLUGIN_FILENAME 147 : void DeclareDeferredMRFPlugin() 148 : { 149 : if (GDALGetDriverByName(DRIVER_NAME) != nullptr) 150 : { 151 : return; 152 : } 153 : auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME); 154 : #ifdef PLUGIN_INSTALLATION_MESSAGE 155 : poDriver->SetMetadataItem(GDAL_DMD_PLUGIN_INSTALLATION_MESSAGE, 156 : PLUGIN_INSTALLATION_MESSAGE); 157 : #endif 158 : MRFDriverSetCommonMetadata(poDriver); 159 : GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver); 160 : } 161 : #endif