0byt3m1n1
Path:
/
data
/
applications
/
aps
/
gallery
/
2.2-08
/
htdocs
/
modules
/
squarethumb
/
classes
/
[
Home
]
File: SquareThumbToolkit.class
<?php /* * Gallery - a web based photo album viewer and editor * Copyright (C) 2000-2007 Bharat Mediratta * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ GalleryCoreApi::requireOnce('modules/core/classes/GalleryToolkit.class'); /** * A version of GalleryToolkit to enforce creation of square thumbnails * @package SquareThumb * @subpackage Classes * @author Alan Harder <alan.harder@sun.com> * @version $Revision: 15513 $ */ class SquareThumbToolkit extends GalleryToolkit { /** * @see GalleryToolkit::getProperty */ function getProperty($mimeType, $propertyName, $sourceFilename) { return array(GalleryCoreApi::error(ERROR_UNIMPLEMENTED), null); } /** * @see GalleryToolkit::performOperation */ function performOperation($mimeType, $operationName, $sourceFilename, $destFilename, $parameters, $context=array()) { global $gallery; $platform =& $gallery->getPlatform(); if ($operationName != 'thumbnail') { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "$operationName $mimeType"), null, null); } list ($ret, $square) = GalleryCoreApi::fetchAllPluginParameters('module', 'squarethumb'); if ($ret) { return array($ret, null, null); } /* Get dimensions */ if (isset($context['width'])) { $width = $context['width']; $height = $context['height']; } else { list ($ret, $toolkit) = GalleryCoreApi::getToolkitByProperty($mimeType, 'dimensions'); if ($ret) { return array($ret, null, null); } if (!isset($toolkit)) { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "dimensions $mimeType"), null, null); } list ($ret, $dimensions) = $toolkit->getProperty($mimeType, 'dimensions', $sourceFilename); if ($ret) { return array($ret, null, null); } list ($width, $height) = $dimensions; } $subContext = array('width' => $width, 'height' => $height); /* Try to crop/fit according to param, but fallback to other based on toolkit support */ if ($width != $height) { for ($i = 0; $i < 2; $i++) { $operation = ($square['mode'] == 'fit') ? 'composite' : 'crop'; list ($ret, $toolkit, $nextMime) = GalleryCoreApi::getToolkitByOperation($mimeType, $operation); if ($ret) { return array($ret, null, null); } if (isset($toolkit)) { break; } $square['mode'] = ($square['mode'] == 'fit') ? 'crop' : 'fit'; } } if ($width != $height && $square['mode'] == 'crop') { /* Crop to square */ if (!isset($toolkit)) { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "crop $mimeType"), null, null); } if ($width > $parameters[0] && $height > $parameters[0]) { list ($ret, $nextToolkit) = $this->_getThumbnailToolkit($nextMime); if (!$ret) { $subContext['next.toolkit'] = $nextToolkit; $subContext['next.operation'] = 'thumbnail'; } } $args = ($width > $height) ? array( 100*(1-$height/$width)/2, 0, 100*$height/$width, 100 ) : array( 0, 100*(1-$width/$height)/2, 100, 100*$width/$height ); list ($ret, $mimeType, $subContext) = $toolkit->performOperation( $mimeType, 'crop', $sourceFilename, $destFilename, $args, $subContext); if ($ret) { return array($ret, null, null); } $sourceFilename = $destFilename; } if ($subContext['width'] > $parameters[0] || $subContext['height'] > $parameters[0]) { /* Scale to thumb size */ list ($ret, $toolkit) = $this->_getThumbnailToolkit($mimeType); if ($ret) { return array($ret, null, null); } $subContext['next.toolkit'] = $subContext['next.operation'] = null; list ($ret, $mimeType, $subContext) = $toolkit->performOperation($mimeType, 'thumbnail', $sourceFilename, $destFilename, $parameters, $subContext); if ($ret) { return array($ret, null, null); } $sourceFilename = $destFilename; } if ($subContext['width'] != $subContext['height'] && $square['mode'] == 'fit') { /* Fit to square */ $size = max($subContext['width'], $subContext['height']); /* Write PPM file with background color and convert to jpeg */ list ($ret, $toolkit) = GalleryCoreApi::getToolkitByOperation('image/x-portable-pixmap', 'convert-to-image/jpeg'); if ($ret) { return array($ret, null, null); } if (!isset($toolkit)) { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, 'convert-to-image/jpeg image/x-portable-pixmap'), null, null); } $tmpFilename = $platform->tempnam($gallery->getConfig('data.gallery.tmp'), 'sqth_'); if (empty($tmpFilename)) { return array(GalleryCoreApi::error(ERROR_BAD_PATH), null, null); } if (!$platform->copy($sourceFilename, $tmpFilename)) { @$platform->unlink($tmpFilename); return array(GalleryCoreApi::error(ERROR_PLATFORM_FAILURE), null, null); } if (!($fh = $platform->fopen($destFilename, 'w'))) { @$platform->unlink($tmpFilename); return array(GalleryCoreApi::error(ERROR_PLATFORM_FAILURE), null, null); } $platform->fwrite($fh, "P6\n$size $size\n255\n"); /* Convert RGB hex string to 3 binary bytes */ $row = str_repeat(chr(hexdec(substr($square['color'], 0, 2))) . chr(hexdec(substr($square['color'], 2, 2))) . chr(hexdec(substr($square['color'], 4, 2))), $size); for ($i = 0; $i < $size; $i++) { $platform->fwrite($fh, $row); } $platform->fclose($fh); list ($ret) = $toolkit->performOperation( 'image/x-portable-pixmap', 'convert-to-image/jpeg', $destFilename, $destFilename, array()); if ($ret) { @$platform->unlink($tmpFilename); return array($ret, null, null); } /* Overlay thumbnail image on square background */ list ($ret, $toolkit) = GalleryCoreApi::getToolkitByOperation($mimeType, 'composite'); if ($ret) { @$platform->unlink($tmpFilename); return array($ret, null, null); } if (!isset($toolkit)) { @$platform->unlink($tmpFilename); return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "composite $mimeType"), null, null); } $newContext = array('width' => $size, 'height' => $size); list ($ret, $mimeType, $subContext) = $toolkit->performOperation( 'image/jpeg', 'composite', $destFilename, $destFilename, array(substr($tmpFilename, strlen($gallery->getConfig('data.gallery.base'))), $mimeType, $subContext['width'], $subContext['height'], 'center', 0, 0), $newContext); @$platform->unlink($tmpFilename); if ($ret) { return array($ret, null, null); } $sourceFilename = $destFilename; } if ($sourceFilename != $destFilename) { /* If no work was done (small image, already square) then just copy original */ if (!$platform->copy($sourceFilename, $destFilename)) { return array(GalleryCoreApi::error(ERROR_PLATFORM_FAILURE), null, null); } } $context['width'] = $subContext['width']; $context['height'] = $subContext['height']; return array(null, $mimeType, $context); } /** * Estimate the dimensions of a GalleryDerivativeImage from its operations and its source. * * @param object GalleryDerivativeImage $derivative the derivative * @param object GalleryDerivativeEntity $source the source * (probably a GalleryPhotoItem or GalleryMovieItem) */ function estimateDimensions(&$derivative, $source) { $handled = false; if (method_exists($source, 'getwidth') && method_exists($source, 'getheight')) { $width = $source->getWidth(); $height = $source->getHeight(); if ($width && $height) { $operations = $derivative->getDerivativeOperations(); if (preg_match('/^(?:thumbnail)\|(\d+)$/', $operations, $matches)) { $targetSize = (int)$matches[1]; if (!empty($targetSize)) { if (!GalleryUtilities::isA($source, 'GalleryDerivativeImage')) { /* * If the source is also a derivative then assume the real source * is large enough that we can make a square of the desired size. * It's possible the real source is actually smaller than our * $targetSize, but it will be corrected once the derivative is built. */ $targetSize = min(min($width, $height), $targetSize); } $derivative->setWidth($targetSize); $derivative->setHeight($targetSize); $handled = true; } } } } if (!$handled) { return parent::estimateDimensions($derivative, $source); } } /** * Get toolkit for thumbnail operation. * @param string $mimeType * @return array object GalleryStatus a status code * object GalleryToolkit * @access private */ function _getThumbnailToolkit($mimeType) { list ($ret, $data) = GalleryCoreApi::getToolkitOperationMimeTypes('thumbnail'); if ($ret) { return array($ret, null); } if (!empty($data[$mimeType]) && $data[$mimeType][0] == 'SquareThumb') { array_shift($data[$mimeType]); } if (empty($data[$mimeType])) { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "thumbnail $mimeType"), null); } list ($ret, $toolkit) = GalleryCoreApi::newFactoryInstanceById('GalleryToolkit', $data[$mimeType][0]); if ($ret) { return array($ret, null); } if (!isset($toolkit)) { return array(GalleryCoreApi::error(ERROR_UNSUPPORTED_OPERATION, __FILE__, __LINE__, "thumbnail $mimeType"), null); } return array(null, $toolkit); } } ?>