MediaWiki
REL1_24
|
00001 <?php 00035 class XCFHandler extends BitmapHandler { 00040 function mustRender( $file ) { 00041 return true; 00042 } 00043 00052 function getThumbType( $ext, $mime, $params = null ) { 00053 return array( 'png', 'image/png' ); 00054 } 00055 00063 function getImageSize( $image, $filename ) { 00064 $header = self::getXCFMetaData( $filename ); 00065 if ( !$header ) { 00066 return false; 00067 } 00068 00069 # Forge a return array containing metadata information just like getimagesize() 00070 # See PHP documentation at: http://www.php.net/getimagesize 00071 $metadata = array(); 00072 $metadata[0] = $header['width']; 00073 $metadata[1] = $header['height']; 00074 $metadata[2] = null; # IMAGETYPE constant, none exist for XCF. 00075 $metadata[3] = sprintf( 00076 'height="%s" width="%s"', $header['height'], $header['width'] 00077 ); 00078 $metadata['mime'] = 'image/x-xcf'; 00079 $metadata['channels'] = null; 00080 $metadata['bits'] = 8; # Always 8-bits per color 00081 00082 assert( '7 == count($metadata); ' . 00083 '# return array must contains 7 elements just like getimagesize() return' ); 00084 00085 return $metadata; 00086 } 00087 00098 static function getXCFMetaData( $filename ) { 00099 # Decode master structure 00100 $f = fopen( $filename, 'rb' ); 00101 if ( !$f ) { 00102 return false; 00103 } 00104 # The image structure always starts at offset 0 in the XCF file. 00105 # So we just read it :-) 00106 $binaryHeader = fread( $f, 26 ); 00107 fclose( $f ); 00108 00109 # Master image structure: 00110 # 00111 # byte[9] "gimp xcf " File type magic 00112 # byte[4] version XCF version 00113 # "file" - version 0 00114 # "v001" - version 1 00115 # "v002" - version 2 00116 # byte 0 Zero-terminator for version tag 00117 # uint32 width With of canvas 00118 # uint32 height Height of canvas 00119 # uint32 base_type Color mode of the image; one of 00120 # 0: RGB color 00121 # 1: Grayscale 00122 # 2: Indexed color 00123 # (enum GimpImageBaseType in libgimpbase/gimpbaseenums.h) 00124 try { 00125 $header = wfUnpack( 00126 "A9magic" . # A: space padded 00127 "/a5version" . # a: zero padded 00128 "/Nwidth" . # \ 00129 "/Nheight" . # N: unsigned long 32bit big endian 00130 "/Nbase_type", # / 00131 $binaryHeader 00132 ); 00133 } catch ( MWException $mwe ) { 00134 return false; 00135 } 00136 00137 # Check values 00138 if ( $header['magic'] !== 'gimp xcf' ) { 00139 wfDebug( __METHOD__ . " '$filename' has invalid magic signature.\n" ); 00140 00141 return false; 00142 } 00143 # TODO: we might want to check for sane values of width and height 00144 00145 wfDebug( __METHOD__ . 00146 ": canvas size of '$filename' is {$header['width']} x {$header['height']} px\n" ); 00147 00148 return $header; 00149 } 00150 00161 public function getMetadata( $file, $filename ) { 00162 $header = self::getXCFMetadata( $filename ); 00163 $metadata = array(); 00164 if ( $header ) { 00165 // Try to be consistent with the names used by PNG files. 00166 // Unclear from base media type if it has an alpha layer, 00167 // so just assume that it does since it "potentially" could. 00168 switch ( $header['base_type'] ) { 00169 case 0: 00170 $metadata['colorType'] = 'truecolour-alpha'; 00171 break; 00172 case 1: 00173 $metadata['colorType'] = 'greyscale-alpha'; 00174 break; 00175 case 2: 00176 $metadata['colorType'] = 'index-coloured'; 00177 break; 00178 default: 00179 $metadata['colorType'] = 'unknown'; 00180 00181 } 00182 } else { 00183 // Marker to prevent repeated attempted extraction 00184 $metadata['error'] = true; 00185 } 00186 return serialize( $metadata ); 00187 } 00188 00196 public function isMetadataValid( $file, $metadata ) { 00197 if ( !$metadata ) { 00198 // Old metadata when we just put an empty string in there 00199 return self::METADATA_BAD; 00200 } else { 00201 return self::METADATA_GOOD; 00202 } 00203 } 00204 00212 protected function getScalerType( $dstPath, $checkDstPath = true ) { 00213 return "im"; 00214 } 00215 00224 public function canRender( $file ) { 00225 wfSuppressWarnings(); 00226 $xcfMeta = unserialize( $file->getMetadata() ); 00227 wfRestoreWarnings(); 00228 if ( isset( $xcfMeta['colorType'] ) && $xcfMeta['colorType'] === 'index-coloured' ) { 00229 return false; 00230 } 00231 return parent::canRender( $file ); 00232 } 00233 }