[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/media/ -> XCF.php (source)

   1  <?php
   2  /**
   3   * Handler for the Gimp's native file format (XCF)
   4   *
   5   * Overview:
   6   *   http://en.wikipedia.org/wiki/XCF_(file_format)
   7   * Specification in Gnome repository:
   8   *   http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
   9   *
  10   * This program is free software; you can redistribute it and/or modify
  11   * it under the terms of the GNU General Public License as published by
  12   * the Free Software Foundation; either version 2 of the License, or
  13   * (at your option) any later version.
  14   *
  15   * This program is distributed in the hope that it will be useful,
  16   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18   * GNU General Public License for more details.
  19   *
  20   * You should have received a copy of the GNU General Public License along
  21   * with this program; if not, write to the Free Software Foundation, Inc.,
  22   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  23   * http://www.gnu.org/copyleft/gpl.html
  24   *
  25   * @file
  26   * @ingroup Media
  27   */
  28  
  29  /**
  30   * Handler for the Gimp's native file format; getimagesize() doesn't
  31   * support these files
  32   *
  33   * @ingroup Media
  34   */
  35  class XCFHandler extends BitmapHandler {
  36      /**
  37       * @param File $file
  38       * @return bool
  39       */
  40  	function mustRender( $file ) {
  41          return true;
  42      }
  43  
  44      /**
  45       * Render files as PNG
  46       *
  47       * @param string $ext
  48       * @param string $mime
  49       * @param array $params
  50       * @return array
  51       */
  52  	function getThumbType( $ext, $mime, $params = null ) {
  53          return array( 'png', 'image/png' );
  54      }
  55  
  56      /**
  57       * Get width and height from the XCF header.
  58       *
  59       * @param File $image
  60       * @param string $filename
  61       * @return array
  62       */
  63  	function getImageSize( $image, $filename ) {
  64          $header = self::getXCFMetaData( $filename );
  65          if ( !$header ) {
  66              return false;
  67          }
  68  
  69          # Forge a return array containing metadata information just like getimagesize()
  70          # See PHP documentation at: http://www.php.net/getimagesize
  71          $metadata = array();
  72          $metadata[0] = $header['width'];
  73          $metadata[1] = $header['height'];
  74          $metadata[2] = null; # IMAGETYPE constant, none exist for XCF.
  75          $metadata[3] = sprintf(
  76              'height="%s" width="%s"', $header['height'], $header['width']
  77          );
  78          $metadata['mime'] = 'image/x-xcf';
  79          $metadata['channels'] = null;
  80          $metadata['bits'] = 8; # Always 8-bits per color
  81  
  82          assert( '7 == count($metadata); ' .
  83              '# return array must contains 7 elements just like getimagesize() return' );
  84  
  85          return $metadata;
  86      }
  87  
  88      /**
  89       * Metadata for a given XCF file
  90       *
  91       * Will return false if file magic signature is not recognized
  92       * @author Hexmode
  93       * @author Hashar
  94       *
  95       * @param string $filename Full path to a XCF file
  96       * @return bool|array Metadata Array just like PHP getimagesize()
  97       */
  98  	static function getXCFMetaData( $filename ) {
  99          # Decode master structure
 100          $f = fopen( $filename, 'rb' );
 101          if ( !$f ) {
 102              return false;
 103          }
 104          # The image structure always starts at offset 0 in the XCF file.
 105          # So we just read it :-)
 106          $binaryHeader = fread( $f, 26 );
 107          fclose( $f );
 108  
 109          # Master image structure:
 110          #
 111          # byte[9] "gimp xcf "  File type magic
 112          # byte[4] version      XCF version
 113          #                        "file" - version 0
 114          #                        "v001" - version 1
 115          #                        "v002" - version 2
 116          # byte    0            Zero-terminator for version tag
 117          # uint32  width        With of canvas
 118          # uint32  height       Height of canvas
 119          # uint32  base_type    Color mode of the image; one of
 120          #                         0: RGB color
 121          #                         1: Grayscale
 122          #                         2: Indexed color
 123          #        (enum GimpImageBaseType in libgimpbase/gimpbaseenums.h)
 124          try {
 125              $header = wfUnpack(
 126                  "A9magic" . # A: space padded
 127                      "/a5version" . # a: zero padded
 128                      "/Nwidth" . # \
 129                      "/Nheight" . # N: unsigned long 32bit big endian
 130                      "/Nbase_type", # /
 131                  $binaryHeader
 132              );
 133          } catch ( MWException $mwe ) {
 134              return false;
 135          }
 136  
 137          # Check values
 138          if ( $header['magic'] !== 'gimp xcf' ) {
 139              wfDebug( __METHOD__ . " '$filename' has invalid magic signature.\n" );
 140  
 141              return false;
 142          }
 143          # TODO: we might want to check for sane values of width and height
 144  
 145          wfDebug( __METHOD__ .
 146              ": canvas size of '$filename' is {$header['width']} x {$header['height']} px\n" );
 147  
 148          return $header;
 149      }
 150  
 151      /**
 152       * Store the channel type
 153       *
 154       * Greyscale files need different command line options.
 155       *
 156       * @param File $file The image object, or false if there isn't one.
 157       *   Warning, FSFile::getPropsFromPath might pass an (object)array() instead (!)
 158       * @param string $filename The filename
 159       * @return string
 160       */
 161  	public function getMetadata( $file, $filename ) {
 162          $header = self::getXCFMetadata( $filename );
 163          $metadata = array();
 164          if ( $header ) {
 165              // Try to be consistent with the names used by PNG files.
 166              // Unclear from base media type if it has an alpha layer,
 167              // so just assume that it does since it "potentially" could.
 168              switch ( $header['base_type'] ) {
 169              case 0:
 170                  $metadata['colorType'] = 'truecolour-alpha';
 171                  break;
 172              case 1:
 173                  $metadata['colorType'] = 'greyscale-alpha';
 174                  break;
 175              case 2:
 176                  $metadata['colorType'] = 'index-coloured';
 177                  break;
 178              default:
 179                  $metadata['colorType'] = 'unknown';
 180  
 181              }
 182          } else {
 183              // Marker to prevent repeated attempted extraction
 184              $metadata['error'] = true;
 185          }
 186          return serialize( $metadata );
 187      }
 188  
 189      /**
 190       * Should we refresh the metadata
 191       *
 192       * @param File $file The file object for the file in question
 193       * @param string $metadata Serialized metadata
 194       * @return bool One of the self::METADATA_(BAD|GOOD|COMPATIBLE) constants
 195       */
 196  	public function isMetadataValid( $file, $metadata ) {
 197          if ( !$metadata ) {
 198              // Old metadata when we just put an empty string in there
 199              return self::METADATA_BAD;
 200          } else {
 201              return self::METADATA_GOOD;
 202          }
 203      }
 204  
 205      /**
 206       * Must use "im" for XCF
 207       *
 208       * @param string $dstPath
 209       * @param bool $checkDstPath
 210       * @return string
 211       */
 212  	protected function getScalerType( $dstPath, $checkDstPath = true ) {
 213          return "im";
 214      }
 215  
 216      /**
 217       * Can we render this file?
 218       *
 219       * Image magick doesn't support indexed xcf files as of current
 220       * writing (as of 6.8.9-3)
 221       * @param File $file
 222       * @return bool
 223       */
 224  	public function canRender( $file ) {
 225          wfSuppressWarnings();
 226          $xcfMeta = unserialize( $file->getMetadata() );
 227          wfRestoreWarnings();
 228          if ( isset( $xcfMeta['colorType'] ) && $xcfMeta['colorType'] === 'index-coloured' ) {
 229              return false;
 230          }
 231          return parent::canRender( $file );
 232      }
 233  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1