Line data Source code
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 2 : WMSMiniDriver_IIIFImage::WMSMiniDriver_IIIFImage() 22 : { 23 2 : } 24 : 25 4 : WMSMiniDriver_IIIFImage::~WMSMiniDriver_IIIFImage() 26 : { 27 4 : } 28 : 29 2 : CPLErr WMSMiniDriver_IIIFImage::Initialize(CPLXMLNode *config, 30 : CPL_UNUSED char **papszOpenOptions) 31 : { 32 2 : m_base_url = CPLGetXMLValue(config, "ServerURL", ""); 33 2 : if (m_base_url.empty()) 34 : { 35 0 : CPLError(CE_Failure, CPLE_AppDefined, 36 : "GDALWMS, IIIFImage mini-driver: ServerURL missing."); 37 0 : return CE_Failure; 38 : } 39 : 40 : const char *pszImageFormat = 41 2 : CPLGetXMLValue(config, "ImageFormat", "image/jpeg"); 42 2 : if (EQUAL(pszImageFormat, "image/jpeg")) 43 2 : 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 2 : return CE_None; 50 : } 51 : 52 2 : void WMSMiniDriver_IIIFImage::GetCapabilities(WMSMiniDriverCapabilities *caps) 53 : { 54 2 : caps->m_overview_dim_computation_method = OVERVIEW_FLOOR; 55 2 : caps->m_has_geotransform = false; 56 2 : } 57 : 58 4 : CPLErr WMSMiniDriver_IIIFImage::TiledImageRequest( 59 : WMSHTTPRequest &request, const GDALWMSImageRequestInfo & /* iri */, 60 : const GDALWMSTiledImageRequestInfo &tiri) 61 : { 62 4 : CPLString &url = request.URL; 63 4 : url = m_base_url; 64 4 : if (!url.empty() && url.back() != '/') 65 4 : url += '/'; 66 : 67 4 : int nBlockWidth = 0; 68 4 : int nBlockHeight = 0; 69 4 : m_parent_dataset->GetRasterBand(1)->GetBlockSize(&nBlockWidth, 70 : &nBlockHeight); 71 : 72 : const int iShift = 73 4 : m_parent_dataset->GetRasterBand(1)->GetOverviewCount() - tiri.m_level; 74 : 75 : GDALRasterBand *poOvrBand = 76 : iShift == 0 77 4 : ? m_parent_dataset->GetRasterBand(1) 78 4 : : m_parent_dataset->GetRasterBand(1)->GetOverview( 79 2 : m_parent_dataset->GetRasterBand(1)->GetOverviewCount() - 1 - 80 4 : tiri.m_level); 81 : 82 4 : const int nXOffFullRes = (tiri.m_x * nBlockWidth) << iShift; 83 4 : const int nYOffFullRes = (tiri.m_y * nBlockHeight) << iShift; 84 : url += CPLSPrintf( 85 : "%d,%d,%d,%d/%d,%d/0/default.%s", nXOffFullRes, nYOffFullRes, 86 0 : std::min(nBlockWidth << iShift, 87 4 : m_parent_dataset->GetRasterXSize() - nXOffFullRes), 88 0 : std::min(nBlockHeight << iShift, 89 4 : m_parent_dataset->GetRasterYSize() - nYOffFullRes), 90 4 : std::min(nBlockWidth, poOvrBand->GetXSize() - tiri.m_x * nBlockWidth), 91 4 : std::min(nBlockHeight, poOvrBand->GetYSize() - tiri.m_y * nBlockHeight), 92 20 : m_imageExtension.c_str()); 93 : 94 4 : return CE_None; 95 : }