1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % % 7 % V V AAA L IIIII DDDD AAA TTTTT EEEEE % 8 % V V A A L I D D A A T E % 9 % V V AAAAA L I D D AAAAA T EEE % 10 % V V A A L I D D A A T E % 11 % V A A LLLLL IIIII DDDD A A T EEEEE % 12 % % 13 % % 14 % ImageMagick Validation Suite % 15 % % 16 % Software Design % 17 % Cristy % 18 % March 2001 % 19 % % 20 % % 21 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 22 % dedicated to making software imaging solutions freely available. % 23 % % 24 % You may not use this file except in compliance with the License. You may % 25 % obtain a copy of the License at % 26 % % 27 % http://www.imagemagick.org/script/license.php % 28 % % 29 % Unless required by applicable law or agreed to in writing, software % 30 % distributed under the License is distributed on an "AS IS" BASIS, % 31 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 32 % see the License for the specific language governing permissions and % 33 % limitations under the License. % 34 % % 35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 36 % 37 % 38 */ 39 40 /* 42 Include declarations. 43 */ 44 #include <stdio.h> 45 #include <stdlib.h> 46 #include <string.h> 47 #include <ctype.h> 48 #include <math.h> 49 #include <locale.h> 50 #include "MagickWand/MagickWand.h" 51 #include "MagickCore/colorspace-private.h" 52 #include "MagickCore/gem.h" 53 #include "MagickCore/resource_.h" 54 #include "MagickCore/string-private.h" 55 #include "validate.h" 56 57 /* 59 Define declarations. 60 */ 61 #define CIEEpsilon (216.0/24389.0) 62 #define CIEK (24389.0/27.0) 63 #define D65X 0.950456 64 #define D65Y 1.0 65 #define D65Z 1.088754 66 #define ReferenceEpsilon (QuantumRange*1.0e-2) 67 68 /* 70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71 % % 72 % % 73 % % 74 % V a l i d a t e C o l o r s p a c e s % 75 % % 76 % % 77 % % 78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 79 % 80 % ValidateColorspaces() validates the ImageMagick colorspaces and returns the 81 % number of validation tests that passed and failed. 82 % 83 % The format of the ValidateColorspaces method is: 84 % 85 % size_t ValidateColorspaces(ImageInfo *image_info,size_t *fail, 86 % ExceptionInfo *exception) 87 % 88 % A description of each parameter follows: 89 % 90 % o image_info: the image info. 91 % 92 % o fail: return the number of validation tests that pass. 93 % 94 % o exception: return any errors or warnings in this structure. 95 % 96 */ 97 98 static void ConvertHSIToRGB(const double hue,const double saturation, 99 const double intensity,double *red,double *green,double *blue) 100 { 101 double 102 h; 103 104 h=360.0*hue; 105 h-=360.0*floor(h/360.0); 106 if (h < 120.0) 107 { 108 *blue=intensity*(1.0-saturation); 109 *red=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 110 (MagickPI/180.0))); 111 *green=3.0*intensity-*red-*blue; 112 } 113 else 114 if (h < 240.0) 115 { 116 h-=120.0; 117 *red=intensity*(1.0-saturation); 118 *green=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 119 (MagickPI/180.0))); 120 *blue=3.0*intensity-*red-*green; 121 } 122 else 123 { 124 h-=240.0; 125 *green=intensity*(1.0-saturation); 126 *blue=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)* 127 (MagickPI/180.0))); 128 *red=3.0*intensity-*green-*blue; 129 } 130 *red*=QuantumRange; 131 *green*=QuantumRange; 132 *blue*=QuantumRange; 133 } 134 135 static void ConvertRGBToHSI(const double red,const double green, 136 const double blue,double *hue,double *saturation,double *intensity) 137 { 138 double 139 alpha, 140 beta; 141 142 *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0; 143 if (*intensity <= 0.0) 144 { 145 *hue=0.0; 146 *saturation=0.0; 147 return; 148 } 149 *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green, 150 QuantumScale*blue))/(*intensity); 151 alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue); 152 beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue); 153 *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0; 154 if (*hue < 0.0) 155 *hue+=1.0; 156 } 157 158 static void ConvertHSVToRGB(const double hue,const double saturation, 159 const double value,double *red,double *green,double *blue) 160 { 161 double 162 c, 163 h, 164 min, 165 x; 166 167 h=hue*360.0; 168 c=value*saturation; 169 min=value-c; 170 h-=360.0*floor(h/360.0); 171 h/=60.0; 172 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0)); 173 switch ((int) floor(h)) 174 { 175 case 0: 176 { 177 *red=QuantumRange*(min+c); 178 *green=QuantumRange*(min+x); 179 *blue=QuantumRange*min; 180 break; 181 } 182 case 1: 183 { 184 *red=QuantumRange*(min+x); 185 *green=QuantumRange*(min+c); 186 *blue=QuantumRange*min; 187 break; 188 } 189 case 2: 190 { 191 *red=QuantumRange*min; 192 *green=QuantumRange*(min+c); 193 *blue=QuantumRange*(min+x); 194 break; 195 } 196 case 3: 197 { 198 *red=QuantumRange*min; 199 *green=QuantumRange*(min+x); 200 *blue=QuantumRange*(min+c); 201 break; 202 } 203 case 4: 204 { 205 *red=QuantumRange*(min+x); 206 *green=QuantumRange*min; 207 *blue=QuantumRange*(min+c); 208 break; 209 } 210 case 5: 211 { 212 *red=QuantumRange*(min+c); 213 *green=QuantumRange*min; 214 *blue=QuantumRange*(min+x); 215 break; 216 } 217 default: 218 { 219 *red=0.0; 220 *green=0.0; 221 *blue=0.0; 222 } 223 } 224 } 225 226 static inline void ConvertRGBToXYZ(const double red,const double green, 227 const double blue,double *X,double *Y,double *Z) 228 { 229 double 230 b, 231 g, 232 r; 233 234 r=QuantumScale*DecodePixelGamma(red); 235 g=QuantumScale*DecodePixelGamma(green); 236 b=QuantumScale*DecodePixelGamma(blue); 237 *X=0.41239558896741421610*r+0.35758343076371481710*g+0.18049264738170157350*b; 238 *Y=0.21258623078559555160*r+0.71517030370341084990*g+0.07220049864333622685*b; 239 *Z=0.01929721549174694484*r+0.11918386458084853180*g+0.95049712513157976600*b; 240 } 241 242 static inline void ConvertXYZToLab(const double X,const double Y,const double Z, 243 double *L,double *a,double *b) 244 { 245 double 246 x, 247 y, 248 z; 249 250 if ((X/D65X) > CIEEpsilon) 251 x=pow(X/D65X,1.0/3.0); 252 else 253 x=(CIEK*X/D65X+16.0)/116.0; 254 if ((Y/D65Y) > CIEEpsilon) 255 y=pow(Y/D65Y,1.0/3.0); 256 else 257 y=(CIEK*Y/D65Y+16.0)/116.0; 258 if ((Z/D65Z) > CIEEpsilon) 259 z=pow(Z/D65Z,1.0/3.0); 260 else 261 z=(CIEK*Z/D65Z+16.0)/116.0; 262 *L=((116.0*y)-16.0)/100.0; 263 *a=(500.0*(x-y))/255.0+0.5; 264 *b=(200.0*(y-z))/255.0+0.5; 265 } 266 267 static void ConvertRGBToLab(const double red,const double green, 268 const double blue,double *L,double *a,double *b) 269 { 270 double 271 X, 272 Y, 273 Z; 274 275 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 276 ConvertXYZToLab(X,Y,Z,L,a,b); 277 } 278 279 static inline void ConvertLabToXYZ(const double L,const double a,const double b, 280 double *X,double *Y,double *Z) 281 { 282 double 283 x, 284 y, 285 z; 286 287 y=(L+16.0)/116.0; 288 x=y+a/500.0; 289 z=y-b/200.0; 290 if ((x*x*x) > CIEEpsilon) 291 x=(x*x*x); 292 else 293 x=(116.0*x-16.0)/CIEK; 294 if ((y*y*y) > CIEEpsilon) 295 y=(y*y*y); 296 else 297 y=L/CIEK; 298 if ((z*z*z) > CIEEpsilon) 299 z=(z*z*z); 300 else 301 z=(116.0*z-16.0)/CIEK; 302 *X=D65X*x; 303 *Y=D65Y*y; 304 *Z=D65Z*z; 305 } 306 307 static inline void ConvertXYZToRGB(const double x,const double y,const double z, 308 double *red,double *green,double *blue) 309 { 310 double 311 b, 312 g, 313 r; 314 315 r=3.2406*x-1.5372*y-0.4986*z; 316 g=(-0.9689*x+1.8758*y+0.0415*z); 317 b=0.0557*x-0.2040*y+1.0570*z; 318 *red=EncodePixelGamma(QuantumRange*r); 319 *green=EncodePixelGamma(QuantumRange*g); 320 *blue=EncodePixelGamma(QuantumRange*b); 321 } 322 323 static inline void ConvertLabToRGB(const double L,const double a, 324 const double b,double *red,double *green,double *blue) 325 { 326 double 327 X, 328 Y, 329 Z; 330 331 ConvertLabToXYZ(L*100.0,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z); 332 ConvertXYZToRGB(X,Y,Z,red,green,blue); 333 } 334 335 static void ConvertRGBToYPbPr(const double red,const double green, 336 const double blue,double *Y,double *Pb,double *Pr) 337 { 338 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 339 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5; 340 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5; 341 } 342 343 static void ConvertRGBToYCbCr(const double red,const double green, 344 const double blue,double *Y,double *Cb,double *Cr) 345 { 346 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr); 347 } 348 349 static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr, 350 double *red,double *green,double *blue) 351 { 352 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+ 353 1.4019995886561440468*(Pr-0.5)); 354 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)- 355 0.71413649331646789076*(Pr-0.5)); 356 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+ 357 2.1453384174593273e-06*(Pr-0.5)); 358 } 359 360 static void ConvertYCbCrToRGB(const double Y,const double Cb, 361 const double Cr,double *red,double *green,double *blue) 362 { 363 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue); 364 } 365 366 static inline void ConvertLCHabToXYZ(const double luma,const double chroma, 367 const double hue,double *X,double *Y,double *Z) 368 { 369 ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma* 370 sin(hue*MagickPI/180.0),X,Y,Z); 371 } 372 373 static void ConvertLCHabToRGB(const double luma,const double chroma, 374 const double hue,double *red,double *green,double *blue) 375 { 376 double 377 X, 378 Y, 379 Z; 380 381 ConvertLCHabToXYZ(luma*100.0,255.0*(chroma-0.5),360.0*hue,&X,&Y,&Z); 382 ConvertXYZToRGB(X,Y,Z,red,green,blue); 383 } 384 385 static void ConvertRGBToHSV(const double red,const double green, 386 const double blue,double *hue,double *saturation,double *value) 387 { 388 double 389 c, 390 max, 391 min; 392 393 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green, 394 QuantumScale*blue)); 395 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green, 396 QuantumScale*blue)); 397 c=max-min; 398 *value=max; 399 if (c <= 0.0) 400 { 401 *hue=0.0; 402 *saturation=0.0; 403 return; 404 } 405 if (max == (QuantumScale*red)) 406 { 407 *hue=(QuantumScale*green-QuantumScale*blue)/c; 408 if ((QuantumScale*green) < (QuantumScale*blue)) 409 *hue+=6.0; 410 } 411 else 412 if (max == (QuantumScale*green)) 413 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c; 414 else 415 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c; 416 *hue*=60.0/360.0; 417 *saturation=c/max; 418 } 419 420 static inline void ConvertXYZToLCHab(const double X,const double Y, 421 const double Z,double *luma,double *chroma,double *hue) 422 { 423 double 424 a, 425 b; 426 427 ConvertXYZToLab(X,Y,Z,luma,&a,&b); 428 *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5))/255.0+0.5; 429 *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI/360.0; 430 if (*hue < 0.0) 431 *hue+=1.0; 432 } 433 434 static void ConvertRGBToLCHab(const double red,const double green, 435 const double blue,double *luma,double *chroma,double *hue) 436 { 437 double 438 X, 439 Y, 440 Z; 441 442 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 443 ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue); 444 } 445 446 static inline void ConvertLMSToXYZ(const double L,const double M,const double S, 447 double *X,double *Y,double *Z) 448 { 449 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S; 450 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S; 451 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S; 452 } 453 454 static inline void ConvertLMSToRGB(const double L,const double M, 455 const double S,double *red,double *green,double *blue) 456 { 457 double 458 X, 459 Y, 460 Z; 461 462 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z); 463 ConvertXYZToRGB(X,Y,Z,red,green,blue); 464 } 465 466 static inline void ConvertXYZToLMS(const double x,const double y, 467 const double z,double *L,double *M,double *S) 468 { 469 *L=0.7328*x+0.4296*y-0.1624*z; 470 *M=(-0.7036*x+1.6975*y+0.0061*z); 471 *S=0.0030*x+0.0136*y+0.9834*z; 472 } 473 474 static void ConvertRGBToLMS(const double red,const double green, 475 const double blue,double *L,double *M,double *S) 476 { 477 double 478 X, 479 Y, 480 Z; 481 482 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 483 ConvertXYZToLMS(X,Y,Z,L,M,S); 484 } 485 486 static inline void ConvertXYZToLuv(const double X,const double Y,const double Z, 487 double *L,double *u,double *v) 488 { 489 double 490 alpha; 491 492 if ((Y/D65Y) > CIEEpsilon) 493 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0); 494 else 495 *L=CIEK*(Y/D65Y); 496 alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z); 497 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))); 498 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))); 499 *L/=100.0; 500 *u=(*u+134.0)/354.0; 501 *v=(*v+140.0)/262.0; 502 } 503 504 static void ConvertRGBToLuv(const double red,const double green, 505 const double blue,double *L,double *u,double *v) 506 { 507 double 508 X, 509 Y, 510 Z; 511 512 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z); 513 ConvertXYZToLuv(X,Y,Z,L,u,v); 514 } 515 516 static inline void ConvertLuvToXYZ(const double L,const double u,const double v, 517 double *X,double *Y,double *Z) 518 { 519 if (L > (CIEK*CIEEpsilon)) 520 *Y=(double) pow((L+16.0)/116.0,3.0); 521 else 522 *Y=L/CIEK; 523 *X=((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+ 524 5.0*(*Y))/((((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/ 525 3.0)-(-1.0/3.0)); 526 *Z=(*X*(((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))- 527 5.0*(*Y); 528 } 529 530 static inline void ConvertLuvToRGB(const double L,const double u, 531 const double v,double *red,double *green,double *blue) 532 { 533 double 534 X, 535 Y, 536 Z; 537 538 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z); 539 ConvertXYZToRGB(X,Y,Z,red,green,blue); 540 } 541 542 static void ConvertRGBToYDbDr(const double red,const double green, 543 const double blue,double *Y,double *Db,double *Dr) 544 { 545 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 546 *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5; 547 *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5; 548 } 549 550 static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr, 551 double *red,double *green,double *blue) 552 { 553 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-0.52591263066186533* 554 (Dr-0.5)); 555 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+0.26789932820759876* 556 (Dr-0.5)); 557 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-7.9202543533108e-05* 558 (Dr-0.5)); 559 } 560 561 static void ConvertRGBToYIQ(const double red,const double green, 562 const double blue,double *Y,double *I,double *Q) 563 { 564 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 565 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5; 566 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5; 567 } 568 569 static void ConvertYIQToRGB(const double Y,const double I,const double Q, 570 double *red,double *green,double *blue) 571 { 572 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754* 573 (Q-0.5)); 574 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427* 575 (Q-0.5)); 576 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374* 577 (Q-0.5)); 578 } 579 580 static void ConvertRGBToYUV(const double red,const double green, 581 const double blue,double *Y,double *U,double *V) 582 { 583 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue); 584 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5; 585 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5; 586 } 587 588 static void ConvertYUVToRGB(const double Y,const double U,const double V, 589 double *red,double *green,double *blue) 590 { 591 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825* 592 (V-0.5)); 593 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797* 594 (V-0.5)); 595 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04* 596 (V-0.5)); 597 } 598 599 static MagickBooleanType ValidateHSIToRGB() 600 { 601 double 602 r, 603 g, 604 b; 605 606 (void) FormatLocaleFile(stdout," HSIToRGB"); 607 ConvertHSIToRGB(111.244375/360.0,0.295985,0.658734,&r,&g,&b); 608 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 609 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 610 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 611 return(MagickFalse); 612 return(MagickTrue); 613 } 614 615 static MagickBooleanType ValidateRGBToHSI() 616 { 617 double 618 h, 619 i, 620 s; 621 622 (void) FormatLocaleFile(stdout," RGBToHSI"); 623 ConvertRGBToHSI(0.545877*QuantumRange,0.966567*QuantumRange, 624 0.463759*QuantumRange,&h,&s,&i); 625 if ((fabs(h-111.244374/360.0) >= ReferenceEpsilon) || 626 (fabs(s-0.295985) >= ReferenceEpsilon) || 627 (fabs(i-0.658734) >= ReferenceEpsilon)) 628 return(MagickFalse); 629 return(MagickTrue); 630 } 631 632 static MagickBooleanType ValidateHSLToRGB() 633 { 634 double 635 r, 636 g, 637 b; 638 639 (void) FormatLocaleFile(stdout," HSLToRGB"); 640 ConvertHSLToRGB(110.200859/360.0,0.882623,0.715163,&r,&g,&b); 641 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 642 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 643 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 644 return(MagickFalse); 645 return(MagickTrue); 646 } 647 648 static MagickBooleanType ValidateRGBToHSL() 649 { 650 double 651 h, 652 l, 653 s; 654 655 (void) FormatLocaleFile(stdout," RGBToHSL"); 656 ConvertRGBToHSL(0.545877*QuantumRange,0.966567*QuantumRange, 657 0.463759*QuantumRange,&h,&s,&l); 658 if ((fabs(h-110.200859/360.0) >= ReferenceEpsilon) || 659 (fabs(s-0.882623) >= ReferenceEpsilon) || 660 (fabs(l-0.715163) >= ReferenceEpsilon)) 661 return(MagickFalse); 662 return(MagickTrue); 663 } 664 665 static MagickBooleanType ValidateHSVToRGB() 666 { 667 double 668 r, 669 g, 670 b; 671 672 (void) FormatLocaleFile(stdout," HSVToRGB"); 673 ConvertHSVToRGB(110.200859/360.0,0.520200,0.966567,&r,&g,&b); 674 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 675 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 676 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 677 return(MagickFalse); 678 return(MagickTrue); 679 } 680 681 static MagickBooleanType ValidateRGBToHSV() 682 { 683 double 684 h, 685 s, 686 v; 687 688 (void) FormatLocaleFile(stdout," RGBToHSV"); 689 ConvertRGBToHSV(0.545877*QuantumRange,0.966567*QuantumRange, 690 0.463759*QuantumRange,&h,&s,&v); 691 if ((fabs(h-110.200859/360.0) >= ReferenceEpsilon) || 692 (fabs(s-0.520200) >= ReferenceEpsilon) || 693 (fabs(v-0.966567) >= ReferenceEpsilon)) 694 return(MagickFalse); 695 return(MagickTrue); 696 } 697 698 static MagickBooleanType ValidateRGBToJPEGYCbCr() 699 { 700 double 701 Cb, 702 Cr, 703 Y; 704 705 (void) FormatLocaleFile(stdout," RGBToJPEGYCbCr"); 706 ConvertRGBToYCbCr(0.545877*QuantumRange,0.966567*QuantumRange, 707 0.463759*QuantumRange,&Y,&Cb,&Cr); 708 if ((fabs(Y-0.783460) >= ReferenceEpsilon) || 709 (fabs(Cb-0.319581) >= ReferenceEpsilon) || 710 (fabs(Cr-0.330539) >= ReferenceEpsilon)) 711 return(MagickFalse); 712 return(MagickTrue); 713 } 714 715 static MagickBooleanType ValidateJPEGYCbCrToRGB() 716 { 717 double 718 r, 719 g, 720 b; 721 722 (void) FormatLocaleFile(stdout," JPEGYCbCrToRGB"); 723 ConvertYCbCrToRGB(0.783460,0.319581,0.330539,&r,&g,&b); 724 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 725 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 726 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 727 return(MagickFalse); 728 return(MagickTrue); 729 } 730 731 static MagickBooleanType ValidateLabToRGB() 732 { 733 double 734 r, 735 g, 736 b; 737 738 (void) FormatLocaleFile(stdout," LabToRGB"); 739 ConvertLabToRGB(88.456154/100.0,-54.671483/255+0.5,51.662818/255.0+0.5, 740 &r,&g,&b); 741 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 742 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 743 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 744 return(MagickFalse); 745 return(MagickTrue); 746 } 747 748 static MagickBooleanType ValidateRGBToLab() 749 { 750 double 751 a, 752 b, 753 L; 754 755 (void) FormatLocaleFile(stdout," RGBToLab"); 756 ConvertRGBToLab(0.545877*QuantumRange,0.966567*QuantumRange, 757 0.463759*QuantumRange,&L,&a,&b); 758 if ((fabs(L-(88.456154/100.0)) >= ReferenceEpsilon) || 759 (fabs(a-(-54.671483/255.0+0.5)) >= ReferenceEpsilon) || 760 (fabs(b-(51.662818/255.0+0.5)) >= ReferenceEpsilon)) 761 return(MagickFalse); 762 return(MagickTrue); 763 } 764 765 static MagickBooleanType ValidateLchToRGB() 766 { 767 double 768 b, 769 g, 770 r; 771 772 (void) FormatLocaleFile(stdout," LchToRGB"); 773 ConvertLCHabToRGB(88.456154/100.0,75.219797/255.0+0.5,136.620717/360.0, 774 &r,&g,&b); 775 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 776 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 777 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 778 return(MagickFalse); 779 return(MagickTrue); 780 } 781 782 static MagickBooleanType ValidateRGBToLch() 783 { 784 double 785 c, 786 h, 787 L; 788 789 (void) FormatLocaleFile(stdout," RGBToLch"); 790 ConvertRGBToLCHab(0.545877*QuantumRange,0.966567*QuantumRange, 791 0.463759*QuantumRange,&L,&c,&h); 792 if ((fabs(L-88.456154/100.0) >= ReferenceEpsilon) || 793 (fabs(c-(75.219797/255.0+0.5)) >= ReferenceEpsilon) || 794 (fabs(h-(136.620717/255.0+0.5)) >= ReferenceEpsilon)) 795 return(MagickFalse); 796 return(MagickTrue); 797 } 798 799 static MagickBooleanType ValidateRGBToLMS() 800 { 801 double 802 L, 803 M, 804 S; 805 806 (void) FormatLocaleFile(stdout," RGBToLMS"); 807 ConvertRGBToLMS(0.545877*QuantumRange,0.966567*QuantumRange, 808 0.463759*QuantumRange,&L,&M,&S); 809 if ((fabs(L-0.611749) >= ReferenceEpsilon) || 810 (fabs(M-0.910088) >= ReferenceEpsilon) || 811 (fabs(S-0.294880) >= ReferenceEpsilon)) 812 return(MagickFalse); 813 return(MagickTrue); 814 } 815 816 static MagickBooleanType ValidateLMSToRGB() 817 { 818 double 819 r, 820 g, 821 b; 822 823 (void) FormatLocaleFile(stdout," LMSToRGB"); 824 ConvertLMSToRGB(0.611749,0.910088,0.294880,&r,&g,&b); 825 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 826 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 827 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 828 return(MagickFalse); 829 return(MagickTrue); 830 } 831 832 static MagickBooleanType ValidateRGBToLuv() 833 { 834 double 835 l, 836 u, 837 v; 838 839 (void) FormatLocaleFile(stdout," RGBToLuv"); 840 ConvertRGBToLuv(0.545877*QuantumRange,0.966567*QuantumRange, 841 0.463759*QuantumRange,&l,&u,&v); 842 if ((fabs(l-88.456154/262.0) >= ReferenceEpsilon) || 843 (fabs(u-(-51.330414+134.0)/354.0) >= ReferenceEpsilon) || 844 (fabs(v-(76.405526+140.0)/262.0) >= ReferenceEpsilon)) 845 return(MagickFalse); 846 return(MagickTrue); 847 } 848 849 static MagickBooleanType ValidateLuvToRGB() 850 { 851 double 852 r, 853 g, 854 b; 855 856 (void) FormatLocaleFile(stdout," LuvToRGB"); 857 ConvertLuvToRGB(88.456154/100.0,(-51.330414+134.0)/354.0, 858 (76.405526+140.0)/262.0,&r,&g,&b); 859 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 860 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 861 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 862 return(MagickFalse); 863 return(MagickTrue); 864 } 865 866 static MagickBooleanType ValidateRGBToXYZ() 867 { 868 double 869 x, 870 y, 871 z; 872 873 (void) FormatLocaleFile(stdout," RGBToXYZ"); 874 ConvertRGBToXYZ(0.545877*QuantumRange,0.966567*QuantumRange, 875 0.463759*QuantumRange,&x,&y,&z); 876 if ((fabs(x-0.470646) >= ReferenceEpsilon) || 877 (fabs(y-0.730178) >= ReferenceEpsilon) || 878 (fabs(z-0.288324) >= ReferenceEpsilon)) 879 return(MagickFalse); 880 return(MagickTrue); 881 } 882 883 static MagickBooleanType ValidateXYZToRGB() 884 { 885 double 886 r, 887 g, 888 b; 889 890 (void) FormatLocaleFile(stdout," XYZToRGB"); 891 ConvertXYZToRGB(0.470646,0.730178,0.288324,&r,&g,&b); 892 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 893 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 894 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 895 return(MagickFalse); 896 return(MagickTrue); 897 } 898 899 static MagickBooleanType ValidateYDbDrToRGB() 900 { 901 double 902 r, 903 g, 904 b; 905 906 (void) FormatLocaleFile(stdout," YDbDrToRGB"); 907 ConvertYDbDrToRGB(0.783460,-0.480932+0.5,0.451670+0.5,&r,&g,&b); 908 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 909 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 910 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 911 return(MagickFalse); 912 return(MagickTrue); 913 } 914 915 static MagickBooleanType ValidateRGBToYDbDr() 916 { 917 double 918 Db, 919 Dr, 920 Y; 921 922 (void) FormatLocaleFile(stdout," RGBToYDbDr"); 923 ConvertRGBToYDbDr(0.545877*QuantumRange,0.966567*QuantumRange, 924 0.463759*QuantumRange,&Y,&Db,&Dr); 925 if ((fabs(Y-0.783460) >= ReferenceEpsilon) || 926 (fabs(Db-(-0.480932)) >= ReferenceEpsilon) || 927 (fabs(Dr-0.451670) >= ReferenceEpsilon)) 928 return(MagickFalse); 929 return(MagickTrue); 930 } 931 932 static MagickBooleanType ValidateRGBToYIQ() 933 { 934 double 935 i, 936 q, 937 y; 938 939 (void) FormatLocaleFile(stdout," RGBToYIQ"); 940 ConvertRGBToYIQ(0.545877*QuantumRange,0.966567*QuantumRange, 941 0.463759*QuantumRange,&y,&i,&q); 942 if ((fabs(y-0.783460) >= ReferenceEpsilon) || 943 (fabs(i-(-0.089078)) >= ReferenceEpsilon) || 944 (fabs(q-(-0.245399)) >= ReferenceEpsilon)) 945 return(MagickFalse); 946 return(MagickTrue); 947 } 948 949 static MagickBooleanType ValidateYIQToRGB() 950 { 951 double 952 r, 953 g, 954 b; 955 956 (void) FormatLocaleFile(stdout," YIQToRGB"); 957 ConvertYIQToRGB(0.783460,-0.089078+0.5,-0.245399+0.5,&r,&g,&b); 958 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 959 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 960 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 961 return(MagickFalse); 962 return(MagickTrue); 963 } 964 965 static MagickBooleanType ValidateRGBToYPbPr() 966 { 967 double 968 Pb, 969 Pr, 970 y; 971 972 (void) FormatLocaleFile(stdout," RGBToYPbPr"); 973 ConvertRGBToYPbPr(0.545877*QuantumRange,0.966567*QuantumRange, 974 0.463759*QuantumRange,&y,&Pb,&Pr); 975 if ((fabs(y-0.783460) >= ReferenceEpsilon) || 976 (fabs(Pb-(-0.180419)) >= ReferenceEpsilon) || 977 (fabs(Pr-(-0.169461)) >= ReferenceEpsilon)) 978 return(MagickFalse); 979 return(MagickTrue); 980 } 981 982 static MagickBooleanType ValidateYPbPrToRGB() 983 { 984 double 985 r, 986 g, 987 b; 988 989 (void) FormatLocaleFile(stdout," YPbPrToRGB"); 990 ConvertYPbPrToRGB(0.783460,-0.180419+0.5,-0.169461+0.5,&r,&g,&b); 991 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 992 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 993 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 994 return(MagickFalse); 995 return(MagickTrue); 996 } 997 998 static MagickBooleanType ValidateRGBToYUV() 999 { 1000 double 1001 U, 1002 V, 1003 Y; 1004 1005 (void) FormatLocaleFile(stdout," RGBToYUV"); 1006 ConvertRGBToYUV(0.545877*QuantumRange,0.966567*QuantumRange, 1007 0.463759*QuantumRange,&Y,&U,&V); 1008 if ((fabs(Y-0.783460) >= ReferenceEpsilon) || 1009 (fabs(U-(-0.157383)) >= ReferenceEpsilon) || 1010 (fabs(V-(-0.208443)) >= ReferenceEpsilon)) 1011 return(MagickFalse); 1012 return(MagickTrue); 1013 } 1014 1015 static MagickBooleanType ValidateYUVToRGB() 1016 { 1017 double 1018 r, 1019 g, 1020 b; 1021 1022 (void) FormatLocaleFile(stdout," YUVToRGB"); 1023 ConvertYUVToRGB(0.783460,-0.157383+0.5,-0.208443+0.5,&r,&g,&b); 1024 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) || 1025 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) || 1026 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon)) 1027 return(MagickFalse); 1028 return(MagickTrue); 1029 } 1030 1031 static size_t ValidateColorspaces(ImageInfo *image_info,size_t *fail, 1032 ExceptionInfo *exception) 1033 { 1034 MagickBooleanType 1035 status; 1036 1037 size_t 1038 test; 1039 1040 /* 1041 Reference: https://code.google.com/p/chroma. 1042 1043 Illuminant = D65 1044 Observer = 2 (1931) 1045 1046 XYZ 0.470645, 0.730177, 0.288323 1047 sRGB 0.545877, 0.966567, 0.463759 1048 CAT02 LMS 0.611749, 0.910088, 0.294880 1049 Y'DbDr 0.783460, -0.480932, 0.451670 1050 Y'IQ 0.783460, -0.089078, -0.245399 1051 Y'PbPr 0.783460, -0.180419, -0.169461 1052 Y'UV 0.783460, -0.157383, -0.208443 1053 JPEG-Y'CbCr 0.783460, 0.319581, 0.330539 1054 L*u*v* 88.456154, -51.330414, 76.405526 1055 L*a*b* 88.456154, -54.671483, 51.662818 1056 L*C*H* 88.456154, 75.219797, 136.620717 1057 HSV 110.200859, 0.520200, 0.966567 1058 HSL 110.200859, 0.882623, 0.715163 1059 HSI 111.244375, 0.295985, 0.658734 1060 Y'CbCr 187.577791, 87.586330, 90.040886 1061 */ 1062 (void) FormatLocaleFile(stdout,"validate colorspaces:\n"); 1063 for (test=0; test < 26; test++) 1064 { 1065 CatchException(exception); 1066 (void) FormatLocaleFile(stdout," test %.20g: ",(double) test); 1067 switch (test) 1068 { 1069 case 0: status=ValidateHSIToRGB(); break; 1070 case 1: status=ValidateRGBToHSI(); break; 1071 case 2: status=ValidateHSLToRGB(); break; 1072 case 3: status=ValidateRGBToHSL(); break; 1073 case 4: status=ValidateHSVToRGB(); break; 1074 case 5: status=ValidateRGBToHSV(); break; 1075 case 6: status=ValidateJPEGYCbCrToRGB(); break; 1076 case 7: status=ValidateRGBToJPEGYCbCr(); break; 1077 case 8: status=ValidateLabToRGB(); break; 1078 case 9: status=ValidateRGBToLab(); break; 1079 case 10: status=ValidateLchToRGB(); break; 1080 case 11: status=ValidateRGBToLch(); break; 1081 case 12: status=ValidateLMSToRGB(); break; 1082 case 13: status=ValidateRGBToLMS(); break; 1083 case 14: status=ValidateLuvToRGB(); break; 1084 case 15: status=ValidateRGBToLuv(); break; 1085 case 16: status=ValidateXYZToRGB(); break; 1086 case 17: status=ValidateRGBToXYZ(); break; 1087 case 18: status=ValidateYDbDrToRGB(); break; 1088 case 19: status=ValidateRGBToYDbDr(); break; 1089 case 20: status=ValidateYIQToRGB(); break; 1090 case 21: status=ValidateRGBToYIQ(); break; 1091 case 22: status=ValidateYPbPrToRGB(); break; 1092 case 23: status=ValidateRGBToYPbPr(); break; 1093 case 24: status=ValidateYUVToRGB(); break; 1094 case 25: status=ValidateRGBToYUV(); break; 1095 default: status=MagickFalse; 1096 } 1097 if (status == MagickFalse) 1098 { 1099 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1100 GetMagickModule()); 1101 (*fail)++; 1102 continue; 1103 } 1104 (void) FormatLocaleFile(stdout,"... pass.\n"); 1105 } 1106 (void) FormatLocaleFile(stdout, 1107 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1108 (double) (test-(*fail)),(double) *fail); 1109 return(test); 1110 } 1111 1112 /* 1114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1115 % % 1116 % % 1117 % % 1118 % V a l i d a t e C o m p a r e C o m m a n d % 1119 % % 1120 % % 1121 % % 1122 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1123 % 1124 % ValidateCompareCommand() validates the ImageMagick compare command line 1125 % program and returns the number of validation tests that passed and failed. 1126 % 1127 % The format of the ValidateCompareCommand method is: 1128 % 1129 % size_t ValidateCompareCommand(ImageInfo *image_info, 1130 % const char *reference_filename,const char *output_filename, 1131 % size_t *fail,ExceptionInfo *exception) 1132 % 1133 % A description of each parameter follows: 1134 % 1135 % o image_info: the image info. 1136 % 1137 % o reference_filename: the reference image filename. 1138 % 1139 % o output_filename: the output image filename. 1140 % 1141 % o fail: return the number of validation tests that pass. 1142 % 1143 % o exception: return any errors or warnings in this structure. 1144 % 1145 */ 1146 static size_t ValidateCompareCommand(ImageInfo *image_info, 1147 const char *reference_filename,const char *output_filename,size_t *fail, 1148 ExceptionInfo *exception) 1149 { 1150 char 1151 **arguments, 1152 command[MagickPathExtent]; 1153 1154 int 1155 number_arguments; 1156 1157 MagickBooleanType 1158 status; 1159 1160 register ssize_t 1161 i, 1162 j; 1163 1164 size_t 1165 test; 1166 1167 test=0; 1168 (void) FormatLocaleFile(stdout,"validate compare command line program:\n"); 1169 for (i=0; compare_options[i] != (char *) NULL; i++) 1170 { 1171 CatchException(exception); 1172 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++), 1173 compare_options[i]); 1174 (void) FormatLocaleString(command,MagickPathExtent,"%s %s %s %s", 1175 compare_options[i],reference_filename,reference_filename,output_filename); 1176 arguments=StringToArgv(command,&number_arguments); 1177 if (arguments == (char **) NULL) 1178 { 1179 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1180 GetMagickModule()); 1181 (*fail)++; 1182 continue; 1183 } 1184 status=CompareImagesCommand(image_info,number_arguments,arguments, 1185 (char **) NULL,exception); 1186 for (j=0; j < (ssize_t) number_arguments; j++) 1187 arguments[j]=DestroyString(arguments[j]); 1188 arguments=(char **) RelinquishMagickMemory(arguments); 1189 if (status == MagickFalse) 1190 { 1191 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1192 GetMagickModule()); 1193 (*fail)++; 1194 continue; 1195 } 1196 (void) FormatLocaleFile(stdout,"... pass.\n"); 1197 } 1198 (void) FormatLocaleFile(stdout, 1199 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1200 (double) (test-(*fail)),(double) *fail); 1201 return(test); 1202 } 1203 1204 /* 1206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1207 % % 1208 % % 1209 % % 1210 % V a l i d a t e C o m p o s i t e C o m m a n d % 1211 % % 1212 % % 1213 % % 1214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1215 % 1216 % ValidateCompositeCommand() validates the ImageMagick composite command line 1217 % program and returns the number of validation tests that passed and failed. 1218 % 1219 % The format of the ValidateCompositeCommand method is: 1220 % 1221 % size_t ValidateCompositeCommand(ImageInfo *image_info, 1222 % const char *reference_filename,const char *output_filename, 1223 % size_t *fail,ExceptionInfo *exception) 1224 % 1225 % A description of each parameter follows: 1226 % 1227 % o image_info: the image info. 1228 % 1229 % o reference_filename: the reference image filename. 1230 % 1231 % o output_filename: the output image filename. 1232 % 1233 % o fail: return the number of validation tests that pass. 1234 % 1235 % o exception: return any errors or warnings in this structure. 1236 % 1237 */ 1238 static size_t ValidateCompositeCommand(ImageInfo *image_info, 1239 const char *reference_filename,const char *output_filename,size_t *fail, 1240 ExceptionInfo *exception) 1241 { 1242 char 1243 **arguments, 1244 command[MagickPathExtent]; 1245 1246 int 1247 number_arguments; 1248 1249 MagickBooleanType 1250 status; 1251 1252 register ssize_t 1253 i, 1254 j; 1255 1256 size_t 1257 test; 1258 1259 test=0; 1260 (void) FormatLocaleFile(stdout,"validate composite command line program:\n"); 1261 for (i=0; composite_options[i] != (char *) NULL; i++) 1262 { 1263 CatchException(exception); 1264 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++), 1265 composite_options[i]); 1266 (void) FormatLocaleString(command,MagickPathExtent,"%s %s %s %s", 1267 reference_filename,composite_options[i],reference_filename, 1268 output_filename); 1269 arguments=StringToArgv(command,&number_arguments); 1270 if (arguments == (char **) NULL) 1271 { 1272 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1273 GetMagickModule()); 1274 (*fail)++; 1275 continue; 1276 } 1277 status=CompositeImageCommand(image_info,number_arguments,arguments, 1278 (char **) NULL,exception); 1279 for (j=0; j < (ssize_t) number_arguments; j++) 1280 arguments[j]=DestroyString(arguments[j]); 1281 arguments=(char **) RelinquishMagickMemory(arguments); 1282 if (status == MagickFalse) 1283 { 1284 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1285 GetMagickModule()); 1286 (*fail)++; 1287 continue; 1288 } 1289 (void) FormatLocaleFile(stdout,"... pass.\n"); 1290 } 1291 (void) FormatLocaleFile(stdout, 1292 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1293 (double) (test-(*fail)),(double) *fail); 1294 return(test); 1295 } 1296 1297 /* 1299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1300 % % 1301 % % 1302 % % 1303 % V a l i d a t e C o n v e r t C o m m a n d % 1304 % % 1305 % % 1306 % % 1307 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1308 % 1309 % ValidateConvertCommand() validates the ImageMagick convert command line 1310 % program and returns the number of validation tests that passed and failed. 1311 % 1312 % The format of the ValidateConvertCommand method is: 1313 % 1314 % size_t ValidateConvertCommand(ImageInfo *image_info, 1315 % const char *reference_filename,const char *output_filename, 1316 % size_t *fail,ExceptionInfo *exception) 1317 % 1318 % A description of each parameter follows: 1319 % 1320 % o image_info: the image info. 1321 % 1322 % o reference_filename: the reference image filename. 1323 % 1324 % o output_filename: the output image filename. 1325 % 1326 % o fail: return the number of validation tests that pass. 1327 % 1328 % o exception: return any errors or warnings in this structure. 1329 % 1330 */ 1331 static size_t ValidateConvertCommand(ImageInfo *image_info, 1332 const char *reference_filename,const char *output_filename,size_t *fail, 1333 ExceptionInfo *exception) 1334 { 1335 char 1336 **arguments, 1337 command[MagickPathExtent]; 1338 1339 int 1340 number_arguments; 1341 1342 MagickBooleanType 1343 status; 1344 1345 register ssize_t 1346 i, 1347 j; 1348 1349 size_t 1350 test; 1351 1352 test=0; 1353 (void) FormatLocaleFile(stdout,"validate convert command line program:\n"); 1354 for (i=0; convert_options[i] != (char *) NULL; i++) 1355 { 1356 CatchException(exception); 1357 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++, 1358 convert_options[i]); 1359 (void) FormatLocaleString(command,MagickPathExtent,"%s %s %s %s", 1360 reference_filename,convert_options[i],reference_filename,output_filename); 1361 arguments=StringToArgv(command,&number_arguments); 1362 if (arguments == (char **) NULL) 1363 { 1364 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1365 GetMagickModule()); 1366 (*fail)++; 1367 continue; 1368 } 1369 status=ConvertImageCommand(image_info,number_arguments,arguments, 1370 (char **) NULL,exception); 1371 for (j=0; j < (ssize_t) number_arguments; j++) 1372 arguments[j]=DestroyString(arguments[j]); 1373 arguments=(char **) RelinquishMagickMemory(arguments); 1374 if (status == MagickFalse) 1375 { 1376 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1377 GetMagickModule()); 1378 (*fail)++; 1379 continue; 1380 } 1381 (void) FormatLocaleFile(stdout,"... pass.\n"); 1382 } 1383 (void) FormatLocaleFile(stdout, 1384 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1385 (double) (test-(*fail)),(double) *fail); 1386 return(test); 1387 } 1388 1389 /* 1391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1392 % % 1393 % % 1394 % % 1395 % V a l i d a t e I d e n t i f y C o m m a n d % 1396 % % 1397 % % 1398 % % 1399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1400 % 1401 % ValidateIdentifyCommand() validates the ImageMagick identify command line 1402 % program and returns the number of validation tests that passed and failed. 1403 % 1404 % The format of the ValidateIdentifyCommand method is: 1405 % 1406 % size_t ValidateIdentifyCommand(ImageInfo *image_info, 1407 % const char *reference_filename,const char *output_filename, 1408 % size_t *fail,ExceptionInfo *exception) 1409 % 1410 % A description of each parameter follows: 1411 % 1412 % o image_info: the image info. 1413 % 1414 % o reference_filename: the reference image filename. 1415 % 1416 % o output_filename: the output image filename. 1417 % 1418 % o fail: return the number of validation tests that pass. 1419 % 1420 % o exception: return any errors or warnings in this structure. 1421 % 1422 */ 1423 static size_t ValidateIdentifyCommand(ImageInfo *image_info, 1424 const char *reference_filename,const char *output_filename,size_t *fail, 1425 ExceptionInfo *exception) 1426 { 1427 char 1428 **arguments, 1429 command[MagickPathExtent]; 1430 1431 int 1432 number_arguments; 1433 1434 MagickBooleanType 1435 status; 1436 1437 register ssize_t 1438 i, 1439 j; 1440 1441 size_t 1442 test; 1443 1444 (void) output_filename; 1445 test=0; 1446 (void) FormatLocaleFile(stdout,"validate identify command line program:\n"); 1447 for (i=0; identify_options[i] != (char *) NULL; i++) 1448 { 1449 CatchException(exception); 1450 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++, 1451 identify_options[i]); 1452 (void) FormatLocaleString(command,MagickPathExtent,"%s %s", 1453 identify_options[i],reference_filename); 1454 arguments=StringToArgv(command,&number_arguments); 1455 if (arguments == (char **) NULL) 1456 { 1457 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1458 GetMagickModule()); 1459 (*fail)++; 1460 continue; 1461 } 1462 status=IdentifyImageCommand(image_info,number_arguments,arguments, 1463 (char **) NULL,exception); 1464 for (j=0; j < (ssize_t) number_arguments; j++) 1465 arguments[j]=DestroyString(arguments[j]); 1466 arguments=(char **) RelinquishMagickMemory(arguments); 1467 if (status == MagickFalse) 1468 { 1469 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1470 GetMagickModule()); 1471 (*fail)++; 1472 continue; 1473 } 1474 (void) FormatLocaleFile(stdout,"... pass.\n"); 1475 } 1476 (void) FormatLocaleFile(stdout, 1477 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1478 (double) (test-(*fail)),(double) *fail); 1479 return(test); 1480 } 1481 1482 /* 1484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1485 % % 1486 % % 1487 % % 1488 % V a l i d a t e I m a g e F o r m a t s I n M e m o r y % 1489 % % 1490 % % 1491 % % 1492 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1493 % 1494 % ValidateImageFormatsInMemory() validates the ImageMagick image formats in 1495 % memory and returns the number of validation tests that passed and failed. 1496 % 1497 % The format of the ValidateImageFormatsInMemory method is: 1498 % 1499 % size_t ValidateImageFormatsInMemory(ImageInfo *image_info, 1500 % const char *reference_filename,const char *output_filename, 1501 % size_t *fail,ExceptionInfo *exception) 1502 % 1503 % A description of each parameter follows: 1504 % 1505 % o image_info: the image info. 1506 % 1507 % o reference_filename: the reference image filename. 1508 % 1509 % o output_filename: the output image filename. 1510 % 1511 % o fail: return the number of validation tests that pass. 1512 % 1513 % o exception: return any errors or warnings in this structure. 1514 % 1515 */ 1516 1517 /* 1518 Enable this to count remaining $TMPDIR/magick-* files. Note that the count 1519 includes any files left over from other runs. 1520 */ 1521 #undef MagickCountTempFiles 1522 1523 static size_t ValidateImageFormatsInMemory(ImageInfo *image_info, 1524 const char *reference_filename,const char *output_filename,size_t *fail, 1525 ExceptionInfo *exception) 1526 { 1527 char 1528 #ifdef MagickCountTempFiles 1529 path[MagickPathExtent], 1530 SystemCommand[MagickPathExtent], 1531 #endif 1532 size[MagickPathExtent]; 1533 1534 const MagickInfo 1535 *magick_info; 1536 1537 double 1538 distortion, 1539 fuzz; 1540 1541 Image 1542 *difference_image, 1543 *ping_image, 1544 *reconstruct_image, 1545 *reference_image; 1546 1547 MagickBooleanType 1548 status; 1549 1550 register ssize_t 1551 i, 1552 j; 1553 1554 size_t 1555 length, 1556 test; 1557 1558 unsigned char 1559 *blob; 1560 1561 test=0; 1562 (void) FormatLocaleFile(stdout,"validate image formats in memory:\n"); 1563 1564 #ifdef MagickCountTempFiles 1565 (void)GetPathTemplate(path); 1566 /* Remove file template except for the leading "/path/to/magick-" */ 1567 path[strlen(path)-17]='\0'; 1568 (void) FormatLocaleFile(stdout," tmp path is '%s*'\n",path); 1569 #endif 1570 1571 for (i=0; reference_formats[i].magick != (char *) NULL; i++) 1572 { 1573 magick_info=GetMagickInfo(reference_formats[i].magick,exception); 1574 if ((magick_info == (const MagickInfo *) NULL) || 1575 (magick_info->decoder == (DecodeImageHandler *) NULL) || 1576 (magick_info->encoder == (EncodeImageHandler *) NULL)) 1577 continue; 1578 for (j=0; reference_types[j].type != UndefinedType; j++) 1579 { 1580 /* 1581 Generate reference image. 1582 */ 1583 CatchException(exception); 1584 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits", 1585 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic( 1586 MagickCompressOptions,reference_formats[i].compression), 1587 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type), 1588 (double) reference_types[j].depth); 1589 (void) CopyMagickString(image_info->filename,reference_filename, 1590 MagickPathExtent); 1591 reference_image=ReadImage(image_info,exception); 1592 if (reference_image == (Image *) NULL || 1593 exception->severity >= ErrorException) 1594 { 1595 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1596 GetMagickModule()); 1597 CatchException(exception); 1598 (*fail)++; 1599 continue; 1600 } 1601 /* 1602 Write reference image. 1603 */ 1604 (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g", 1605 (double) reference_image->columns,(double) reference_image->rows); 1606 (void) CloneString(&image_info->size,size); 1607 image_info->depth=reference_types[j].depth; 1608 (void) FormatLocaleString(reference_image->filename,MagickPathExtent,"%s:%s", 1609 reference_formats[i].magick,output_filename); 1610 status=SetImageType(reference_image,reference_types[j].type,exception); 1611 if (status == MagickFalse || exception->severity >= ErrorException) 1612 { 1613 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1614 GetMagickModule()); 1615 CatchException(exception); 1616 (*fail)++; 1617 reference_image=DestroyImage(reference_image); 1618 continue; 1619 } 1620 status=SetImageDepth(reference_image,reference_types[j].depth,exception); 1621 if (status == MagickFalse || exception->severity >= ErrorException) 1622 { 1623 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1624 GetMagickModule()); 1625 CatchException(exception); 1626 (*fail)++; 1627 reference_image=DestroyImage(reference_image); 1628 continue; 1629 } 1630 reference_image->compression=reference_formats[i].compression; 1631 status=WriteImage(image_info,reference_image,exception); 1632 reference_image=DestroyImage(reference_image); 1633 if (status == MagickFalse || exception->severity >= ErrorException) 1634 { 1635 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1636 GetMagickModule()); 1637 CatchException(exception); 1638 (*fail)++; 1639 continue; 1640 } 1641 /* 1642 Ping reference image. 1643 */ 1644 (void) FormatLocaleString(image_info->filename,MagickPathExtent,"%s:%s", 1645 reference_formats[i].magick,output_filename); 1646 ping_image=PingImage(image_info,exception); 1647 if (ping_image == (Image *) NULL || 1648 exception->severity >= ErrorException) 1649 { 1650 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1651 GetMagickModule()); 1652 CatchException(exception); 1653 (*fail)++; 1654 continue; 1655 } 1656 ping_image=DestroyImage(ping_image); 1657 /* 1658 Read reference image. 1659 */ 1660 reference_image=ReadImage(image_info,exception); 1661 if (reference_image == (Image *) NULL || 1662 exception->severity >= ErrorException) 1663 { 1664 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1665 GetMagickModule()); 1666 CatchException(exception); 1667 (*fail)++; 1668 continue; 1669 } 1670 /* 1671 Write reference image. 1672 */ 1673 (void) FormatLocaleString(reference_image->filename,MagickPathExtent,"%s:%s", 1674 reference_formats[i].magick,output_filename); 1675 (void) CopyMagickString(image_info->magick,reference_formats[i].magick, 1676 MagickPathExtent); 1677 reference_image->depth=reference_types[j].depth; 1678 reference_image->compression=reference_formats[i].compression; 1679 length=8192; 1680 blob=ImageToBlob(image_info,reference_image,&length,exception); 1681 if (blob == (unsigned char *) NULL || 1682 exception->severity >= ErrorException) 1683 { 1684 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1685 GetMagickModule()); 1686 CatchException(exception); 1687 (*fail)++; 1688 reference_image=DestroyImage(reference_image); 1689 continue; 1690 } 1691 /* 1692 Ping reference blob. 1693 */ 1694 ping_image=PingBlob(image_info,blob,length,exception); 1695 if (ping_image == (Image *) NULL || 1696 exception->severity >= ErrorException) 1697 { 1698 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1699 GetMagickModule()); 1700 CatchException(exception); 1701 (*fail)++; 1702 blob=(unsigned char *) RelinquishMagickMemory(blob); 1703 continue; 1704 } 1705 ping_image=DestroyImage(ping_image); 1706 /* 1707 Read reconstruct image. 1708 */ 1709 (void) FormatLocaleString(image_info->filename,MagickPathExtent,"%s:%s", 1710 reference_formats[i].magick,output_filename); 1711 reconstruct_image=BlobToImage(image_info,blob,length,exception); 1712 blob=(unsigned char *) RelinquishMagickMemory(blob); 1713 if (reconstruct_image == (Image *) NULL || 1714 exception->severity >= ErrorException) 1715 { 1716 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1717 GetMagickModule()); 1718 CatchException(exception); 1719 (*fail)++; 1720 reference_image=DestroyImage(reference_image); 1721 continue; 1722 } 1723 /* 1724 Compare reference to reconstruct image. 1725 */ 1726 fuzz=0.003; /* grayscale */ 1727 if (reference_formats[i].fuzz != 0.0) 1728 fuzz=reference_formats[i].fuzz; 1729 difference_image=CompareImages(reference_image,reconstruct_image, 1730 RootMeanSquaredErrorMetric,&distortion,exception); 1731 reconstruct_image=DestroyImage(reconstruct_image); 1732 reference_image=DestroyImage(reference_image); 1733 if (difference_image == (Image *) NULL || 1734 exception->severity >= ErrorException) 1735 { 1736 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1737 GetMagickModule()); 1738 CatchException(exception); 1739 (*fail)++; 1740 continue; 1741 } 1742 difference_image=DestroyImage(difference_image); 1743 if ((QuantumScale*distortion) > fuzz) 1744 { 1745 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n", 1746 QuantumScale*distortion); 1747 (*fail)++; 1748 continue; 1749 } 1750 #ifdef MagickCountTempFiles 1751 (void) FormatLocaleFile(stdout,"... pass, "); 1752 (void) fflush(stdout); 1753 SystemCommand[0]='\0'; 1754 (void) strncat(SystemCommand,"echo `ls ",9); 1755 (void) strncat(SystemCommand,path,MagickPathExtent-31); 1756 (void) strncat(SystemCommand,"* | wc -w` tmp files.",20); 1757 (void) system(SystemCommand); 1758 (void) fflush(stdout); 1759 #else 1760 (void) FormatLocaleFile(stdout,"... pass\n"); 1761 #endif 1762 } 1763 } 1764 (void) FormatLocaleFile(stdout, 1765 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1766 (double) (test-(*fail)),(double) *fail); 1767 return(test); 1768 } 1769 1770 /* 1772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1773 % % 1774 % % 1775 % % 1776 % V a l i d a t e I m a g e F o r m a t s O n D i s k % 1777 % % 1778 % % 1779 % % 1780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1781 % 1782 % ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk 1783 % and returns the number of validation tests that passed and failed. 1784 % 1785 % The format of the ValidateImageFormatsOnDisk method is: 1786 % 1787 % size_t ValidateImageFormatsOnDisk(ImageInfo *image_info, 1788 % const char *reference_filename,const char *output_filename, 1789 % size_t *fail,ExceptionInfo *exception) 1790 % 1791 % A description of each parameter follows: 1792 % 1793 % o image_info: the image info. 1794 % 1795 % o reference_filename: the reference image filename. 1796 % 1797 % o output_filename: the output image filename. 1798 % 1799 % o fail: return the number of validation tests that pass. 1800 % 1801 % o exception: return any errors or warnings in this structure. 1802 % 1803 */ 1804 static size_t ValidateImageFormatsOnDisk(ImageInfo *image_info, 1805 const char *reference_filename,const char *output_filename,size_t *fail, 1806 ExceptionInfo *exception) 1807 { 1808 char 1809 size[MagickPathExtent]; 1810 1811 const MagickInfo 1812 *magick_info; 1813 1814 double 1815 distortion, 1816 fuzz; 1817 1818 Image 1819 *difference_image, 1820 *reference_image, 1821 *reconstruct_image; 1822 1823 MagickBooleanType 1824 status; 1825 1826 register ssize_t 1827 i, 1828 j; 1829 1830 size_t 1831 test; 1832 1833 test=0; 1834 (void) FormatLocaleFile(stdout,"validate image formats on disk:\n"); 1835 for (i=0; reference_formats[i].magick != (char *) NULL; i++) 1836 { 1837 magick_info=GetMagickInfo(reference_formats[i].magick,exception); 1838 if ((magick_info == (const MagickInfo *) NULL) || 1839 (magick_info->decoder == (DecodeImageHandler *) NULL) || 1840 (magick_info->encoder == (EncodeImageHandler *) NULL)) 1841 continue; 1842 for (j=0; reference_types[j].type != UndefinedType; j++) 1843 { 1844 /* 1845 Generate reference image. 1846 */ 1847 CatchException(exception); 1848 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits", 1849 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic( 1850 MagickCompressOptions,reference_formats[i].compression), 1851 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type), 1852 (double) reference_types[j].depth); 1853 (void) CopyMagickString(image_info->filename,reference_filename, 1854 MagickPathExtent); 1855 reference_image=ReadImage(image_info,exception); 1856 if (reference_image == (Image *) NULL || 1857 exception->severity >= ErrorException) 1858 { 1859 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1860 GetMagickModule()); 1861 CatchException(exception); 1862 (*fail)++; 1863 continue; 1864 } 1865 /* 1866 Write reference image. 1867 */ 1868 (void) FormatLocaleString(size,MagickPathExtent,"%.20gx%.20g", 1869 (double) reference_image->columns,(double) reference_image->rows); 1870 (void) CloneString(&image_info->size,size); 1871 image_info->depth=reference_types[j].depth; 1872 (void) FormatLocaleString(reference_image->filename,MagickPathExtent,"%s:%s", 1873 reference_formats[i].magick,output_filename); 1874 status=SetImageType(reference_image,reference_types[j].type,exception); 1875 if (status == MagickFalse || exception->severity >= ErrorException) 1876 { 1877 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1878 GetMagickModule()); 1879 CatchException(exception); 1880 (*fail)++; 1881 reference_image=DestroyImage(reference_image); 1882 continue; 1883 } 1884 status=SetImageDepth(reference_image,reference_types[j].depth,exception); 1885 if (status == MagickFalse || exception->severity >= ErrorException) 1886 { 1887 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1888 GetMagickModule()); 1889 CatchException(exception); 1890 (*fail)++; 1891 reference_image=DestroyImage(reference_image); 1892 continue; 1893 } 1894 reference_image->compression=reference_formats[i].compression; 1895 status=WriteImage(image_info,reference_image,exception); 1896 reference_image=DestroyImage(reference_image); 1897 if (status == MagickFalse || exception->severity >= ErrorException) 1898 { 1899 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1900 GetMagickModule()); 1901 CatchException(exception); 1902 (*fail)++; 1903 continue; 1904 } 1905 /* 1906 Read reference image. 1907 */ 1908 (void) FormatLocaleString(image_info->filename,MagickPathExtent,"%s:%s", 1909 reference_formats[i].magick,output_filename); 1910 reference_image=ReadImage(image_info,exception); 1911 if (reference_image == (Image *) NULL || 1912 exception->severity >= ErrorException) 1913 { 1914 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1915 GetMagickModule()); 1916 CatchException(exception); 1917 (*fail)++; 1918 continue; 1919 } 1920 /* 1921 Write reference image. 1922 */ 1923 (void) FormatLocaleString(reference_image->filename,MagickPathExtent,"%s:%s", 1924 reference_formats[i].magick,output_filename); 1925 reference_image->depth=reference_types[j].depth; 1926 reference_image->compression=reference_formats[i].compression; 1927 status=WriteImage(image_info,reference_image,exception); 1928 if (status == MagickFalse ||exception->severity >= ErrorException) 1929 { 1930 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1931 GetMagickModule()); 1932 CatchException(exception); 1933 (*fail)++; 1934 reference_image=DestroyImage(reference_image); 1935 continue; 1936 } 1937 /* 1938 Read reconstruct image. 1939 */ 1940 (void) FormatLocaleString(image_info->filename,MagickPathExtent,"%s:%s", 1941 reference_formats[i].magick,output_filename); 1942 reconstruct_image=ReadImage(image_info,exception); 1943 if (reconstruct_image == (Image *) NULL || 1944 exception->severity >= ErrorException) 1945 { 1946 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1947 GetMagickModule()); 1948 CatchException(exception); 1949 (*fail)++; 1950 reference_image=DestroyImage(reference_image); 1951 continue; 1952 } 1953 /* 1954 Compare reference to reconstruct image. 1955 */ 1956 fuzz=0.003; /* grayscale */ 1957 if (reference_formats[i].fuzz != 0.0) 1958 fuzz=reference_formats[i].fuzz; 1959 difference_image=CompareImages(reference_image,reconstruct_image, 1960 RootMeanSquaredErrorMetric,&distortion,exception); 1961 reconstruct_image=DestroyImage(reconstruct_image); 1962 reference_image=DestroyImage(reference_image); 1963 if (difference_image == (Image *) NULL || 1964 exception->severity >= ErrorException) 1965 { 1966 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 1967 GetMagickModule()); 1968 CatchException(exception); 1969 (*fail)++; 1970 continue; 1971 } 1972 difference_image=DestroyImage(difference_image); 1973 if ((QuantumScale*distortion) > fuzz) 1974 { 1975 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n", 1976 QuantumScale*distortion); 1977 (*fail)++; 1978 continue; 1979 } 1980 (void) FormatLocaleFile(stdout,"... pass.\n"); 1981 } 1982 } 1983 (void) FormatLocaleFile(stdout, 1984 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 1985 (double) (test-(*fail)),(double) *fail); 1986 return(test); 1987 } 1988 1989 /* 1991 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1992 % % 1993 % % 1994 % % 1995 % V a l i d a t e I m p o r t E x p o r t P i x e l s % 1996 % % 1997 % % 1998 % % 1999 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2000 % 2001 % ValidateImportExportPixels() validates the pixel import and export methods. 2002 % It returns the number of validation tests that passed and failed. 2003 % 2004 % The format of the ValidateImportExportPixels method is: 2005 % 2006 % size_t ValidateImportExportPixels(ImageInfo *image_info, 2007 % const char *reference_filename,const char *output_filename, 2008 % size_t *fail,ExceptionInfo *exception) 2009 % 2010 % A description of each parameter follows: 2011 % 2012 % o image_info: the image info. 2013 % 2014 % o reference_filename: the reference image filename. 2015 % 2016 % o output_filename: the output image filename. 2017 % 2018 % o fail: return the number of validation tests that pass. 2019 % 2020 % o exception: return any errors or warnings in this structure. 2021 % 2022 */ 2023 static size_t ValidateImportExportPixels(ImageInfo *image_info, 2024 const char *reference_filename,const char *output_filename,size_t *fail, 2025 ExceptionInfo *exception) 2026 { 2027 double 2028 distortion; 2029 2030 Image 2031 *difference_image, 2032 *reference_image, 2033 *reconstruct_image; 2034 2035 MagickBooleanType 2036 status; 2037 2038 register ssize_t 2039 i, 2040 j; 2041 2042 size_t 2043 length; 2044 2045 unsigned char 2046 *pixels; 2047 2048 size_t 2049 test; 2050 2051 (void) output_filename; 2052 test=0; 2053 (void) FormatLocaleFile(stdout, 2054 "validate the import and export of image pixels:\n"); 2055 for (i=0; reference_map[i] != (char *) NULL; i++) 2056 { 2057 for (j=0; reference_storage[j].type != UndefinedPixel; j++) 2058 { 2059 /* 2060 Generate reference image. 2061 */ 2062 CatchException(exception); 2063 (void) FormatLocaleFile(stdout," test %.20g: %s/%s",(double) (test++), 2064 reference_map[i],CommandOptionToMnemonic(MagickStorageOptions, 2065 reference_storage[j].type)); 2066 (void) CopyMagickString(image_info->filename,reference_filename, 2067 MagickPathExtent); 2068 reference_image=ReadImage(image_info,exception); 2069 if (reference_image == (Image *) NULL || 2070 exception->severity >= ErrorException) 2071 { 2072 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2073 GetMagickModule()); 2074 CatchException(exception); 2075 (*fail)++; 2076 continue; 2077 } 2078 if (LocaleNCompare(reference_map[i],"cmy",3) == 0) 2079 (void) SetImageColorspace(reference_image,CMYKColorspace,exception); 2080 length=strlen(reference_map[i])*reference_image->columns* 2081 reference_image->rows*reference_storage[j].quantum; 2082 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels)); 2083 if (pixels == (unsigned char *) NULL || 2084 exception->severity >= ErrorException) 2085 { 2086 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2087 GetMagickModule()); 2088 CatchException(exception); 2089 (*fail)++; 2090 reference_image=DestroyImage(reference_image); 2091 continue; 2092 } 2093 (void) ResetMagickMemory(pixels,0,length*sizeof(*pixels)); 2094 status=ExportImagePixels(reference_image,0,0,reference_image->columns, 2095 reference_image->rows,reference_map[i],reference_storage[j].type,pixels, 2096 exception); 2097 if (status == MagickFalse || exception->severity >= ErrorException) 2098 { 2099 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2100 GetMagickModule()); 2101 CatchException(exception); 2102 (*fail)++; 2103 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 2104 reference_image=DestroyImage(reference_image); 2105 continue; 2106 } 2107 (void) SetImageBackgroundColor(reference_image,exception); 2108 status=ImportImagePixels(reference_image,0,0,reference_image->columns, 2109 reference_image->rows,reference_map[i],reference_storage[j].type, 2110 pixels,exception); 2111 if (status == MagickFalse || exception->severity >= ErrorException) 2112 { 2113 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2114 GetMagickModule()); 2115 CatchException(exception); 2116 (*fail)++; 2117 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 2118 reference_image=DestroyImage(reference_image); 2119 continue; 2120 } 2121 /* 2122 Read reconstruct image. 2123 */ 2124 reconstruct_image=AcquireImage(image_info,exception); 2125 (void) SetImageExtent(reconstruct_image,reference_image->columns, 2126 reference_image->rows,exception); 2127 (void) SetImageColorspace(reconstruct_image,reference_image->colorspace, 2128 exception); 2129 (void) SetImageBackgroundColor(reconstruct_image,exception); 2130 status=ImportImagePixels(reconstruct_image,0,0,reconstruct_image->columns, 2131 reconstruct_image->rows,reference_map[i],reference_storage[j].type, 2132 pixels,exception); 2133 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 2134 if (status == MagickFalse || exception->severity >= ErrorException) 2135 { 2136 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2137 GetMagickModule()); 2138 CatchException(exception); 2139 (*fail)++; 2140 reference_image=DestroyImage(reference_image); 2141 continue; 2142 } 2143 /* 2144 Compare reference to reconstruct image. 2145 */ 2146 difference_image=CompareImages(reference_image,reconstruct_image, 2147 RootMeanSquaredErrorMetric,&distortion,exception); 2148 reconstruct_image=DestroyImage(reconstruct_image); 2149 reference_image=DestroyImage(reference_image); 2150 if (difference_image == (Image *) NULL || 2151 exception->severity >= ErrorException) 2152 { 2153 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2154 GetMagickModule()); 2155 CatchException(exception); 2156 (*fail)++; 2157 continue; 2158 } 2159 difference_image=DestroyImage(difference_image); 2160 if ((QuantumScale*distortion) > 0.0) 2161 { 2162 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n", 2163 QuantumScale*distortion); 2164 (*fail)++; 2165 continue; 2166 } 2167 (void) FormatLocaleFile(stdout,"... pass.\n"); 2168 } 2169 } 2170 (void) FormatLocaleFile(stdout, 2171 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 2172 (double) (test-(*fail)),(double) *fail); 2173 return(test); 2174 } 2175 2176 /* 2178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2179 % % 2180 % % 2181 % % 2182 % V a l i d a t e M o n t a g e C o m m a n d % 2183 % % 2184 % % 2185 % % 2186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2187 % 2188 % ValidateMontageCommand() validates the ImageMagick montage command line 2189 % program and returns the number of validation tests that passed and failed. 2190 % 2191 % The format of the ValidateMontageCommand method is: 2192 % 2193 % size_t ValidateMontageCommand(ImageInfo *image_info, 2194 % const char *reference_filename,const char *output_filename, 2195 % size_t *fail,ExceptionInfo *exception) 2196 % 2197 % A description of each parameter follows: 2198 % 2199 % o image_info: the image info. 2200 % 2201 % o reference_filename: the reference image filename. 2202 % 2203 % o output_filename: the output image filename. 2204 % 2205 % o fail: return the number of validation tests that pass. 2206 % 2207 % o exception: return any errors or warnings in this structure. 2208 % 2209 */ 2210 static size_t ValidateMontageCommand(ImageInfo *image_info, 2211 const char *reference_filename,const char *output_filename,size_t *fail, 2212 ExceptionInfo *exception) 2213 { 2214 char 2215 **arguments, 2216 command[MagickPathExtent]; 2217 2218 int 2219 number_arguments; 2220 2221 MagickBooleanType 2222 status; 2223 2224 register ssize_t 2225 i, 2226 j; 2227 2228 size_t 2229 test; 2230 2231 test=0; 2232 (void) FormatLocaleFile(stdout,"validate montage command line program:\n"); 2233 for (i=0; montage_options[i] != (char *) NULL; i++) 2234 { 2235 CatchException(exception); 2236 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++), 2237 montage_options[i]); 2238 (void) FormatLocaleString(command,MagickPathExtent,"%s %s %s %s", 2239 reference_filename,montage_options[i],reference_filename, 2240 output_filename); 2241 arguments=StringToArgv(command,&number_arguments); 2242 if (arguments == (char **) NULL) 2243 { 2244 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2245 GetMagickModule()); 2246 (*fail)++; 2247 continue; 2248 } 2249 status=MontageImageCommand(image_info,number_arguments,arguments, 2250 (char **) NULL,exception); 2251 for (j=0; j < (ssize_t) number_arguments; j++) 2252 arguments[j]=DestroyString(arguments[j]); 2253 arguments=(char **) RelinquishMagickMemory(arguments); 2254 if (status == MagickFalse) 2255 { 2256 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2257 GetMagickModule()); 2258 (*fail)++; 2259 continue; 2260 } 2261 (void) FormatLocaleFile(stdout,"... pass.\n"); 2262 } 2263 (void) FormatLocaleFile(stdout, 2264 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 2265 (double) (test-(*fail)),(double) *fail); 2266 return(test); 2267 } 2268 2269 /* 2271 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2272 % % 2273 % % 2274 % % 2275 % V a l i d a t e S t r e a m C o m m a n d % 2276 % % 2277 % % 2278 % % 2279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2280 % 2281 % ValidateStreamCommand() validates the ImageMagick stream command line 2282 % program and returns the number of validation tests that passed and failed. 2283 % 2284 % The format of the ValidateStreamCommand method is: 2285 % 2286 % size_t ValidateStreamCommand(ImageInfo *image_info, 2287 % const char *reference_filename,const char *output_filename, 2288 % size_t *fail,ExceptionInfo *exception) 2289 % 2290 % A description of each parameter follows: 2291 % 2292 % o image_info: the image info. 2293 % 2294 % o reference_filename: the reference image filename. 2295 % 2296 % o output_filename: the output image filename. 2297 % 2298 % o fail: return the number of validation tests that pass. 2299 % 2300 % o exception: return any errors or warnings in this structure. 2301 % 2302 */ 2303 static size_t ValidateStreamCommand(ImageInfo *image_info, 2304 const char *reference_filename,const char *output_filename,size_t *fail, 2305 ExceptionInfo *exception) 2306 { 2307 char 2308 **arguments, 2309 command[MagickPathExtent]; 2310 2311 int 2312 number_arguments; 2313 2314 MagickBooleanType 2315 status; 2316 2317 register ssize_t 2318 i, 2319 j; 2320 2321 size_t 2322 test; 2323 2324 test=0; 2325 (void) FormatLocaleFile(stdout,"validate stream command line program:\n"); 2326 for (i=0; stream_options[i] != (char *) NULL; i++) 2327 { 2328 CatchException(exception); 2329 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++), 2330 stream_options[i]); 2331 (void) FormatLocaleString(command,MagickPathExtent,"%s %s %s", 2332 stream_options[i],reference_filename,output_filename); 2333 arguments=StringToArgv(command,&number_arguments); 2334 if (arguments == (char **) NULL) 2335 { 2336 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2337 GetMagickModule()); 2338 (*fail)++; 2339 continue; 2340 } 2341 status=StreamImageCommand(image_info,number_arguments,arguments, 2342 (char **) NULL,exception); 2343 for (j=0; j < (ssize_t) number_arguments; j++) 2344 arguments[j]=DestroyString(arguments[j]); 2345 arguments=(char **) RelinquishMagickMemory(arguments); 2346 if (status == MagickFalse) 2347 { 2348 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n", 2349 GetMagickModule()); 2350 (*fail)++; 2351 continue; 2352 } 2353 (void) FormatLocaleFile(stdout,"... pass.\n"); 2354 } 2355 (void) FormatLocaleFile(stdout, 2356 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test, 2357 (double) (test-(*fail)),(double) *fail); 2358 return(test); 2359 } 2360 2361 /* 2363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2364 % % 2365 % % 2366 % % 2367 % M a i n % 2368 % % 2369 % % 2370 % % 2371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2372 % 2373 % 2374 */ 2375 2376 static MagickBooleanType ValidateUsage(void) 2377 { 2378 const char 2379 **p; 2380 2381 static const char 2382 *miscellaneous[]= 2383 { 2384 "-debug events display copious debugging information", 2385 "-help print program options", 2386 "-log format format of debugging information", 2387 "-validate type validation type", 2388 "-version print version information", 2389 (char *) NULL 2390 }, 2391 *settings[]= 2392 { 2393 "-regard-warnings pay attention to warning messages", 2394 "-verbose print detailed information about the image", 2395 (char *) NULL 2396 }; 2397 2398 (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL)); 2399 (void) printf("Copyright: %s\n\n",GetMagickCopyright()); 2400 (void) printf("Features: %s\n",GetMagickFeatures()); 2401 (void) printf("Usage: %s [options ...] reference-file\n",GetClientName()); 2402 (void) printf("\nValidate Settings:\n"); 2403 for (p=settings; *p != (char *) NULL; p++) 2404 (void) printf(" %s\n",*p); 2405 (void) printf("\nMiscellaneous Options:\n"); 2406 for (p=miscellaneous; *p != (char *) NULL; p++) 2407 (void) printf(" %s\n",*p); 2408 return(MagickTrue); 2409 } 2410 2411 int main(int argc,char **argv) 2412 { 2413 #define DestroyValidate() \ 2414 { \ 2415 image_info=DestroyImageInfo(image_info); \ 2416 exception=DestroyExceptionInfo(exception); \ 2417 } 2418 #define ThrowValidateException(asperity,tag,option) \ 2419 { \ 2420 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \ 2421 option); \ 2422 CatchException(exception); \ 2423 DestroyValidate(); \ 2424 return(MagickFalse); \ 2425 } 2426 2427 char 2428 output_filename[MagickPathExtent], 2429 reference_filename[MagickPathExtent], 2430 *option; 2431 2432 double 2433 elapsed_time, 2434 user_time; 2435 2436 ExceptionInfo 2437 *exception; 2438 2439 Image 2440 *reference_image; 2441 2442 ImageInfo 2443 *image_info; 2444 2445 MagickBooleanType 2446 regard_warnings, 2447 status; 2448 2449 MagickSizeType 2450 memory_resource, 2451 map_resource; 2452 2453 register ssize_t 2454 i; 2455 2456 TimerInfo 2457 *timer; 2458 2459 size_t 2460 fail, 2461 iterations, 2462 tests; 2463 2464 ValidateType 2465 type; 2466 2467 /* 2468 Validate the ImageMagick image processing suite. 2469 */ 2470 MagickCoreGenesis(*argv,MagickTrue); 2471 (void) setlocale(LC_ALL,""); 2472 (void) setlocale(LC_NUMERIC,"C"); 2473 iterations=1; 2474 status=MagickFalse; 2475 type=AllValidate; 2476 regard_warnings=MagickFalse; 2477 (void) regard_warnings; 2478 exception=AcquireExceptionInfo(); 2479 image_info=AcquireImageInfo(); 2480 (void) CopyMagickString(image_info->filename,ReferenceFilename,MagickPathExtent); 2481 for (i=1; i < (ssize_t) argc; i++) 2482 { 2483 option=argv[i]; 2484 if (IsCommandOption(option) == MagickFalse) 2485 { 2486 (void) CopyMagickString(image_info->filename,option,MagickPathExtent); 2487 continue; 2488 } 2489 switch (*(option+1)) 2490 { 2491 case 'b': 2492 { 2493 if (LocaleCompare("bench",option+1) == 0) 2494 { 2495 iterations=StringToUnsignedLong(argv[++i]); 2496 break; 2497 } 2498 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2499 } 2500 case 'd': 2501 { 2502 if (LocaleCompare("debug",option+1) == 0) 2503 { 2504 (void) SetLogEventMask(argv[++i]); 2505 break; 2506 } 2507 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2508 } 2509 case 'h': 2510 { 2511 if (LocaleCompare("help",option+1) == 0) 2512 { 2513 (void) ValidateUsage(); 2514 return(0); 2515 } 2516 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2517 } 2518 case 'l': 2519 { 2520 if (LocaleCompare("log",option+1) == 0) 2521 { 2522 if (*option != '+') 2523 (void) SetLogFormat(argv[i+1]); 2524 break; 2525 } 2526 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2527 } 2528 case 'r': 2529 { 2530 if (LocaleCompare("regard-warnings",option+1) == 0) 2531 { 2532 regard_warnings=MagickTrue; 2533 break; 2534 } 2535 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2536 } 2537 case 'v': 2538 { 2539 if (LocaleCompare("validate",option+1) == 0) 2540 { 2541 ssize_t 2542 validate; 2543 2544 if (*option == '+') 2545 break; 2546 i++; 2547 if (i >= (ssize_t) argc) 2548 ThrowValidateException(OptionError,"MissingArgument",option); 2549 validate=ParseCommandOption(MagickValidateOptions,MagickFalse, 2550 argv[i]); 2551 if (validate < 0) 2552 ThrowValidateException(OptionError,"UnrecognizedValidateType", 2553 argv[i]); 2554 type=(ValidateType) validate; 2555 break; 2556 } 2557 if ((LocaleCompare("version",option+1) == 0) || 2558 (LocaleCompare("-version",option+1) == 0)) 2559 { 2560 (void) FormatLocaleFile(stdout,"Version: %s\n", 2561 GetMagickVersion((size_t *) NULL)); 2562 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n", 2563 GetMagickCopyright()); 2564 (void) FormatLocaleFile(stdout,"Features: %s\n\n", 2565 GetMagickFeatures()); 2566 return(0); 2567 } 2568 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2569 } 2570 default: 2571 ThrowValidateException(OptionError,"UnrecognizedOption",option) 2572 } 2573 } 2574 timer=(TimerInfo *) NULL; 2575 if (iterations > 1) 2576 timer=AcquireTimerInfo(); 2577 reference_image=ReadImage(image_info,exception); 2578 tests=0; 2579 fail=0; 2580 if (reference_image == (Image *) NULL) 2581 fail++; 2582 else 2583 { 2584 if (LocaleCompare(image_info->filename,ReferenceFilename) == 0) 2585 (void) CopyMagickString(reference_image->magick,ReferenceImageFormat, 2586 MagickPathExtent); 2587 (void) AcquireUniqueFilename(reference_filename); 2588 (void) AcquireUniqueFilename(output_filename); 2589 (void) CopyMagickString(reference_image->filename,reference_filename, 2590 MagickPathExtent); 2591 status=WriteImage(image_info,reference_image,exception); 2592 reference_image=DestroyImage(reference_image); 2593 if (status == MagickFalse) 2594 fail++; 2595 else 2596 { 2597 (void) FormatLocaleFile(stdout,"Version: %s\n", 2598 GetMagickVersion((size_t *) NULL)); 2599 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n", 2600 GetMagickCopyright()); 2601 (void) FormatLocaleFile(stdout, 2602 "ImageMagick Validation Suite (%s)\n\n",CommandOptionToMnemonic( 2603 MagickValidateOptions,(ssize_t) type)); 2604 if ((type & ColorspaceValidate) != 0) 2605 tests+=ValidateColorspaces(image_info,&fail,exception); 2606 if ((type & CompareValidate) != 0) 2607 tests+=ValidateCompareCommand(image_info,reference_filename, 2608 output_filename,&fail,exception); 2609 if ((type & CompositeValidate) != 0) 2610 tests+=ValidateCompositeCommand(image_info,reference_filename, 2611 output_filename,&fail,exception); 2612 if ((type & ConvertValidate) != 0) 2613 tests+=ValidateConvertCommand(image_info,reference_filename, 2614 output_filename,&fail,exception); 2615 if ((type & FormatsDiskValidate) != 0) 2616 { 2617 memory_resource=SetMagickResourceLimit(MemoryResource,0); 2618 map_resource=SetMagickResourceLimit(MapResource,0); 2619 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] "); 2620 tests+=ValidateImageFormatsInMemory(image_info,reference_filename, 2621 output_filename,&fail,exception); 2622 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] "); 2623 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename, 2624 output_filename,&fail,exception); 2625 (void) SetMagickResourceLimit(MemoryResource,memory_resource); 2626 (void) SetMagickResourceLimit(MapResource,map_resource); 2627 } 2628 if ((type & FormatsMapValidate) != 0) 2629 { 2630 memory_resource=SetMagickResourceLimit(MemoryResource,0); 2631 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] "); 2632 tests+=ValidateImageFormatsInMemory(image_info,reference_filename, 2633 output_filename,&fail,exception); 2634 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] "); 2635 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename, 2636 output_filename,&fail,exception); 2637 (void) SetMagickResourceLimit(MemoryResource,memory_resource); 2638 } 2639 if ((type & FormatsMemoryValidate) != 0) 2640 { 2641 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] "); 2642 tests+=ValidateImageFormatsInMemory(image_info,reference_filename, 2643 output_filename,&fail,exception); 2644 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] "); 2645 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename, 2646 output_filename,&fail,exception); 2647 } 2648 if ((type & IdentifyValidate) != 0) 2649 tests+=ValidateIdentifyCommand(image_info,reference_filename, 2650 output_filename,&fail,exception); 2651 if ((type & ImportExportValidate) != 0) 2652 tests+=ValidateImportExportPixels(image_info,reference_filename, 2653 output_filename,&fail,exception); 2654 if ((type & MontageValidate) != 0) 2655 tests+=ValidateMontageCommand(image_info,reference_filename, 2656 output_filename,&fail,exception); 2657 if ((type & StreamValidate) != 0) 2658 tests+=ValidateStreamCommand(image_info,reference_filename, 2659 output_filename,&fail,exception); 2660 (void) FormatLocaleFile(stdout, 2661 "validation suite: %.20g tests; %.20g passed; %.20g failed.\n", 2662 (double) tests,(double) (tests-fail),(double) fail); 2663 } 2664 (void) RelinquishUniqueFileResource(output_filename); 2665 (void) RelinquishUniqueFileResource(reference_filename); 2666 } 2667 if (exception->severity != UndefinedException) 2668 CatchException(exception); 2669 if (iterations > 1) 2670 { 2671 elapsed_time=GetElapsedTime(timer); 2672 user_time=GetUserTime(timer); 2673 (void) FormatLocaleFile(stderr, 2674 "Performance: %.20gi %gips %0.3fu %ld:%02ld.%03ld\n",(double) 2675 iterations,1.0*iterations/elapsed_time,user_time,(long) 2676 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)), 2677 (long) (1000.0*(elapsed_time-floor(elapsed_time)))); 2678 timer=DestroyTimerInfo(timer); 2679 } 2680 DestroyValidate(); 2681 MagickCoreTerminus(); 2682 return(fail == 0 ? 0 : 1); 2683 } 2684