/src/gdal/frmts/wms/minidriver_iiifimage.cpp
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Project: WMS Client Driver |
4 | | * Purpose: Mini driver for International Image Interoperability Framework |
5 | | * Image API (IIIFImage) |
6 | | * Author: Even Rouault <even.rouault at spatialys.com> |
7 | | * |
8 | | ****************************************************************************** |
9 | | * Copyright (c) 2025, Even Rouault <even.rouault at spatialys.com> |
10 | | * |
11 | | * SPDX-License-Identifier: MIT |
12 | | ****************************************************************************/ |
13 | | |
14 | | #include "wmsdriver.h" |
15 | | #include "minidriver_iiifimage.h" |
16 | | |
17 | | #include <algorithm> |
18 | | |
19 | | // Implements https://iiif.io/api/image/3.0/ "Image API 3.0" |
20 | | |
21 | | WMSMiniDriver_IIIFImage::WMSMiniDriver_IIIFImage() |
22 | 0 | { |
23 | 0 | } |
24 | | |
25 | | WMSMiniDriver_IIIFImage::~WMSMiniDriver_IIIFImage() |
26 | 0 | { |
27 | 0 | } |
28 | | |
29 | | CPLErr WMSMiniDriver_IIIFImage::Initialize(CPLXMLNode *config, |
30 | | CPL_UNUSED char **papszOpenOptions) |
31 | 0 | { |
32 | 0 | m_base_url = CPLGetXMLValue(config, "ServerURL", ""); |
33 | 0 | if (m_base_url.empty()) |
34 | 0 | { |
35 | 0 | CPLError(CE_Failure, CPLE_AppDefined, |
36 | 0 | "GDALWMS, IIIFImage mini-driver: ServerURL missing."); |
37 | 0 | return CE_Failure; |
38 | 0 | } |
39 | | |
40 | 0 | const char *pszImageFormat = |
41 | 0 | CPLGetXMLValue(config, "ImageFormat", "image/jpeg"); |
42 | 0 | if (EQUAL(pszImageFormat, "image/jpeg")) |
43 | 0 | m_imageExtension = "jpg"; |
44 | 0 | else if (EQUAL(pszImageFormat, "image/png")) |
45 | 0 | m_imageExtension = "png"; |
46 | 0 | else if (EQUAL(pszImageFormat, "image/webp")) |
47 | 0 | m_imageExtension = "webp"; |
48 | |
|
49 | 0 | return CE_None; |
50 | 0 | } |
51 | | |
52 | | void WMSMiniDriver_IIIFImage::GetCapabilities(WMSMiniDriverCapabilities *caps) |
53 | 0 | { |
54 | 0 | caps->m_overview_dim_computation_method = OVERVIEW_FLOOR; |
55 | 0 | caps->m_has_geotransform = false; |
56 | 0 | } |
57 | | |
58 | | CPLErr WMSMiniDriver_IIIFImage::TiledImageRequest( |
59 | | WMSHTTPRequest &request, const GDALWMSImageRequestInfo & /* iri */, |
60 | | const GDALWMSTiledImageRequestInfo &tiri) |
61 | 0 | { |
62 | 0 | CPLString &url = request.URL; |
63 | 0 | url = m_base_url; |
64 | 0 | if (!url.empty() && url.back() != '/') |
65 | 0 | url += '/'; |
66 | |
|
67 | 0 | int nBlockWidth = 0; |
68 | 0 | int nBlockHeight = 0; |
69 | 0 | m_parent_dataset->GetRasterBand(1)->GetBlockSize(&nBlockWidth, |
70 | 0 | &nBlockHeight); |
71 | |
|
72 | 0 | const int iShift = |
73 | 0 | m_parent_dataset->GetRasterBand(1)->GetOverviewCount() - tiri.m_level; |
74 | |
|
75 | 0 | GDALRasterBand *poOvrBand = |
76 | 0 | iShift == 0 |
77 | 0 | ? m_parent_dataset->GetRasterBand(1) |
78 | 0 | : m_parent_dataset->GetRasterBand(1)->GetOverview( |
79 | 0 | m_parent_dataset->GetRasterBand(1)->GetOverviewCount() - 1 - |
80 | 0 | tiri.m_level); |
81 | |
|
82 | 0 | const int nXOffFullRes = (tiri.m_x * nBlockWidth) << iShift; |
83 | 0 | const int nYOffFullRes = (tiri.m_y * nBlockHeight) << iShift; |
84 | 0 | url += CPLSPrintf( |
85 | 0 | "%d,%d,%d,%d/%d,%d/0/default.%s", nXOffFullRes, nYOffFullRes, |
86 | 0 | std::min(nBlockWidth << iShift, |
87 | 0 | m_parent_dataset->GetRasterXSize() - nXOffFullRes), |
88 | 0 | std::min(nBlockHeight << iShift, |
89 | 0 | m_parent_dataset->GetRasterYSize() - nYOffFullRes), |
90 | 0 | std::min(nBlockWidth, poOvrBand->GetXSize() - tiri.m_x * nBlockWidth), |
91 | 0 | std::min(nBlockHeight, poOvrBand->GetYSize() - tiri.m_y * nBlockHeight), |
92 | 0 | m_imageExtension.c_str()); |
93 | |
|
94 | 0 | return CE_None; |
95 | 0 | } |