changeset 259:3e511f10896c iiif

avoid non-integer scale factors in IIIF
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 10 Jul 2023 08:06:10 +0200
parents 07be799fa383
children 35c241231af2
files ViewerPlugin/Plugin.cpp
diffstat 1 files changed, 24 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ViewerPlugin/Plugin.cpp	Sun Jul 09 16:16:04 2023 +0200
+++ b/ViewerPlugin/Plugin.cpp	Mon Jul 10 08:06:10 2023 +0200
@@ -417,19 +417,26 @@
   }
 
   Json::Value sizes = Json::arrayValue;
+  Json::Value scaleFactors = Json::arrayValue;
+
   for (unsigned int i = locker.GetPyramid().GetLevelCount(); i > 0; i--)
   {
-    Json::Value level;
-    level["width"] = locker.GetPyramid().GetLevelWidth(i - 1);
-    level["height"] = locker.GetPyramid().GetLevelHeight(i - 1);
-    sizes.append(level);
-  }
+    /**
+     * Openseadragon seems to have difficulties in rendering
+     * non-integer scale factors. Consequently, we only keep the
+     * levels with an integer scale factor.
+     **/
+    if (locker.GetPyramid().GetLevelWidth(0) % locker.GetPyramid().GetLevelWidth(i - 1) == 0 &&
+        locker.GetPyramid().GetLevelHeight(0) % locker.GetPyramid().GetLevelHeight(i - 1) == 0)
+    {
+      Json::Value level;
+      level["width"] = locker.GetPyramid().GetLevelWidth(i - 1);
+      level["height"] = locker.GetPyramid().GetLevelHeight(i - 1);
+      sizes.append(level);
 
-  Json::Value scaleFactors = Json::arrayValue;
-  for (unsigned int i = locker.GetPyramid().GetLevelCount(); i > 0; i--)
-  {
-    scaleFactors.append(static_cast<float>(locker.GetPyramid().GetLevelWidth(0)) /
-                        static_cast<float>(locker.GetPyramid().GetLevelWidth(i - 1)));
+      scaleFactors.append(static_cast<float>(locker.GetPyramid().GetLevelWidth(0)) /
+                          static_cast<float>(locker.GetPyramid().GetLevelWidth(i - 1)));
+    }
   }
 
   Json::Value tiles;
@@ -609,21 +616,22 @@
         if (regionX % physicalTileWidth == 0 &&
             regionY % physicalTileHeight == 0 &&
             regionWidth <= physicalTileWidth &&
-            regionHeight <= physicalTileHeight)
+            regionHeight <= physicalTileHeight &&
+            regionX + regionWidth <= pyramid.GetLevelWidth(0) &&
+            regionY + regionHeight <= pyramid.GetLevelHeight(0))
         {
           break;
         }
       }
 
-      if (cropWidth > pyramid.GetTileWidth(level))
-      {
-        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, "IIIF - Request for a cropping that is too large for the tile size");
-      }
-
       if (level == pyramid.GetLevelCount())
       {
         throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, "IIIF - Cannot locate the level of interest");
       }
+      else if (cropWidth > pyramid.GetTileWidth(level))
+      {
+        throw Orthanc::OrthancException(Orthanc::ErrorCode_BadRequest, "IIIF - Request for a cropping that is too large for the tile size");
+      }
       else
       {
         rawTile.reset(new RawTile(locker.GetPyramid(), level,