@@ -538,25 +538,111 @@ QMap<QString, QList<QgsMapLayer *> > QgsWmsRenderContext::layerGroups() const
538
538
return mLayerGroups ;
539
539
}
540
540
541
- QSize QgsWmsRenderContext::mapSize ( const bool aspectRatio ) const
541
+ int QgsWmsRenderContext::width ( ) const
542
542
{
543
543
int width = mParameters .widthAsInt ();
544
+
545
+ // May use SRCWIDTH to define image map size
546
+ if ( ( mFlags & UseSrcWidthHeight ) && mParameters .srcWidthAsInt () > 0 )
547
+ {
548
+ width = mParameters .srcWidthAsInt ();
549
+ }
550
+
551
+ return width;
552
+ }
553
+
554
+ int QgsWmsRenderContext::height () const
555
+ {
544
556
int height = mParameters .heightAsInt ();
545
557
546
- // May use SRCWIDTH and SRCHEIGHT to define image map size
547
- if ( mFlags & UseSrcWidthHeight )
558
+ // May use SRCHEIGHT to define image map size
559
+ if ( ( mFlags & UseSrcWidthHeight ) && mParameters . srcHeightAsInt () > 0 )
548
560
{
549
- if ( mParameters .srcWidthAsInt () > 0 )
550
- {
551
- width = mParameters .srcWidthAsInt ();
552
- }
561
+ height = mParameters .srcHeightAsInt ();
562
+ }
553
563
554
- if ( mParameters .srcHeightAsInt () > 0 )
555
- {
556
- height = mParameters .srcHeightAsInt ();
557
- }
564
+ return height;
565
+ }
566
+
567
+ bool QgsWmsRenderContext::isValidWidthHeight () const
568
+ {
569
+ // test if maxWidth / maxHeight are set in the project or as an env variable
570
+ // and WIDTH / HEIGHT parameter is in the range allowed range
571
+ // WIDTH
572
+ const int wmsMaxWidthProj = QgsServerProjectUtils::wmsMaxWidth ( *mProject );
573
+ const int wmsMaxWidthEnv = settings ().wmsMaxWidth ();
574
+ int wmsMaxWidth;
575
+ if ( wmsMaxWidthEnv != -1 && wmsMaxWidthProj != -1 )
576
+ {
577
+ // both are set, so we take the more conservative one
578
+ wmsMaxWidth = std::min ( wmsMaxWidthProj, wmsMaxWidthEnv );
579
+ }
580
+ else
581
+ {
582
+ // none or one are set, so we take the bigger one which is the one set or -1
583
+ wmsMaxWidth = std::max ( wmsMaxWidthProj, wmsMaxWidthEnv );
584
+ }
585
+
586
+ if ( wmsMaxWidth != -1 && width () > wmsMaxWidth )
587
+ {
588
+ return false ;
558
589
}
559
590
591
+ // HEIGHT
592
+ const int wmsMaxHeightProj = QgsServerProjectUtils::wmsMaxHeight ( *mProject );
593
+ const int wmsMaxHeightEnv = settings ().wmsMaxHeight ();
594
+ int wmsMaxHeight;
595
+ if ( wmsMaxHeightEnv != -1 && wmsMaxHeightProj != -1 )
596
+ {
597
+ // both are set, so we take the more conservative one
598
+ wmsMaxHeight = std::min ( wmsMaxHeightProj, wmsMaxHeightEnv );
599
+ }
600
+ else
601
+ {
602
+ // none or one are set, so we take the bigger one which is the one set or -1
603
+ wmsMaxHeight = std::max ( wmsMaxHeightProj, wmsMaxHeightEnv );
604
+ }
605
+
606
+ if ( wmsMaxHeight != -1 && height () > wmsMaxHeight )
607
+ {
608
+ return false ;
609
+ }
610
+
611
+ // Sanity check from internal QImage checks (see qimage.cpp)
612
+ // this is to report a meaningful error message in case of
613
+ // image creation failure and to differentiate it from out
614
+ // of memory conditions.
615
+
616
+ // depth for now it cannot be anything other than 32, but I don't like
617
+ // to hardcode it: I hope we will support other depths in the future.
618
+ uint depth = 32 ;
619
+ switch ( mParameters .format () )
620
+ {
621
+ case QgsWmsParameters::Format::JPG:
622
+ case QgsWmsParameters::Format::PNG:
623
+ default :
624
+ depth = 32 ;
625
+ }
626
+
627
+ const int bytes_per_line = ( ( width () * depth + 31 ) >> 5 ) << 2 ; // bytes per scanline (must be multiple of 4)
628
+
629
+ if ( std::numeric_limits<int >::max () / depth < static_cast <uint>( width () )
630
+ || bytes_per_line <= 0
631
+ || height () <= 0
632
+ || std::numeric_limits<int >::max () / static_cast <uint>( bytes_per_line ) < static_cast <uint>( height () )
633
+ || std::numeric_limits<int >::max () / sizeof ( uchar * ) < static_cast <uint>( height () ) )
634
+ {
635
+ return false ;
636
+ }
637
+
638
+ return true ;
639
+ }
640
+
641
+ QSize QgsWmsRenderContext::mapSize ( const bool aspectRatio ) const
642
+ {
643
+ int mapWidth = width ();
644
+ int mapHeight = height ();
645
+
560
646
// Adapt width / height if the aspect ratio does not correspond with the BBOX.
561
647
// Required by WMS spec. 1.3.
562
648
if ( aspectRatio
@@ -582,32 +668,32 @@ QSize QgsWmsRenderContext::mapSize( const bool aspectRatio ) const
582
668
extent.invert ();
583
669
}
584
670
585
- if ( !extent.isEmpty () && height > 0 && width > 0 )
671
+ if ( !extent.isEmpty () && mapHeight > 0 && mapWidth > 0 )
586
672
{
587
673
const double mapRatio = extent.width () / extent.height ();
588
- const double imageRatio = static_cast <double >( width ) / static_cast <double >( height );
674
+ const double imageRatio = static_cast <double >( mapWidth ) / static_cast <double >( mapHeight );
589
675
if ( !qgsDoubleNear ( mapRatio, imageRatio, 0.0001 ) )
590
676
{
591
677
// inspired by MapServer, mapdraw.c L115
592
- const double cellsize = ( extent.width () / static_cast <double >( width ) ) * 0.5 + ( extent.height () / static_cast <double >( height ) ) * 0.5 ;
593
- width = extent.width () / cellsize;
594
- height = extent.height () / cellsize;
678
+ const double cellsize = ( extent.width () / static_cast <double >( mapWidth ) ) * 0.5 + ( extent.height () / static_cast <double >( mapHeight ) ) * 0.5 ;
679
+ mapWidth = extent.width () / cellsize;
680
+ mapHeight = extent.height () / cellsize;
595
681
}
596
682
}
597
683
}
598
684
599
- if ( width <= 0 )
685
+ if ( mapWidth <= 0 )
600
686
{
601
687
throw QgsBadRequestException ( QgsServiceException::QGIS_InvalidParameterValue,
602
688
mParameters [QgsWmsParameter::WIDTH] );
603
689
}
604
- else if ( height <= 0 )
690
+ else if ( mapHeight <= 0 )
605
691
{
606
692
throw QgsBadRequestException ( QgsServiceException::QGIS_InvalidParameterValue,
607
693
mParameters [QgsWmsParameter::HEIGHT] );
608
694
}
609
695
610
- return QSize ( width, height );
696
+ return QSize ( mapWidth, mapHeight );
611
697
}
612
698
613
699
void QgsWmsRenderContext::removeUnwantedLayers ()
0 commit comments