Coverage Report

Created: 2026-02-14 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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