Skip to content

Commit

Permalink
MRF: implement deferred driver loading
Browse files Browse the repository at this point in the history
  • Loading branch information
rouault committed Nov 11, 2023
1 parent 481874a commit 864f289
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 54 deletions.
3 changes: 3 additions & 0 deletions frmts/gdalallregister.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,9 @@ void CPL_STDCALL GDALAllRegister()
#if defined(DEFERRED_MONGODBV3_DRIVER)
DeclareDeferredOGRMongoDBv3Plugin();
#endif
#if defined(DEFERRED_MRF_DRIVER)
DeclareDeferredMRFPlugin();
#endif
#if defined(DEFERRED_MRSID_DRIVER)
DeclareDeferredMrSIDPlugin();
#endif
Expand Down
13 changes: 13 additions & 0 deletions frmts/mrf/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,22 @@ add_gdal_driver(
Packer_RLE.cpp
Packer_RLE.h
Tif_band.cpp
CORE_SOURCES
mrfdrivercore.cpp
PLUGIN_CAPABLE_IF
"NOT GDAL_USE_JPEG_INTERNAL;NOT GDAL_USE_JPEG12_INTERNAL;NOT GDAL_USE_LERC_INTERNAL;NOT GDAL_USE_PNG_INTERNAL;NOT GDAL_USE_TIFF_INTERNAL;NOT GDAL_USE_ZLIB_INTERNAL"
)

if(TARGET gdal_MRF_core)
if (GDAL_USE_LERC OR GDAL_USE_LERC_INTERNAL)
target_compile_definitions(gdal_MRF_core PRIVATE -DLERC)
endif()
endif()

if(NOT TARGET gdal_MRF)
return()
endif()

gdal_standard_includes(gdal_MRF)

if (GDAL_USE_JPEG OR GDAL_USE_JPEG_INTERNAL)
Expand Down
1 change: 0 additions & 1 deletion frmts/mrf/marfa.h
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,6 @@ class MRFDataset final : public GDALPamDataset
virtual ~MRFDataset();

static GDALDataset *Open(GDALOpenInfo *);
static int Identify(GDALOpenInfo *);

static GDALDataset *CreateCopy(const char *pszFilename,
GDALDataset *poSrcDS, int bStrict,
Expand Down
34 changes: 2 additions & 32 deletions frmts/mrf/marfa_dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
****************************************************************************/

#include "marfa.h"
#include "mrfdrivercore.h"
#include "cpl_multiproc.h" /* for CPLSleep() */
#include "gdal_priv.h"
#include <assert.h>
Expand Down Expand Up @@ -519,37 +520,6 @@ void MRFDataset::SetMaxValue(const char *pszVal)
list2vec(vMax, pszVal);
}

/**
*\brief Idenfity a MRF file, lightweight
*
* Lightweight test, otherwise Open gets called.
*
*/
int MRFDataset::Identify(GDALOpenInfo *poOpenInfo)
{
if (STARTS_WITH(poOpenInfo->pszFilename, "<MRF_META>"))
return TRUE;

CPLString fn(poOpenInfo->pszFilename);
if (fn.find(":MRF:") != string::npos)
return TRUE;

if (poOpenInfo->nHeaderBytes < 10)
return FALSE;

const char *pszHeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader);
fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes);
if (STARTS_WITH(fn, "<MRF_META>"))
return TRUE;

#if defined(LERC) // Could be single LERC tile
if (LERC_Band::IsLerc1(fn) || LERC_Band::IsLerc2(fn))
return TRUE;
#endif

return FALSE;
}

/**
*
*\brief Read the XML config tree, from file
Expand Down Expand Up @@ -615,7 +585,7 @@ static int getnum(const vector<string> &theStringVector, const char prefix,
*/
GDALDataset *MRFDataset::Open(GDALOpenInfo *poOpenInfo)
{
if (!Identify(poOpenInfo))
if (!MRFDriverIdentify(poOpenInfo))
return nullptr;

CPLXMLNode *config = nullptr;
Expand Down
24 changes: 3 additions & 21 deletions frmts/mrf/mrf_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <zlib.h>
#include <algorithm>
#include <limits>
#include "mrfdrivercore.h"

// LERC and QB3 only work on little endian machines
#if defined(WORDS_BIGENDIAN)
Expand Down Expand Up @@ -582,20 +583,11 @@ USING_NAMESPACE_MRF

void GDALRegister_mrf()
{
if (GDALGetDriverByName("MRF") != nullptr)
if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
return;

GDALDriver *driver = new GDALDriver();
driver->SetDescription("MRF");
driver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format");
driver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html");
driver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf");
driver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
driver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");

// These will need to be revisited, do we support complex data types too?
driver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES,
"Byte UInt16 Int16 Int32 UInt32 Float32 Float64");
MRFDriverSetCommonMetadata(driver);

driver->SetMetadataItem(
GDAL_DMD_CREATIONOPTIONLIST,
Expand Down Expand Up @@ -694,17 +686,7 @@ void GDALRegister_mrf()
"'/>"
"</CreationOptionList>\n");

driver->SetMetadataItem(
GDAL_DMD_OPENOPTIONLIST,
"<OpenOptionList>"
" <Option name='NOERRORS' type='boolean' description='Ignore "
"decompression errors' default='FALSE'/>"
" <Option name='ZSLICE' type='int' description='For a third "
"dimension MRF, pick a slice' default='0'/>"
"</OpenOptionList>");

driver->pfnOpen = MRFDataset::Open;
driver->pfnIdentify = MRFDataset::Identify;
driver->pfnCreateCopy = MRFDataset::CreateCopy;
driver->pfnCreate = MRFDataset::Create;
driver->pfnDelete = MRFDataset::Delete;
Expand Down
149 changes: 149 additions & 0 deletions frmts/mrf/mrfdrivercore.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
* Copyright (c) 2002-2012, California Institute of Technology.
* All rights reserved. Based on Government Sponsored Research under contracts
* NAS7-1407 and/or NAS7-03001.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the California Institute of Technology (Caltech),
* its operating division the Jet Propulsion Laboratory (JPL), the National
* Aeronautics and Space Administration (NASA), nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2014-2021 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Functions used by the driver, should have prototypes in the header file
*
* Author: Lucian Plesea
*/

#include "mrfdrivercore.h"
#include "cpl_string.h"

#if defined(LERC)
static bool IsLerc1(const char *s)
{
static const char L1sig[] = "CntZImage ";
return !strncmp(s, L1sig, sizeof(L1sig) - 1);
}
static bool IsLerc2(const char *s)
{
static const char L2sig[] = "Lerc2 ";
return !strncmp(s, L2sig, sizeof(L2sig) - 1);
}
#endif

/************************************************************************/
/* MRFDriverIdentify() */
/************************************************************************/

/**
*\brief Idenfity a MRF file, lightweight
*
* Lightweight test, otherwise Open gets called.
*
*/
int MRFDriverIdentify(GDALOpenInfo *poOpenInfo)

{
if (STARTS_WITH(poOpenInfo->pszFilename, "<MRF_META>"))
return TRUE;

CPLString fn(poOpenInfo->pszFilename);
if (fn.find(":MRF:") != std::string::npos)
return TRUE;

if (poOpenInfo->nHeaderBytes < 10)
return FALSE;

const char *pszHeader = reinterpret_cast<char *>(poOpenInfo->pabyHeader);
fn.assign(pszHeader, pszHeader + poOpenInfo->nHeaderBytes);
if (STARTS_WITH(fn, "<MRF_META>"))
return TRUE;

#if defined(LERC) // Could be single LERC tile
if (IsLerc1(fn) || IsLerc2(fn))
return TRUE;
#endif

return FALSE;
}

/************************************************************************/
/* MRFDriverSetCommonMetadata() */
/************************************************************************/

void MRFDriverSetCommonMetadata(GDALDriver *poDriver)
{
poDriver->SetDescription(DRIVER_NAME);
poDriver->SetMetadataItem(GDAL_DMD_LONGNAME, "Meta Raster Format");
poDriver->SetMetadataItem(GDAL_DMD_HELPTOPIC, "drivers/raster/marfa.html");
poDriver->SetMetadataItem(GDAL_DMD_EXTENSION, "mrf");
poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");
poDriver->SetMetadataItem(GDAL_DCAP_RASTER, "YES");

poDriver->SetMetadataItem(
GDAL_DMD_OPENOPTIONLIST,
"<OpenOptionList>"
" <Option name='NOERRORS' type='boolean' description='Ignore "
"decompression errors' default='FALSE'/>"
" <Option name='ZSLICE' type='int' description='For a third "
"dimension MRF, pick a slice' default='0'/>"
"</OpenOptionList>");

// These will need to be revisited, do we support complex data types too?
poDriver->SetMetadataItem(GDAL_DMD_CREATIONDATATYPES,
"Byte UInt16 Int16 Int32 UInt32 Float32 Float64");

poDriver->pfnIdentify = MRFDriverIdentify;
poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
poDriver->SetMetadataItem(GDAL_DCAP_CREATECOPY, "YES");
}

/************************************************************************/
/* DeclareDeferredMRFPlugin() */
/************************************************************************/

#ifdef PLUGIN_FILENAME
void DeclareDeferredMRFPlugin()
{
if (GDALGetDriverByName(DRIVER_NAME) != nullptr)
{
return;
}
auto poDriver = new GDALPluginDriverProxy(PLUGIN_FILENAME);
MRFDriverSetCommonMetadata(poDriver);
GetGDALDriverManager()->DeclareDeferredPluginDriver(poDriver);
}
#endif
61 changes: 61 additions & 0 deletions frmts/mrf/mrfdrivercore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2002-2012, California Institute of Technology.
* All rights reserved. Based on Government Sponsored Research under contracts
* NAS7-1407 and/or NAS7-03001.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the California Institute of Technology (Caltech),
* its operating division the Jet Propulsion Laboratory (JPL), the National
* Aeronautics and Space Administration (NASA), nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE CALIFORNIA INSTITUTE OF TECHNOLOGY BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2014-2021 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Functions used by the driver, should have prototypes in the header file
*
* Author: Lucian Plesea
*/

#ifndef MRFDRIVERCORE_H
#define MRFDRIVERCORE_H

#include "gdal_priv.h"

constexpr const char *DRIVER_NAME = "MRF";

int CPL_DLL MRFDriverIdentify(GDALOpenInfo *poOpenInfo);

void CPL_DLL MRFDriverSetCommonMetadata(GDALDriver *poDriver);

#endif
1 change: 1 addition & 0 deletions gcore/gdal_frmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ void CPL_DLL GDALRegister_WMTS(void);
void CPL_DLL GDALRegister_SAFE(void);
void CPL_DLL GDALRegister_SENTINEL2(void);
void CPL_DLL GDALRegister_mrf(void);
void DeclareDeferredMRFPlugin(void);
void CPL_DLL GDALRegister_RRASTER(void);
void CPL_DLL GDALRegister_Derived(void);
void CPL_DLL GDALRegister_JP2Lura(void);
Expand Down

0 comments on commit 864f289

Please sign in to comment.