1<?php 2 3// A simple tool to scan for missed enum entries in the ImageMagick header files. 4// This code does not attempt to maintain BC across all ImageMagick versions. It 5// only needs to work against the latest version of ImageMagick 6 + 7. 6 7$directory = false; 8// Either pass in the directory to scan or set it here. 9// $directory = "/home/github/BastionRPM/zips/ImageMagick/ImageMagick-7.0.1-9"; 10// 'php ./scanHeaders.php ../imagemagick_src/ImageMagick-7.0.11-12' 11 12if ($directory) { 13 $pathToImageMagick = $directory; 14} 15else { 16 if ($argc != 2) { 17 echo "usage 'php scanHeaders.php /path/to/ImageMagick\n"; 18 exit(-1); 19 } 20 21 $pathToImageMagick = $argv[1]; 22} 23 24$pathToImageMagick .= '/'; 25 26 27 28if (file_exists($pathToImageMagick) == false || 29 is_dir($pathToImageMagick) == false) { 30 echo "Path $pathToImageMagick is not accessible.\n"; 31 exit(-1); 32} 33 34$includeDir = null; 35 36$directory = realpath($pathToImageMagick); 37 38// IM6 checks 39if (file_exists($directory.'/'.'magick') == true) { 40 $enumToCheck = [ 41 'magick/compare.h' => [ 42 'MetricType', 43 ], 44 'magick/colorspace.h' => [ 45 'ColorspaceType', 46 ], 47 'magick/composite.h' => [ 48 'CompositeOperator', 49 ], 50 'magick/compress.h' => [ 51 'CompressionType', 52 ], 53 'magick/distort.h' => [ 54 'DistortImageMethod', 55 'SparseColorMethod', 56 ], 57 'magick/effect.h' => [ 58 'PreviewType', 59 ], 60 'magick/fourier.h' => [ 61 // 'ComplexOperator', // used by ComplexImages - not exposed in wand api 62 ], 63 'magick/fx.h' => [ 64 'NoiseType', 65 ], 66 'magick/geometry.h' => [ 67 'GravityType', 68 ], 69 'magick/image.h' => [ 70 'AlphaChannelType', 71 'ImageType', 72 'InterlaceType', 73 'OrientationType', 74 'ResolutionType', 75 //'TransmitType', 76 ], 77 'magick/layer.h' => [ 78 'DisposeType', 79 'ImageLayerMethod', 80 ], 81 'magick/magick-type.h' => [ 82 'ChannelType', 83 ], 84 'magick/morphology.h' => [ 85 'KernelInfoType', 86 'MorphologyMethod' 87 ], 88 'magick/pixel.h' => [ 89 'InterpolatePixelMethod', 90 // 'PixelComponent', // present in 6.9.2 but not used? 91 // 'PixelIntensityMethod', //// Used by GrayscaleImage function that is not expose in wand api 92 ], 93 'magick/profile.h' => [ 94 'RenderingIntent', 95 ], 96 'magick/quantize.h' => [ 97 'DitherMethod', 98 ], 99 'magick/resample.h' => [ 100 'FilterTypes', 101 ], 102 'magick/resource_.h' => [ 103 'ResourceType' 104 ], 105 'magick/statistic.h' => [ 106 'MagickEvaluateOperator', 107 'MagickFunction', 108 'StatisticType', 109 ], 110 'magick/type.h' => [ 111 'StretchType', 112 'StyleType', 113 ], 114 ]; 115} 116// IM7 checks 117else if (file_exists($directory.'/'.'MagickCore') == true) { 118 $enumToCheck = [ 119 'MagickCore/cache-view.h' => [ 120 'VirtualPixelMethod', 121 ], 122 'MagickCore/compare.h' => [ 123 'MetricType', 124 ], 125 'MagickCore/colorspace.h' => [ 126 'ColorspaceType', 127 ], 128 'MagickCore/composite.h' => [ 129 'CompositeOperator', 130 ], 131 'MagickCore/compress.h' => [ 132 'CompressionType', 133 ], 134 'MagickCore/distort.h' => [ 135 'DistortMethod', 136 'SparseColorMethod', 137 ], 138 'MagickCore/draw.h' => [ 139 'AlignType', 140 "ClipPathUnits", 141 'DecorationType', 142 'DirectionType', 143 'FillRule', 144 'LineCap', 145 'LineJoin', 146 ], 147 'MagickCore/effect.h' => [ 148 'PreviewType', 149 ], 150 'MagickCore/fourier.h' => [ 151 // 'ComplexOperator', // used by ComplexImages - not exposed in wand api 152 ], 153 'MagickCore/geometry.h' => [ 154 // 'GeometryFlags', this is a nightmare of an 'enum' 155 'GravityType', 156 ], 157 'MagickCore/image.h' => [ 158 'AlphaChannelOption', 159 'ImageType', 160 'InterlaceType', 161 'OrientationType', 162 'ResolutionType', 163 //'TransmitType', 164 ], 165 'MagickCore/layer.h' => [ 166 'DisposeType', 167 'LayerMethod', 168 ], 169 'MagickCore/morphology.h' => [ 170 'KernelInfoType', 171 'MorphologyMethod' 172 ], 173 'MagickCore/pixel.h' => [ 174 'ChannelType', 175 'PixelInterpolateMethod', 176 // 'PixelComponent', // present in 6.9.2 but not used? 177 // 'PixelIntensityMethod', //// Used by GrayscaleImage function that is not expose in wand api 178 179 //'PixelTrait', no idea 180 'PixelMask', 181 // 'StorageType', This needs to be re-enabled, but also involves work getting 64bits to play nicely... 182 ], 183 'MagickCore/profile.h' => [ 184 'RenderingIntent', 185 ], 186 'MagickCore/quantize.h' => [ 187 'DitherMethod', 188 ], 189 'MagickCore/resample.h' => [ 190 'FilterType', 191 ], 192 'MagickCore/resource_.h' => [ 193 'ResourceType' 194 ], 195 'MagickCore/statistic.h' => [ 196 'MagickEvaluateOperator', 197 'MagickFunction', 198 'StatisticType', 199 ], 200 'MagickCore/type.h' => [ 201 'StretchType', 202 'StyleType', 203 ], 204 'MagickCore/visual-effects.h' => [ 205 'NoiseType', 206 ], 207 ]; 208} 209else { 210 echo "oops - couldn't figure out enums to check.\n"; 211 echo "Check what directories exist in $directory \n"; 212 exit(-1); 213} 214 215 216 217 218 219 220 221 222$imagickHelperContents = file_get_contents("../imagick_helpers.c"); 223 224if ($imagickHelperContents == false) { 225 echo "failed to read ../imagick_helpers.c\n"; 226 exit(-1); 227} 228 229// We don't use these enums currently. 230$skipEnumList = [ 231// 'ComplexOperator', // used by ComplexImages - not exposed in wand api 232// 'PixelComponent', // present in 6.9.2 but not used? 233// 'PixelIntensityMethod', // Used by GrayscaleImage function that is not expose in wand api 234]; 235 236 237foreach ($enumToCheck as $filename => $enums) { 238 foreach ($enums as $enum) { 239 if (in_array($enum, $skipEnumList)) { 240 //We don't use these enums currently. 241 continue; 242 } 243 244 $enumNameList = getEnumList($enum, $pathToImageMagick.$filename); 245 foreach ($enumNameList as $enumName) { 246 //echo "checking for $enumName\n"; 247 if (stripos($imagickHelperContents, $enumName) === false) { 248 echo "value '$enumName' is missing for enum $enum.\n"; 249 } 250 } 251 } 252} 253 254 255 256 257 258function getEnumList($enum, $filename) 259{ 260 $fileContents = file_get_contents($filename); 261 262 if ($fileContents === false) { 263 echo "Could not read file $filename \n"; 264 exit(-1); 265 } 266 267 // These characters mess with the matching. 268 $searchReplace = [ 269 ',' 270 ]; 271 272 $pregString = '#\{([^\{\}]*)\}\s*'.$enum.'#sU'; 273 274 preg_match($pregString, $fileContents, $matches); 275 276 if (count($matches) == 0) { 277 echo "Couldn't find enum $enum in $filename.\n"; 278 return []; 279 } 280 281 $match = $matches[1]; 282 283 foreach ($searchReplace as $search) { 284 $match = str_replace($search, '', $match); 285 } 286 287 $match = preg_replace('#/\*.*\*/#sU', '', $match); 288 289 $vars = explode("\n", $match); 290 291 $trimmedVars = []; 292 293 foreach ($vars as $var) { 294 if (stripos($var, 'Undefined') !== false) { 295 continue; 296 } 297 $equalsPosition = strpos($var, '='); 298 if ($equalsPosition !== false) { 299 $var = substr($var, 0, $equalsPosition); 300 } 301 302 $entry = trim($var); 303 304 if (strlen($entry) === 0) { 305 continue; 306 } 307 308 if (strpos($entry, '#') !== false) { 309 // skip things like '#undef EvenOddRule' 310 continue; 311 } 312 313 $trimmedVars[] = $entry; 314 } 315 316 return $trimmedVars; 317} 318