Skip to content

Commit 0823069

Browse files
authored
Merge pull request OSGeo#13030 from rouault/fix_13025
WEBP: add read and creation support for .wld worldfiles
2 parents dc43114 + 7d60f79 commit 0823069

32 files changed

+130
-31
lines changed

autotest/gdrivers/webp.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,23 @@ def my_callback(pct, msg, user_data):
202202

203203
with gdal.Open(out_filename) as ds:
204204
ds.GetRasterBand(1).Checksum()
205+
206+
207+
###############################################################################
208+
209+
210+
def test_webp_world_file(tmp_vsimem):
211+
212+
src_ds = gdal.Open("data/rgbsmall.tif")
213+
214+
drv = gdal.GetDriverByName("WEBP")
215+
drv.CreateCopy(tmp_vsimem / "out.webp", src_ds, options={"WORLDFILE": "YES"})
216+
assert gdal.VSIStatL(tmp_vsimem / "out.wld") is not None
217+
gdal.Unlink(tmp_vsimem / "out.webp.aux.xml")
218+
with gdal.Open(tmp_vsimem / "out.webp") as ds:
219+
assert ds.GetGeoTransform() == pytest.approx(src_ds.GetGeoTransform())
220+
with gdal.Open(tmp_vsimem / "out.webp") as ds:
221+
assert ds.GetFileList() == [
222+
str(tmp_vsimem / "out.webp"),
223+
str(tmp_vsimem / "out.wld"),
224+
]

doc/source/drivers/raster/jpeg.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ to the JPEG file.
166166
The following creation options are supported:
167167

168168
- .. co:: WORLDFILE
169-
:choices: YES
169+
:choices: YES,NO
170+
:default: NO
170171

171172
Force the generation of an associated ESRI world
172173
file (with the extension .wld). See :ref:`World Files <raster.wld>`

doc/source/drivers/raster/webp.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ The WEBP driver supports 3 bands (RGB) images. It also supports 4 bands (RGBA)
2525
XMP metadata can be extracted from the file,
2626
and will be stored as XML raw content in the xml:XMP metadata domain.
2727

28+
Since 3.12, if an ESRI :ref:`world file <raster.wld>` exists with the
29+
``.webpw`` or ``.wld`` suffixes, it will be read and used to establish the
30+
geotransform for the image.
31+
2832
Driver capabilities
2933
-------------------
3034

@@ -65,6 +69,15 @@ Various creation options exists, among them :
6569
compression, the regular conversion code path is taken, resulting in a
6670
lossless or lossy copy depending on the LOSSLESS setting.
6771

72+
- .. co:: WORLDFILE
73+
:choices: YES,NO
74+
:default: NO
75+
:since: 3.12
76+
77+
Force the generation of an associated ESRI world
78+
file (with the extension ``.wld``). See :ref:`World Files <raster.wld>`
79+
section for details.
80+
6881
See Also
6982
--------
7083

frmts/webp/webpdataset.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@ class WEBPDataset final : public GDALPamDataset
4242

4343
CPL_DISALLOW_COPY_ASSIGN(WEBPDataset)
4444

45+
CPLErr GetGeoTransform(GDALGeoTransform &gt,
46+
std::string &osWorldFilename) const;
47+
4548
public:
4649
WEBPDataset();
4750
~WEBPDataset() override;
4851

52+
char **GetFileList() override;
53+
54+
CPLErr GetGeoTransform(GDALGeoTransform &gt) const override;
4955
CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
5056
GDALDataType, int, BANDMAP_TYPE, GSpacing nPixelSpace,
5157
GSpacing nLineSpace, GSpacing nBandSpace,
@@ -173,6 +179,54 @@ WEBPDataset::~WEBPDataset()
173179
VSIFree(pabyUncompressed);
174180
}
175181

182+
/************************************************************************/
183+
/* GetFileList() */
184+
/************************************************************************/
185+
186+
char **WEBPDataset::GetFileList()
187+
{
188+
char **papszFileList = GDALPamDataset::GetFileList();
189+
GDALGeoTransform gt;
190+
std::string osWorldFilename;
191+
CPL_IGNORE_RET_VAL(GetGeoTransform(gt, osWorldFilename));
192+
if (!osWorldFilename.empty())
193+
{
194+
papszFileList = CSLAddString(papszFileList, osWorldFilename.c_str());
195+
}
196+
return papszFileList;
197+
}
198+
199+
/************************************************************************/
200+
/* GetGeoTransform() */
201+
/************************************************************************/
202+
203+
CPLErr WEBPDataset::GetGeoTransform(GDALGeoTransform &gt) const
204+
{
205+
std::string osWorldFilename;
206+
return GetGeoTransform(gt, osWorldFilename);
207+
}
208+
209+
CPLErr WEBPDataset::GetGeoTransform(GDALGeoTransform &gt,
210+
std::string &osWorldFilename) const
211+
{
212+
bool bGeoTransformValid = GDALPamDataset::GetGeoTransform(gt) == CE_None;
213+
if (!bGeoTransformValid)
214+
{
215+
char *pszWldFilename = nullptr;
216+
bGeoTransformValid =
217+
GDALReadWorldFile2(GetDescription(), ".wld", gt,
218+
oOvManager.GetSiblingFiles(), &pszWldFilename) ||
219+
GDALReadWorldFile2(GetDescription(), ".wpw", gt,
220+
oOvManager.GetSiblingFiles(), &pszWldFilename) ||
221+
GDALReadWorldFile2(GetDescription(), ".webpw", gt,
222+
oOvManager.GetSiblingFiles(), &pszWldFilename);
223+
if (bGeoTransformValid)
224+
osWorldFilename = pszWldFilename;
225+
CPLFree(pszWldFilename);
226+
}
227+
return bGeoTransformValid ? CE_None : CE_Failure;
228+
}
229+
176230
/************************************************************************/
177231
/* GetMetadataDomainList() */
178232
/************************************************************************/
@@ -1083,6 +1137,14 @@ GDALDataset *WEBPDataset::CreateCopy(const char *pszFilename,
10831137
return nullptr;
10841138
}
10851139

1140+
// Do we need a world file?
1141+
if (CPLFetchBool(papszOptions, "WORLDFILE", false))
1142+
{
1143+
GDALGeoTransform gt;
1144+
poSrcDS->GetGeoTransform(gt);
1145+
GDALWriteWorldFile(pszFilename, "wld", gt.data());
1146+
}
1147+
10861148
/* -------------------------------------------------------------------- */
10871149
/* Re-open dataset, and copy any auxiliary pam information. */
10881150
/* -------------------------------------------------------------------- */

frmts/webp/webpdrivercore.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ void WEBPDriverSetCommonMetadata(GDALDriver *poDriver)
104104
" <Option name='EXACT' type='int' description='preserve the exact "
105105
"RGB values under transparent area. off=0, on=1' default='0'/>\n"
106106
#endif
107+
"<Option name='WORLDFILE' type='boolean' description='whether "
108+
"to generate a worldfile' default='NO'/>\n"
107109
"</CreationOptionList>\n");
108110

109111
poDriver->SetMetadataItem(GDAL_DCAP_VIRTUALIO, "YES");

gcore/gdal_mdreader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ GDALMDReaderManager::~GDALMDReaderManager()
9090
delete pReaderBase
9191

9292
GDALMDReaderBase *GDALMDReaderManager::GetReader(const char *pszPath,
93-
char **papszSiblingFiles,
93+
CSLConstList papszSiblingFiles,
9494
GUInt32 nType)
9595
{
9696
if (!GDALCanFileAcceptSidecarFile(pszPath))
@@ -160,7 +160,7 @@ GDALMDReaderBase *GDALMDReaderManager::GetReader(const char *pszPath,
160160
* GDALMDReaderBase()
161161
*/
162162
GDALMDReaderBase::GDALMDReaderBase(const char * /* pszPath */,
163-
char ** /* papszSiblingFiles */)
163+
CSLConstList /* papszSiblingFiles */)
164164
{
165165
}
166166

gcore/gdal_mdreader.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class CPL_DLL GDALMDReaderBase
116116
const std::string &osPrefixFull);
117117

118118
public:
119-
GDALMDReaderBase(const char *pszPath, char **papszSiblingFiles);
119+
GDALMDReaderBase(const char *pszPath, CSLConstList papszSiblingFiles);
120120
virtual ~GDALMDReaderBase();
121121

122122
/**
@@ -214,7 +214,7 @@ class CPL_DLL GDALMDReaderManager
214214
* delete it.
215215
*/
216216
virtual GDALMDReaderBase *GetReader(const char *pszPath,
217-
char **papszSiblingFiles,
217+
CSLConstList papszSiblingFiles,
218218
GUInt32 nType = MDR_ANY);
219219

220220
protected:

gcore/gdal_priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ class CPL_DLL GDALDefaultOverviews
311311
int HaveMaskFile(char **papszSiblings = nullptr,
312312
const char *pszBasename = nullptr);
313313

314-
char **GetSiblingFiles()
314+
CSLConstList GetSiblingFiles() const
315315
{
316316
return papszInitSiblingFiles;
317317
}

gcore/mdreader/reader_alos.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* GDALMDReaderALOS()
2929
*/
3030
GDALMDReaderALOS::GDALMDReaderALOS(const char *pszPath,
31-
char **papszSiblingFiles)
31+
CSLConstList papszSiblingFiles)
3232
: GDALMDReaderBase(pszPath, papszSiblingFiles)
3333
{
3434
const CPLString osDirName = CPLGetDirnameSafe(pszPath);

gcore/mdreader/reader_alos.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Common metadata (from metadata filename):
3434
class GDALMDReaderALOS final : public GDALMDReaderBase
3535
{
3636
public:
37-
GDALMDReaderALOS(const char *pszPath, char **papszSiblingFiles);
37+
GDALMDReaderALOS(const char *pszPath, CSLConstList papszSiblingFiles);
3838
~GDALMDReaderALOS() override;
3939
bool HasRequiredFiles() const override;
4040
char **GetMetadataFiles() const override;

0 commit comments

Comments
 (0)