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