wfProfileOut() for new return added in c6396 (c4e407c)
[lhc/web/wiklou.git] / includes / media / XCF.php
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 * @file
11 * @ingroup Media
12 */
13
14 /**
15 * Handler for the Gimp's native file format; getimagesize() doesn't
16 * support these files
17 *
18 * @ingroup Media
19 */
20 class XCFHandler extends BitmapHandler {
21
22 /**
23 * @param $file
24 * @return bool
25 */
26 function mustRender( $file ) {
27 return true;
28 }
29
30 /**
31 * Render files as PNG
32 *
33 * @param $ext
34 * @param $mime
35 * @param $params
36 * @return array
37 */
38 function getThumbType( $ext, $mime, $params = null ) {
39 return array( 'png', 'image/png' );
40 }
41
42 /**
43 * Get width and height from the XCF header.
44 *
45 * @param $image
46 * @param $filename
47 * @return array
48 */
49 function getImageSize( $image, $filename ) {
50 return self::getXCFMetaData( $filename );
51 }
52
53 /**
54 * Metadata for a given XCF file
55 *
56 * Will return false if file magic signature is not recognized
57 * @author Hexmode
58 * @author Hashar
59 *
60 * @param $filename String Full path to a XCF file
61 * @return bool|array metadata array just like PHP getimagesize()
62 */
63 static function getXCFMetaData( $filename ) {
64 # Decode master structure
65 $f = fopen( $filename, 'rb' );
66 if( !$f ) {
67 return false;
68 }
69 # The image structure always starts at offset 0 in the XCF file.
70 # So we just read it :-)
71 $binaryHeader = fread( $f, 26 );
72 fclose($f);
73
74 # Master image structure:
75 #
76 # byte[9] "gimp xcf " File type magic
77 # byte[4] version XCF version
78 # "file" - version 0
79 # "v001" - version 1
80 # "v002" - version 2
81 # byte 0 Zero-terminator for version tag
82 # uint32 width With of canvas
83 # uint32 height Height of canvas
84 # uint32 base_type Color mode of the image; one of
85 # 0: RGB color
86 # 1: Grayscale
87 # 2: Indexed color
88 # (enum GimpImageBaseType in libgimpbase/gimpbaseenums.h)
89 try {
90 $header = wfUnpack(
91 "A9magic" # A: space padded
92 . "/a5version" # a: zero padded
93 . "/Nwidth" # \
94 . "/Nheight" # N: unsigned long 32bit big endian
95 . "/Nbase_type" # /
96 , $binaryHeader
97 );
98 } catch( MWException $mwe ) {
99 return false;
100 }
101
102 # Check values
103 if( $header['magic'] !== 'gimp xcf' ) {
104 wfDebug( __METHOD__ . " '$filename' has invalid magic signature.\n" );
105 return false;
106 }
107 # TODO: we might want to check for sane values of width and height
108
109 wfDebug( __METHOD__ . ": canvas size of '$filename' is {$header['width']} x {$header['height']} px\n" );
110
111 # Forge a return array containing metadata information just like getimagesize()
112 # See PHP documentation at: http://www.php.net/getimagesize
113 $metadata = array();
114 $metadata[0] = $header['width'];
115 $metadata[1] = $header['height'];
116 $metadata[2] = null; # IMAGETYPE constant, none exist for XCF.
117 $metadata[3] = sprintf(
118 'height="%s" width="%s"', $header['height'], $header['width']
119 );
120 $metadata['mime'] = 'image/x-xcf';
121 $metadata['channels'] = null;
122 $metadata['bits'] = 8; # Always 8-bits per color
123
124 assert( '7 == count($metadata); # return array must contains 7 elements just like getimagesize() return' );
125
126 return $metadata;
127 }
128
129 /**
130 * Must use "im" for XCF
131 *
132 * @return string
133 */
134 protected static function getScalerType( $dstPath, $checkDstPath = true ) {
135 return "im";
136 }
137 }