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