X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=BookReaderIA%2Fdatanode%2FBookReaderImages.inc.php;h=5e09445064b90d991ce27cc3936accad545cae3b;hb=4c3d0cd7a49ed26566b7876d583c970d08fd2325;hp=74b7b13e1cecc4012d66f1d5b185bbfef59ffff4;hpb=e4abc196a788139e42ce944532bc64db7f5b4507;p=bookreader.git diff --git a/BookReaderIA/datanode/BookReaderImages.inc.php b/BookReaderIA/datanode/BookReaderImages.inc.php index 74b7b13..5e09445 100644 --- a/BookReaderIA/datanode/BookReaderImages.inc.php +++ b/BookReaderIA/datanode/BookReaderImages.inc.php @@ -60,6 +60,8 @@ class BookReaderImages 'tile' => 'tile', 'w' => 'width', 'h' => 'height', + 'x' => 'x', + 'y' => 'y', 'rotate' => 'rotate' ); @@ -97,7 +99,7 @@ class BookReaderImages // deal with subPrefix if ($_REQUEST['subPrefix']) { - $parts = split('/', $_REQUEST['subPrefix']); + $parts = explode('/', $_REQUEST['subPrefix']); $bookId = $parts[count($parts) - 1 ]; } else { $bookId = $_REQUEST['id']; @@ -108,6 +110,7 @@ class BookReaderImages $basePage = $pageInfo['type']; $leaf = null; + $region = null; switch ($basePage) { case 'title': @@ -175,7 +178,7 @@ class BookReaderImages // Leaf explicitly specified $leaf = $pageInfo['value']; break; - + default: // Shouldn't be possible $this->BRfatal("Unrecognized page type requested"); @@ -251,6 +254,20 @@ class BookReaderImages // Get the image size and depth $imageInfo = $this->getImageInfo($zipPath, $file); + $region = array(); + foreach (array('x', 'y', 'w', 'h') as $key) { + if (array_key_exists($key, $requestEnv)) { + $region[$key] = $requestEnv[$key]; + } + } + $regionDimensions = $this->getRegionDimensions($imageInfo, $region); + + /* $$$ remove + print_r($imageInfo); + print_r($region); + print_r($regionDimensions); + */ + // Output json if requested if ('json' == $ext) { // $$$ we should determine the output size first based on requested scale @@ -874,6 +891,103 @@ class BookReaderImages return $pageInfo; } + function getRegionDimensions($sourceDimensions, $regionDimensions) { + // Return region dimensions as { 'x' => xOffset, 'y' => yOffset, 'w' => width, 'h' => height } + // in terms of full resolution image. + // Note: this will clip the returned dimensions to fit within the source image + + $sourceX = 0; + if (array_key_exists('x', $regionDimensions)) { + $sourceX = intAmount($regionDimensions['x'], $sourceDimensions['width']); + } + $sourceX = $this->clamp(0, $sourceDimensions['width'] - 2, $sourceX); // Allow at least one pixel + + $sourceY = 0; + if (array_key_exists('y', $regionDimensions)) { + $sourceY = intAmount($regionDimensions['y'], $sourceDimensions['height']); + } + $sourceY = $this->clamp(0, $sourceDimensions['height'] - 2, $sourceY); // Allow at least one pixel + + $sourceWidth = $sourceDimensions['width'] - $sourceX; + if (array_key_exists('w', $regionDimensions)) { + $sourceWidth = intAmount($regionDimensions['w'], $sourceDimensions['width']); + } + $sourceWidth = $this->clamp(1, max(1, $sourceDimensions['width'] - $sourceX), $sourceWidth); + + $sourceHeight = $sourceDimensions['height'] - $sourceY; + if (array_key_exists('h', $regionDimensions)) { + $sourceHeight = intAmount($regionDimensions['h'], $sourceDimensions['height']); + } + $sourceHeight = $this->clamp(1, max(1, $sourceDimensions['height'] - $sourceY), $sourceHeight); + + return array('x' => $sourceX, 'y' => $sourceY, 'w' => $sourceWidth, 'h' => $sourceHeight); + } + + function getRegionDimensionsAsFloat($sourceDimensions, $regionDimensions) { + // Return region dimensions as { 'x' => xOffset, 'y' => yOffset, 'w' => width, 'h' => height } + // in terms of full resolution image. + // Note: this will clip the returned dimensions to fit within the source image + + $sourceX = 0; + if (array_key_exists('x', $regionDimensions)) { + $sourceX = floatAmount($regionDimensions['x'], $sourceDimensions['width']); + } + $sourceX = $this->clamp(0.0, 1.0, $sourceX); + + $sourceY = 0; + if (array_key_exists('y', $regionDimensions)) { + $sourceY = floatAmount($regionDimensions['y'], $sourceDimensions['height']); + } + $sourceY = $this->clamp(0.0, 1.0, $sourceY); // Allow at least one pixel + + $sourceWidth = $sourceDimensions['width'] - $sourceX; + if (array_key_exists('w', $regionDimensions)) { + $sourceWidth = floatAmount($regionDimensions['w'], $sourceDimensions['width']); + } + $sourceWidth = $this->clamp(0.0, 1.0, $sourceWidth); + + $sourceHeight = $sourceDimensions['height'] - $sourceY; + if (array_key_exists('h', $regionDimensions)) { + $sourceHeight = floatAmount($regionDimensions['h'], $sourceDimensions['height']); + } + $sourceHeight = $this->clamp(0.0, 1.0, $sourceHeight); + + return array('x' => $sourceX, 'y' => $sourceY, 'w' => $sourceWidth, 'h' => $sourceHeight); + } + + function intAmount($stringValue, $maximum) { + // Returns integer amount for string like "5" (5 units) or "0.5" (50%) + if (strpos($stringValue, '.') === false) { + // No decimal, assume int + return intval($stringValue); + } + + return floatval($stringValue) * $maximum + 0.5; + } + + function floatAmount($stringValue, $maximum) { + // Returns float amount (0.0 to 1.0) for string like "0.4" (40%) or "4" (40% if max is 10) + if (strpos($stringValue, ".") === false) { + // No decimal, assume int value out of maximum + return floatval($stringValue) / $maximum; + } + + // Given float - just pass through + return floatval($stringValue); + } + + function clamp($minValue, $maxValue, $observedValue) { + if ($observedValue < $minValue) { + return $minValue; + } + + if ($observedValue > $maxValue) { + return $maxValue; + } + + return $observedValue; + } + // Clean up temporary files and resources function cleanup() { foreach($this->tempFiles as $tempFile) {