blob: 3d3fc32f3cbcab42016b0887e386716e1b8daa31 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
18% March 2001 %
19% %
20% %
cristy45ef08f2012-12-07 13:13:34 +000021% Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000022% 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>
cristy5e8e9812009-12-17 15:13:38 +000044#include <stdlib.h>
cristy3ed852e2009-09-05 21:47:34 +000045#include <string.h>
cristy5e8e9812009-12-17 15:13:38 +000046#include <ctype.h>
cristy3ed852e2009-09-05 21:47:34 +000047#include <math.h>
cristye2605742012-12-12 11:18:34 +000048#include <locale.h>
cristy9883b452011-07-01 23:37:21 +000049#include "MagickWand/MagickWand.h"
cristy510d06a2011-07-06 23:43:54 +000050#include "MagickCore/colorspace-private.h"
glennrp4084cda2012-12-11 14:13:35 +000051#include "MagickCore/resource_.h"
cristy9883b452011-07-01 23:37:21 +000052#include "MagickCore/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000053#include "validate.h"
54
55/*
cristy8d24e062013-05-07 12:48:19 +000056 Define declarations.
57*/
58#define CIEEpsilon (216.0/24389.0)
59#define CIEK (24389.0/27.0)
60#define D65X 0.950456
61#define D65Y 1.0
62#define D65Z 1.088754
63#define ReferenceEpsilon (1.0e-0)
64
65/*
cristy3ed852e2009-09-05 21:47:34 +000066%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67% %
68% %
69% %
cristy572e0972013-05-07 12:51:28 +000070% V a l i d a t e C o l o r s p a c e s %
cristy80e870e2013-05-07 12:23:02 +000071% %
72% %
73% %
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75%
cristy572e0972013-05-07 12:51:28 +000076% ValidateColorspaces() validates the ImageMagick colorspaces and returns the
77% number of validation tests that passed and failed.
cristy80e870e2013-05-07 12:23:02 +000078%
cristy572e0972013-05-07 12:51:28 +000079% The format of the ValidateColorspaces method is:
cristy80e870e2013-05-07 12:23:02 +000080%
cristy572e0972013-05-07 12:51:28 +000081% size_t ValidateColorspaces(ImageInfo *image_info,size_t *fail,
82% ExceptionInfo *exception)
cristy80e870e2013-05-07 12:23:02 +000083%
84% A description of each parameter follows:
85%
86% o image_info: the image info.
87%
cristy80e870e2013-05-07 12:23:02 +000088% o fail: return the number of validation tests that pass.
89%
90% o exception: return any errors or warnings in this structure.
91%
92*/
cristy8d24e062013-05-07 12:48:19 +000093
94static void ConvertHSIToRGB(const double hue,const double saturation,
95 const double intensity,double *red,double *green,double *blue)
96{
97 double
98 h;
99
cristy8d24e062013-05-07 12:48:19 +0000100 h=360.0*hue;
101 h-=360.0*floor(h/360.0);
102 if (h < 120.0)
103 {
104 *blue=intensity*(1.0-saturation);
105 *red=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
106 (MagickPI/180.0)));
107 *green=3.0*intensity-*red-*blue;
108 }
109 else
110 if (h < 240.0)
111 {
112 h-=120.0;
113 *red=intensity*(1.0-saturation);
114 *green=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
115 (MagickPI/180.0)));
116 *blue=3.0*intensity-*red-*green;
117 }
118 else
119 {
120 h-=240.0;
121 *green=intensity*(1.0-saturation);
122 *blue=intensity*(1.0+saturation*cos(h*(MagickPI/180.0))/cos((60.0-h)*
123 (MagickPI/180.0)));
124 *red=3.0*intensity-*green-*blue;
125 }
126 *red*=QuantumRange;
127 *green*=QuantumRange;
128 *blue*=QuantumRange;
129}
130
131static inline double MagickMin(const double x,const double y)
132{
133 if (x < y)
134 return(x);
135 return(y);
136}
137
138static void ConvertRGBToHSI(const double red,const double green,
139 const double blue,double *hue,double *saturation,double *intensity)
140{
141 double
142 alpha,
143 beta;
144
cristy8d24e062013-05-07 12:48:19 +0000145 *intensity=(QuantumScale*red+QuantumScale*green+QuantumScale*blue)/3.0;
146 if (*intensity <= 0.0)
147 {
148 *hue=0.0;
149 *saturation=0.0;
150 return;
151 }
152 *saturation=1.0-MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
153 QuantumScale*blue))/(*intensity);
154 alpha=0.5*(2.0*QuantumScale*red-QuantumScale*green-QuantumScale*blue);
155 beta=0.8660254037844385*(QuantumScale*green-QuantumScale*blue);
156 *hue=atan2(beta,alpha)*(180.0/MagickPI)/360.0;
157 if (*hue < 0.0)
158 *hue+=1.0;
159}
160
161MagickExport void ConvertHSLToRGB(const double hue,const double saturation,
162 const double lightness,double *red,double *green,double *blue)
163{
164 double
165 c,
166 h,
167 min,
168 x;
169
cristy8d24e062013-05-07 12:48:19 +0000170 h=hue*360.0;
171 if (lightness <= 0.5)
172 c=2.0*lightness*saturation;
173 else
174 c=(2.0-2.0*lightness)*saturation;
175 min=lightness-0.5*c;
176 h-=360.0*floor(h/360.0);
177 h/=60.0;
178 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
179 switch ((int) floor(h))
180 {
181 case 0:
182 {
183 *red=QuantumRange*(min+c);
184 *green=QuantumRange*(min+x);
185 *blue=QuantumRange*min;
186 break;
187 }
188 case 1:
189 {
190 *red=QuantumRange*(min+x);
191 *green=QuantumRange*(min+c);
192 *blue=QuantumRange*min;
193 break;
194 }
195 case 2:
196 {
197 *red=QuantumRange*min;
198 *green=QuantumRange*(min+c);
199 *blue=QuantumRange*(min+x);
200 break;
201 }
202 case 3:
203 {
204 *red=QuantumRange*min;
205 *green=QuantumRange*(min+x);
206 *blue=QuantumRange*(min+c);
207 break;
208 }
209 case 4:
210 {
211 *red=QuantumRange*(min+x);
212 *green=QuantumRange*min;
213 *blue=QuantumRange*(min+c);
214 break;
215 }
216 case 5:
217 {
218 *red=QuantumRange*(min+c);
219 *green=QuantumRange*min;
220 *blue=QuantumRange*(min+x);
221 break;
222 }
223 default:
224 {
225 *red=0.0;
226 *green=0.0;
227 *blue=0.0;
228 }
229 }
230}
231
232static inline double MagickMax(const double x,const double y)
233{
234 if (x > y)
235 return(x);
236 return(y);
237}
238
239MagickExport void ConvertRGBToHSL(const double red,const double green,
240 const double blue,double *hue,double *saturation,double *lightness)
241{
242 double
243 c,
244 max,
245 min;
246
cristy8d24e062013-05-07 12:48:19 +0000247 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
248 QuantumScale*blue));
249 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
250 QuantumScale*blue));
251 c=max-min;
252 *lightness=(max+min)/2.0;
253 if (c <= 0.0)
254 {
255 *hue=0.0;
256 *saturation=0.0;
257 return;
258 }
259 if (max == (QuantumScale*red))
260 {
261 *hue=(QuantumScale*green-QuantumScale*blue)/c;
262 if ((QuantumScale*green) < (QuantumScale*blue))
263 *hue+=6.0;
264 }
265 else
266 if (max == (QuantumScale*green))
267 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
268 else
269 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
270 *hue*=60.0/360.0;
271 if (*lightness <= 0.5)
272 *saturation=c/(2.0*(*lightness));
273 else
274 *saturation=c/(2.0-2.0*(*lightness));
275}
276
277static void ConvertHSVToRGB(const double hue,const double saturation,
278 const double value,double *red,double *green,double *blue)
279{
280 double
281 c,
282 h,
283 min,
284 x;
285
cristy8d24e062013-05-07 12:48:19 +0000286 h=hue*360.0;
287 c=value*saturation;
288 min=value-c;
289 h-=360.0*floor(h/360.0);
290 h/=60.0;
291 x=c*(1.0-fabs(h-2.0*floor(h/2.0)-1.0));
292 switch ((int) floor(h))
293 {
294 case 0:
295 {
296 *red=QuantumRange*(min+c);
297 *green=QuantumRange*(min+x);
298 *blue=QuantumRange*min;
299 break;
300 }
301 case 1:
302 {
303 *red=QuantumRange*(min+x);
304 *green=QuantumRange*(min+c);
305 *blue=QuantumRange*min;
306 break;
307 }
308 case 2:
309 {
310 *red=QuantumRange*min;
311 *green=QuantumRange*(min+c);
312 *blue=QuantumRange*(min+x);
313 break;
314 }
315 case 3:
316 {
317 *red=QuantumRange*min;
318 *green=QuantumRange*(min+x);
319 *blue=QuantumRange*(min+c);
320 break;
321 }
322 case 4:
323 {
324 *red=QuantumRange*(min+x);
325 *green=QuantumRange*min;
326 *blue=QuantumRange*(min+c);
327 break;
328 }
329 case 5:
330 {
331 *red=QuantumRange*(min+c);
332 *green=QuantumRange*min;
333 *blue=QuantumRange*(min+x);
334 break;
335 }
336 default:
337 {
338 *red=0.0;
339 *green=0.0;
340 *blue=0.0;
341 }
342 }
343}
344
345static inline void ConvertRGBToXYZ(const double red,const double green,
346 const double blue,double *X,double *Y,double *Z)
347{
348 double
349 b,
350 g,
351 r;
352
cristy8d24e062013-05-07 12:48:19 +0000353 r=QuantumScale*DecodePixelGamma(red);
354 g=QuantumScale*DecodePixelGamma(green);
355 b=QuantumScale*DecodePixelGamma(blue);
356 *X=0.41239558896741421610*r+0.35758343076371481710*g+0.18049264738170157350*b;
357 *Y=0.21258623078559555160*r+0.71517030370341084990*g+0.07220049864333622685*b;
358 *Z=0.01929721549174694484*r+0.11918386458084853180*g+0.95049712513157976600*b;
359}
360
361static inline void ConvertXYZToLab(const double X,const double Y,const double Z,
362 double *L,double *a,double *b)
363{
364 double
365 x,
366 y,
367 z;
368
369 if ((X/D65X) > CIEEpsilon)
370 x=pow(X/D65X,1.0/3.0);
371 else
372 x=(CIEK*X/D65X+16.0)/116.0;
373 if ((Y/D65Y) > CIEEpsilon)
374 y=pow(Y/D65Y,1.0/3.0);
375 else
376 y=(CIEK*Y/D65Y+16.0)/116.0;
377 if ((Z/D65Z) > CIEEpsilon)
378 z=pow(Z/D65Z,1.0/3.0);
379 else
380 z=(CIEK*Z/D65Z+16.0)/116.0;
381 *L=((116.0*y)-16.0)/100.0;
382 *a=(500.0*(x-y))/255.0+0.5;
383 *b=(200.0*(y-z))/255.0+0.5;
384}
385
386static void ConvertRGBToLab(const double red,const double green,
387 const double blue,double *L,double *a,double *b)
388{
389 double
390 X,
391 Y,
392 Z;
393
394 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
395 ConvertXYZToLab(X,Y,Z,L,a,b);
396}
397
398static inline void ConvertLabToXYZ(const double L,const double a,const double b,
399 double *X,double *Y,double *Z)
400{
401 double
402 x,
403 y,
404 z;
405
406 y=(L+16.0)/116.0;
407 x=y+a/500.0;
408 z=y-b/200.0;
409 if ((x*x*x) > CIEEpsilon)
410 x=(x*x*x);
411 else
412 x=(116.0*x-16.0)/CIEK;
413 if ((y*y*y) > CIEEpsilon)
414 y=(y*y*y);
415 else
416 y=L/CIEK;
417 if ((z*z*z) > CIEEpsilon)
418 z=(z*z*z);
419 else
420 z=(116.0*z-16.0)/CIEK;
421 *X=D65X*x;
422 *Y=D65Y*y;
423 *Z=D65Z*z;
424}
425
426static inline void ConvertXYZToRGB(const double x,const double y,const double z,
427 double *red,double *green,double *blue)
428{
429 double
430 b,
431 g,
432 r;
433
cristy8d24e062013-05-07 12:48:19 +0000434 r=3.2406*x-1.5372*y-0.4986*z;
435 g=(-0.9689*x+1.8758*y+0.0415*z);
436 b=0.0557*x-0.2040*y+1.0570*z;
437 *red=EncodePixelGamma(QuantumRange*r);
438 *green=EncodePixelGamma(QuantumRange*g);
439 *blue=EncodePixelGamma(QuantumRange*b);
440}
441
442static inline void ConvertLabToRGB(const double L,const double a,
443 const double b,double *red,double *green,double *blue)
444{
445 double
446 X,
447 Y,
448 Z;
449
450 ConvertLabToXYZ(L*100.0,255.0*(a-0.5),255.0*(b-0.5),&X,&Y,&Z);
451 ConvertXYZToRGB(X,Y,Z,red,green,blue);
452}
453
454static void ConvertRGBToYPbPr(const double red,const double green,
455 const double blue,double *Y,double *Pb,double *Pr)
456{
cristy8d24e062013-05-07 12:48:19 +0000457 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
458 *Pb=QuantumScale*((-0.1687367)*red-0.331264*green+0.5*blue)+0.5;
459 *Pr=QuantumScale*(0.5*red-0.418688*green-0.081312*blue)+0.5;
460}
461
462static void ConvertRGBToYCbCr(const double red,const double green,
463 const double blue,double *Y,double *Cb,double *Cr)
464{
cristy8d24e062013-05-07 12:48:19 +0000465 ConvertRGBToYPbPr(red,green,blue,Y,Cb,Cr);
466}
467
468static void ConvertYPbPrToRGB(const double Y,const double Pb,const double Pr,
469 double *red,double *green,double *blue)
470{
cristy8d24e062013-05-07 12:48:19 +0000471 *red=QuantumRange*(0.99999999999914679361*Y-1.2188941887145875e-06*(Pb-0.5)+
472 1.4019995886561440468*(Pr-0.5));
473 *green=QuantumRange*(0.99999975910502514331*Y-0.34413567816504303521*(Pb-0.5)-
474 0.71413649331646789076*(Pr-0.5));
475 *blue=QuantumRange*(1.00000124040004623180*Y+1.77200006607230409200*(Pb-0.5)+
476 2.1453384174593273e-06*(Pr-0.5));
477}
478
479static void ConvertYCbCrToRGB(const double Y,const double Cb,
480 const double Cr,double *red,double *green,double *blue)
481{
cristy8d24e062013-05-07 12:48:19 +0000482 ConvertYPbPrToRGB(Y,Cb,Cr,red,green,blue);
483}
484
485static inline void ConvertLCHabToXYZ(const double luma,const double chroma,
486 const double hue,double *X,double *Y,double *Z)
487{
488 ConvertLabToXYZ(luma,chroma*cos(hue*MagickPI/180.0),chroma*
489 sin(hue*MagickPI/180.0),X,Y,Z);
490}
491
492static void ConvertLCHabToRGB(const double luma,const double chroma,
493 const double hue,double *red,double *green,double *blue)
494{
495 double
496 X,
497 Y,
498 Z;
499
cristy8d24e062013-05-07 12:48:19 +0000500 ConvertLCHabToXYZ(luma*100.0,255.0*(chroma-0.5),255.0*(hue-0.5),&X,&Y,&Z);
501 ConvertXYZToRGB(X,Y,Z,red,green,blue);
502}
503
504static void ConvertRGBToHSV(const double red,const double green,
505 const double blue,double *hue,double *saturation,double *value)
506{
507 double
508 c,
509 max,
510 min;
511
cristy8d24e062013-05-07 12:48:19 +0000512 max=MagickMax(QuantumScale*red,MagickMax(QuantumScale*green,
513 QuantumScale*blue));
514 min=MagickMin(QuantumScale*red,MagickMin(QuantumScale*green,
515 QuantumScale*blue));
516 c=max-min;
517 *value=max;
518 if (c <= 0.0)
519 {
520 *hue=0.0;
521 *saturation=0.0;
522 return;
523 }
524 if (max == (QuantumScale*red))
525 {
526 *hue=(QuantumScale*green-QuantumScale*blue)/c;
527 if ((QuantumScale*green) < (QuantumScale*blue))
528 *hue+=6.0;
529 }
530 else
531 if (max == (QuantumScale*green))
532 *hue=2.0+(QuantumScale*blue-QuantumScale*red)/c;
533 else
534 *hue=4.0+(QuantumScale*red-QuantumScale*green)/c;
535 *hue*=60.0/360.0;
536 *saturation=c/max;
537}
538
539static inline void ConvertXYZToLCHab(const double X,const double Y,
540 const double Z,double *luma,double *chroma,double *hue)
541{
542 double
543 a,
544 b;
545
546 ConvertXYZToLab(X,Y,Z,luma,&a,&b);
547 *chroma=hypot(255.0*(a-0.5),255.0*(b-0.5));
548 *hue=180.0*atan2(255.0*(b-0.5),255.0*(a-0.5))/MagickPI;
549 *chroma=(*chroma)/255.0+0.5;
550 *hue=(*hue)/255.0+0.5;
551 if (*hue < 0.0)
552 *hue+=1.0;
553}
554
555static void ConvertRGBToLCHab(const double red,const double green,
556 const double blue,double *luma,double *chroma,double *hue)
557{
558 double
559 X,
560 Y,
561 Z;
562
563 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
564 ConvertXYZToLCHab(X,Y,Z,luma,chroma,hue);
565}
566
567static inline void ConvertLMSToXYZ(const double L,const double M,const double S,
568 double *X,double *Y,double *Z)
569{
570 *X=1.096123820835514*L-0.278869000218287*M+0.182745179382773*S;
571 *Y=0.454369041975359*L+0.473533154307412*M+0.072097803717229*S;
572 *Z=(-0.009627608738429)*L-0.005698031216113*M+1.015325639954543*S;
573}
574
575static inline void ConvertLMSToRGB(const double L,const double M,
576 const double S,double *red,double *green,double *blue)
577{
578 double
579 X,
580 Y,
581 Z;
582
583 ConvertLMSToXYZ(L,M,S,&X,&Y,&Z);
584 ConvertXYZToRGB(X,Y,Z,red,green,blue);
585}
586
587static inline void ConvertXYZToLMS(const double x,const double y,
588 const double z,double *L,double *M,double *S)
589{
cristy8d24e062013-05-07 12:48:19 +0000590 *L=0.7328*x+0.4296*y-0.1624*z;
591 *M=(-0.7036*x+1.6975*y+0.0061*z);
592 *S=0.0030*x+0.0136*y+0.9834*z;
593}
594
595static void ConvertRGBToLMS(const double red,const double green,
596 const double blue,double *L,double *M,double *S)
597{
598 double
599 X,
600 Y,
601 Z;
602
603 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
604 ConvertXYZToLMS(X,Y,Z,L,M,S);
605}
606
607static inline double PerceptibleReciprocal(const double x)
608{
609 double
610 sign;
611
612 /*
613 Return 1/x where x is perceptible (not unlimited or infinitesimal).
614 */
615 sign=x < 0.0 ? -1.0 : 1.0;
616 if ((sign*x) >= MagickEpsilon)
617 return(1.0/x);
618 return(sign/MagickEpsilon);
619}
620
621static inline void ConvertXYZToLuv(const double X,const double Y,const double Z,
622 double *L,double *u,double *v)
623{
624 double
625 alpha;
626
627 if ((Y/D65Y) > CIEEpsilon)
628 *L=(double) (116.0*pow(Y/D65Y,1.0/3.0)-16.0);
629 else
630 *L=CIEK*(Y/D65Y);
631 alpha=PerceptibleReciprocal(X+15.0*Y+3.0*Z);
632 *u=13.0*(*L)*((4.0*alpha*X)-(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z)));
633 *v=13.0*(*L)*((9.0*alpha*Y)-(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z)));
634 *L/=100.0;
635 *u=(*u+134.0)/354.0;
636 *v=(*v+140.0)/262.0;
637}
638
639static void ConvertRGBToLuv(const double red,const double green,
640 const double blue,double *L,double *u,double *v)
641{
642 double
643 X,
644 Y,
645 Z;
646
647 ConvertRGBToXYZ(red,green,blue,&X,&Y,&Z);
648 ConvertXYZToLuv(X,Y,Z,L,u,v);
649}
650
651static inline void ConvertLuvToXYZ(const double L,const double u,const double v,
652 double *X,double *Y,double *Z)
653{
654 if (L > (CIEK*CIEEpsilon))
655 *Y=(double) pow((L+16.0)/116.0,3.0);
656 else
657 *Y=L/CIEK;
658 *X=((*Y*((39.0*L/(v+13.0*L*(9.0*D65Y/(D65X+15.0*D65Y+3.0*D65Z))))-5.0))+
659 5.0*(*Y))/((((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/
660 3.0)-(-1.0/3.0));
661 *Z=(*X*(((52.0f*L/(u+13.0*L*(4.0*D65X/(D65X+15.0*D65Y+3.0*D65Z))))-1.0)/3.0))-
662 5.0*(*Y);
663}
664
665static inline void ConvertLuvToRGB(const double L,const double u,
666 const double v,double *red,double *green,double *blue)
667{
668 double
669 X,
670 Y,
671 Z;
672
673 ConvertLuvToXYZ(100.0*L,354.0*u-134.0,262.0*v-140.0,&X,&Y,&Z);
674 ConvertXYZToRGB(X,Y,Z,red,green,blue);
675}
676
677static void ConvertRGBToYDbDr(const double red,const double green,
678 const double blue,double *Y,double *Db,double *Dr)
679{
cristy8d24e062013-05-07 12:48:19 +0000680 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
681 *Db=QuantumScale*(-0.450*red-0.883*green+1.333*blue)+0.5;
682 *Dr=QuantumScale*(-1.333*red+1.116*green+0.217*blue)+0.5;
683}
684
685static void ConvertYDbDrToRGB(const double Y,const double Db,const double Dr,
686 double *red,double *green,double *blue)
687{
cristy8d24e062013-05-07 12:48:19 +0000688 *red=QuantumRange*(Y+9.2303716147657e-05*(Db-0.5)-0.52591263066186533*
689 (Dr-0.5));
690 *green=QuantumRange*(Y-0.12913289889050927*(Db-0.5)+0.26789932820759876*
691 (Dr-0.5));
692 *blue=QuantumRange*(Y+0.66467905997895482*(Db-0.5)-7.9202543533108e-05*
693 (Dr-0.5));
694}
695
696static void ConvertRGBToYIQ(const double red,const double green,
697 const double blue,double *Y,double *I,double *Q)
698{
cristy8d24e062013-05-07 12:48:19 +0000699 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
700 *I=QuantumScale*(0.595716*red-0.274453*green-0.321263*blue)+0.5;
701 *Q=QuantumScale*(0.211456*red-0.522591*green+0.311135*blue)+0.5;
702}
703
704static void ConvertYIQToRGB(const double Y,const double I,const double Q,
705 double *red,double *green,double *blue)
706{
cristy8d24e062013-05-07 12:48:19 +0000707 *red=QuantumRange*(Y+0.9562957197589482261*(I-0.5)+0.6210244164652610754*
708 (Q-0.5));
709 *green=QuantumRange*(Y-0.2721220993185104464*(I-0.5)-0.6473805968256950427*
710 (Q-0.5));
711 *blue=QuantumRange*(Y-1.1069890167364901945*(I-0.5)+1.7046149983646481374*
712 (Q-0.5));
713}
714
715static void ConvertRGBToYUV(const double red,const double green,
716 const double blue,double *Y,double *U,double *V)
717{
cristy8d24e062013-05-07 12:48:19 +0000718 *Y=QuantumScale*(0.298839*red+0.586811*green+0.114350*blue);
719 *U=QuantumScale*((-0.147)*red-0.289*green+0.436*blue)+0.5;
720 *V=QuantumScale*(0.615*red-0.515*green-0.100*blue)+0.5;
721}
722
723static void ConvertYUVToRGB(const double Y,const double U,const double V,
724 double *red,double *green,double *blue)
725{
cristy8d24e062013-05-07 12:48:19 +0000726 *red=QuantumRange*(Y-3.945707070708279e-05*(U-0.5)+1.1398279671717170825*
727 (V-0.5));
728 *green=QuantumRange*(Y-0.3946101641414141437*(U-0.5)-0.5805003156565656797*
729 (V-0.5));
730 *blue=QuantumRange*(Y+2.0319996843434342537*(U-0.5)-4.813762626262513e-04*
731 (V-0.5));
732}
733
734static MagickBooleanType ValidateHSIToRGB()
735{
736 double
737 r,
738 g,
739 b;
740
cristyb8588ab2013-05-07 13:17:38 +0000741 (void) FormatLocaleFile(stdout," HSIToRGB");
cristy8d24e062013-05-07 12:48:19 +0000742 ConvertHSIToRGB(111.244375/360.0,0.295985,0.658734,&r,&g,&b);
743 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
744 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
745 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
746 return(MagickFalse);
747 return(MagickTrue);
748}
749
750static MagickBooleanType ValidateRGBToHSI()
751{
752 double
753 h,
754 i,
755 s;
756
cristyb8588ab2013-05-07 13:17:38 +0000757 (void) FormatLocaleFile(stdout," RGBToHSI");
cristy8d24e062013-05-07 12:48:19 +0000758 ConvertRGBToHSI(0.545877*QuantumRange,0.966567*QuantumRange,
759 0.463759*QuantumRange,&h,&s,&i);
760 if ((fabs(h-111.244374/360.0) >= ReferenceEpsilon) ||
761 (fabs(s-0.295985) >= ReferenceEpsilon) ||
762 (fabs(i-0.658734) >= ReferenceEpsilon))
763 return(MagickFalse);
764 return(MagickTrue);
765}
766
767static MagickBooleanType ValidateHSLToRGB()
768{
769 double
770 r,
771 g,
772 b;
773
cristyb8588ab2013-05-07 13:17:38 +0000774 (void) FormatLocaleFile(stdout," HSLToRGB");
cristy8d24e062013-05-07 12:48:19 +0000775 ConvertHSLToRGB(110.200859/360.0,0.882623,0.715163,&r,&g,&b);
776 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
777 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
778 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
779 return(MagickFalse);
780 return(MagickTrue);
781}
782
783static MagickBooleanType ValidateRGBToHSL()
784{
785 double
786 h,
787 l,
788 s;
789
cristyb8588ab2013-05-07 13:17:38 +0000790 (void) FormatLocaleFile(stdout," RGBToHSL");
cristy8d24e062013-05-07 12:48:19 +0000791 ConvertRGBToHSL(0.545877*QuantumRange,0.966567*QuantumRange,
792 0.463759*QuantumRange,&h,&s,&l);
793 if ((fabs(h-110.200859/360.0) >= ReferenceEpsilon) ||
794 (fabs(s-0.882623) >= ReferenceEpsilon) ||
795 (fabs(l-0.715163) >= ReferenceEpsilon))
796 return(MagickFalse);
797 return(MagickTrue);
798}
799
800static MagickBooleanType ValidateHSVToRGB()
801{
802 double
803 r,
804 g,
805 b;
806
cristyb8588ab2013-05-07 13:17:38 +0000807 (void) FormatLocaleFile(stdout," HSVToRGB");
cristy8d24e062013-05-07 12:48:19 +0000808 ConvertHSVToRGB(110.200859/360.0,0.520200,0.966567,&r,&g,&b);
809 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
810 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
811 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
812 return(MagickFalse);
813 return(MagickTrue);
814}
815
816static MagickBooleanType ValidateRGBToHSV()
817{
818 double
819 h,
820 s,
821 v;
822
cristyb8588ab2013-05-07 13:17:38 +0000823 (void) FormatLocaleFile(stdout," RGBToHSV");
cristy8d24e062013-05-07 12:48:19 +0000824 ConvertRGBToHSV(0.545877*QuantumRange,0.966567*QuantumRange,
825 0.463759*QuantumRange,&h,&s,&v);
826 if ((fabs(h-110.200859/360.0) >= ReferenceEpsilon) ||
827 (fabs(s-0.520200) >= ReferenceEpsilon) ||
828 (fabs(v-0.966567) >= ReferenceEpsilon))
829 return(MagickFalse);
830 return(MagickTrue);
831}
832
833static MagickBooleanType ValidateRGBToJPEGYCbCr()
834{
835 double
836 Cb,
837 Cr,
838 Y;
839
cristyb8588ab2013-05-07 13:17:38 +0000840 (void) FormatLocaleFile(stdout," RGBToJPEGYCbCr");
cristy8d24e062013-05-07 12:48:19 +0000841 ConvertRGBToYCbCr(0.545877*QuantumRange,0.966567*QuantumRange,
842 0.463759*QuantumRange,&Y,&Cb,&Cr);
843 if ((fabs(Y-0.783460) >= ReferenceEpsilon) ||
844 (fabs(Cb-0.319581) >= ReferenceEpsilon) ||
845 (fabs(Cr-0.330539) >= ReferenceEpsilon))
846 return(MagickFalse);
847 return(MagickTrue);
848}
849
850static MagickBooleanType ValidateJPEGYCbCrToRGB()
851{
852 double
853 r,
854 g,
855 b;
856
cristyb8588ab2013-05-07 13:17:38 +0000857 (void) FormatLocaleFile(stdout," JPEGYCbCrToRGB");
cristy8d24e062013-05-07 12:48:19 +0000858 ConvertYCbCrToRGB(0.783460,0.319581,0.330539,&r,&g,&b);
859 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
860 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
861 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
862 return(MagickFalse);
863 return(MagickTrue);
864}
865
866static MagickBooleanType ValidateLabToRGB()
867{
868 double
869 r,
870 g,
871 b;
872
cristyb8588ab2013-05-07 13:17:38 +0000873 (void) FormatLocaleFile(stdout," LabToRGB");
cristy8d24e062013-05-07 12:48:19 +0000874 ConvertLabToRGB(88.456154/100.0,-54.671483/255+0.5,51.662818/255.0+0.5,
875 &r,&g,&b);
876 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
877 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
878 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
879 return(MagickFalse);
880 return(MagickTrue);
881}
882
883static MagickBooleanType ValidateRGBToLab()
884{
885 double
886 a,
887 b,
888 L;
889
cristyb8588ab2013-05-07 13:17:38 +0000890 (void) FormatLocaleFile(stdout," RGBToLab");
cristy8d24e062013-05-07 12:48:19 +0000891 ConvertRGBToLab(0.545877*QuantumRange,0.966567*QuantumRange,
892 0.463759*QuantumRange,&L,&a,&b);
893 if ((fabs(L-(88.456154/100.0)) >= ReferenceEpsilon) ||
894 (fabs(a-(-54.671483/255.0+0.5)) >= ReferenceEpsilon) ||
895 (fabs(b-(51.662818/255.0+0.5)) >= ReferenceEpsilon))
896 return(MagickFalse);
897 return(MagickTrue);
898}
899
900static MagickBooleanType ValidateLchToRGB()
901{
902 double
903 b,
904 g,
905 r;
906
cristyb8588ab2013-05-07 13:17:38 +0000907 (void) FormatLocaleFile(stdout," LchToRGB");
cristy8d24e062013-05-07 12:48:19 +0000908 ConvertLCHabToRGB(88.456154/100.0,75.219797/255.0+0.5,136.620717/255.0+0.5,
909 &r,&g,&b);
910 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
911 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
912 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
913 return(MagickFalse);
914 return(MagickTrue);
915}
916
917static MagickBooleanType ValidateRGBToLch()
918{
919 double
920 c,
921 h,
922 L;
923
cristyb8588ab2013-05-07 13:17:38 +0000924 (void) FormatLocaleFile(stdout," RGBToLch");
cristy8d24e062013-05-07 12:48:19 +0000925 ConvertRGBToLCHab(0.545877*QuantumRange,0.966567*QuantumRange,
926 0.463759*QuantumRange,&L,&c,&h);
927 if ((fabs(L-88.456154/100.0) >= ReferenceEpsilon) ||
928 (fabs(c-(75.219797/255.0+0.5)) >= ReferenceEpsilon) ||
929 (fabs(h-(136.620717/255.0+0.5)) >= ReferenceEpsilon))
930 return(MagickFalse);
931 return(MagickTrue);
932}
933
934static MagickBooleanType ValidateRGBToLMS()
935{
936 double
937 L,
938 M,
939 S;
940
cristyb8588ab2013-05-07 13:17:38 +0000941 (void) FormatLocaleFile(stdout," RGBToLMS");
cristy8d24e062013-05-07 12:48:19 +0000942 ConvertRGBToLMS(0.545877*QuantumRange,0.966567*QuantumRange,
943 0.463759*QuantumRange,&L,&M,&S);
944 if ((fabs(L-0.611749) >= ReferenceEpsilon) ||
945 (fabs(M-0.910088) >= ReferenceEpsilon) ||
946 (fabs(S-0.294880) >= ReferenceEpsilon))
947 return(MagickFalse);
948 return(MagickTrue);
949}
950
951static MagickBooleanType ValidateLMSToRGB()
952{
953 double
954 r,
955 g,
956 b;
957
cristyb8588ab2013-05-07 13:17:38 +0000958 (void) FormatLocaleFile(stdout," LMSToRGB");
cristy8d24e062013-05-07 12:48:19 +0000959 ConvertLMSToRGB(0.611749,0.910088,0.294880,&r,&g,&b);
960 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
961 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
962 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
963 return(MagickFalse);
964 return(MagickTrue);
965}
966
967static MagickBooleanType ValidateRGBToLuv()
968{
969 double
970 l,
971 u,
972 v;
973
cristyb8588ab2013-05-07 13:17:38 +0000974 (void) FormatLocaleFile(stdout," RGBToLuv");
cristy8d24e062013-05-07 12:48:19 +0000975 ConvertRGBToLuv(0.545877*QuantumRange,0.966567*QuantumRange,
976 0.463759*QuantumRange,&l,&u,&v);
977 if ((fabs(l-88.456154/262.0) >= ReferenceEpsilon) ||
978 (fabs(u-(-51.330414+134.0)/354.0) >= ReferenceEpsilon) ||
979 (fabs(v-(76.405526+140.0)/262.0) >= ReferenceEpsilon))
980 return(MagickFalse);
981 return(MagickTrue);
982}
983
984static MagickBooleanType ValidateLuvToRGB()
985{
986 double
987 r,
988 g,
989 b;
990
cristyb8588ab2013-05-07 13:17:38 +0000991 (void) FormatLocaleFile(stdout," LuvToRGB");
cristy8d24e062013-05-07 12:48:19 +0000992 ConvertLuvToRGB(88.456154/100.0,(-51.330414+134.0)/354.0,
993 (76.405526+140.0)/262.0,&r,&g,&b);
994 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
995 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
996 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
997 return(MagickFalse);
998 return(MagickTrue);
999}
1000
1001static MagickBooleanType ValidateRGBToXYZ()
1002{
1003 double
1004 x,
1005 y,
1006 z;
1007
cristyb8588ab2013-05-07 13:17:38 +00001008 (void) FormatLocaleFile(stdout," RGBToXYZ");
cristy8d24e062013-05-07 12:48:19 +00001009 ConvertRGBToXYZ(0.545877*QuantumRange,0.966567*QuantumRange,
1010 0.463759*QuantumRange,&x,&y,&z);
1011 if ((fabs(x-0.470646) >= ReferenceEpsilon) ||
1012 (fabs(y-0.730178) >= ReferenceEpsilon) ||
1013 (fabs(z-0.288324) >= ReferenceEpsilon))
1014 return(MagickFalse);
1015 return(MagickTrue);
1016}
1017
1018static MagickBooleanType ValidateXYZToRGB()
1019{
1020 double
1021 r,
1022 g,
1023 b;
1024
cristyb8588ab2013-05-07 13:17:38 +00001025 (void) FormatLocaleFile(stdout," XYZToRGB");
cristy8d24e062013-05-07 12:48:19 +00001026 ConvertXYZToRGB(0.470646,0.730178,0.288324,&r,&g,&b);
1027 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
1028 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
1029 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
1030 return(MagickFalse);
1031 return(MagickTrue);
1032}
1033
1034static MagickBooleanType ValidateYDbDrToRGB()
1035{
1036 double
1037 r,
1038 g,
1039 b;
1040
cristyb8588ab2013-05-07 13:17:38 +00001041 (void) FormatLocaleFile(stdout," YDbDrToRGB");
cristy8d24e062013-05-07 12:48:19 +00001042 ConvertYDbDrToRGB(0.783460,-0.480932+0.5,0.451670+0.5,&r,&g,&b);
1043 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
1044 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
1045 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
1046 return(MagickFalse);
1047 return(MagickTrue);
1048}
1049
1050static MagickBooleanType ValidateRGBToYDbDr()
1051{
1052 double
1053 Db,
1054 Dr,
1055 Y;
1056
cristyb8588ab2013-05-07 13:17:38 +00001057 (void) FormatLocaleFile(stdout," RGBToYDbDr");
cristy8d24e062013-05-07 12:48:19 +00001058 ConvertRGBToYDbDr(0.545877*QuantumRange,0.966567*QuantumRange,
1059 0.463759*QuantumRange,&Y,&Db,&Dr);
1060 if ((fabs(Y-0.783460) >= ReferenceEpsilon) ||
1061 (fabs(Db-(-0.480932)) >= ReferenceEpsilon) ||
1062 (fabs(Dr-0.451670) >= ReferenceEpsilon))
1063 return(MagickFalse);
1064 return(MagickTrue);
1065}
1066
1067static MagickBooleanType ValidateRGBToYIQ()
1068{
1069 double
1070 i,
1071 q,
1072 y;
1073
cristyb8588ab2013-05-07 13:17:38 +00001074 (void) FormatLocaleFile(stdout," RGBToYIQ");
cristy8d24e062013-05-07 12:48:19 +00001075 ConvertRGBToYIQ(0.545877*QuantumRange,0.966567*QuantumRange,
1076 0.463759*QuantumRange,&y,&i,&q);
1077 if ((fabs(y-0.783460) >= ReferenceEpsilon) ||
1078 (fabs(i-(-0.089078)) >= ReferenceEpsilon) ||
1079 (fabs(q-(-0.245399)) >= ReferenceEpsilon))
1080 return(MagickFalse);
1081 return(MagickTrue);
1082}
1083
1084static MagickBooleanType ValidateYIQToRGB()
1085{
1086 double
1087 r,
1088 g,
1089 b;
1090
cristyb8588ab2013-05-07 13:17:38 +00001091 (void) FormatLocaleFile(stdout," YIQToRGB");
cristy8d24e062013-05-07 12:48:19 +00001092 ConvertYIQToRGB(0.783460,-0.089078+0.5,-0.245399+0.5,&r,&g,&b);
1093 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
1094 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
1095 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
1096 return(MagickFalse);
1097 return(MagickTrue);
1098}
1099
1100static MagickBooleanType ValidateRGBToYPbPr()
1101{
1102 double
cristy4ae2e762013-05-07 13:19:24 +00001103 Pb,
1104 Pr,
cristy8d24e062013-05-07 12:48:19 +00001105 y;
1106
cristyb8588ab2013-05-07 13:17:38 +00001107 (void) FormatLocaleFile(stdout," RGBToYPbPr");
cristy8d24e062013-05-07 12:48:19 +00001108 ConvertRGBToYPbPr(0.545877*QuantumRange,0.966567*QuantumRange,
cristy4ae2e762013-05-07 13:19:24 +00001109 0.463759*QuantumRange,&y,&Pb,&Pr);
cristy8d24e062013-05-07 12:48:19 +00001110 if ((fabs(y-0.783460) >= ReferenceEpsilon) ||
cristy4ae2e762013-05-07 13:19:24 +00001111 (fabs(Pb-(-0.180419)) >= ReferenceEpsilon) ||
1112 (fabs(Pr-(-0.169461)) >= ReferenceEpsilon))
cristy8d24e062013-05-07 12:48:19 +00001113 return(MagickFalse);
1114 return(MagickTrue);
1115}
1116
1117static MagickBooleanType ValidateYPbPrToRGB()
1118{
1119 double
1120 r,
1121 g,
1122 b;
1123
cristyb8588ab2013-05-07 13:17:38 +00001124 (void) FormatLocaleFile(stdout," YPbPrToRGB");
cristy8d24e062013-05-07 12:48:19 +00001125 ConvertYPbPrToRGB(0.783460,-0.180419+0.5,-0.169461+0.5,&r,&g,&b);
1126 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
1127 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
1128 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
1129 return(MagickFalse);
1130 return(MagickTrue);
1131}
1132
1133static MagickBooleanType ValidateRGBToYUV()
1134{
1135 double
1136 U,
1137 V,
1138 Y;
1139
cristyb8588ab2013-05-07 13:17:38 +00001140 (void) FormatLocaleFile(stdout," RGBToYUV");
cristy8d24e062013-05-07 12:48:19 +00001141 ConvertRGBToYUV(0.545877*QuantumRange,0.966567*QuantumRange,
1142 0.463759*QuantumRange,&Y,&U,&V);
1143 if ((fabs(Y-0.783460) >= ReferenceEpsilon) ||
1144 (fabs(U-(-0.157383)) >= ReferenceEpsilon) ||
1145 (fabs(V-(-0.208443)) >= ReferenceEpsilon))
1146 return(MagickFalse);
1147 return(MagickTrue);
1148}
1149
1150static MagickBooleanType ValidateYUVToRGB()
1151{
1152 double
1153 r,
1154 g,
1155 b;
1156
cristyb8588ab2013-05-07 13:17:38 +00001157 (void) FormatLocaleFile(stdout," YUVToRGB");
cristy8d24e062013-05-07 12:48:19 +00001158 ConvertYUVToRGB(0.783460,-0.157383+0.5,-0.208443+0.5,&r,&g,&b);
1159 if ((fabs(r-0.545877*QuantumRange) >= ReferenceEpsilon) ||
1160 (fabs(g-0.966567*QuantumRange) >= ReferenceEpsilon) ||
1161 (fabs(b-0.463759*QuantumRange) >= ReferenceEpsilon))
1162 return(MagickFalse);
1163 return(MagickTrue);
1164}
1165
cristy572e0972013-05-07 12:51:28 +00001166static size_t ValidateColorspaces(ImageInfo *image_info,size_t *fail,
cristy80e870e2013-05-07 12:23:02 +00001167 ExceptionInfo *exception)
1168{
1169 MagickBooleanType
1170 status;
1171
cristy80e870e2013-05-07 12:23:02 +00001172 size_t
1173 test;
1174
cristy8d24e062013-05-07 12:48:19 +00001175 /*
cristy92e5cea2013-05-08 12:24:12 +00001176 Reference: https://code.google.com/p/chroma.
cristy8d24e062013-05-07 12:48:19 +00001177
1178 Illuminant = D65
1179 Observer = 2° (1931)
1180
1181 XYZ 0.470645, 0.730177, 0.288323
1182 sRGB 0.545877, 0.966567, 0.463759
1183 CAT02 LMS 0.611749, 0.910088, 0.294880
1184 Y'DbDr 0.783460, -0.480932, 0.451670
1185 Y'IQ 0.783460, -0.089078, -0.245399
1186 Y'PbPr 0.783460, -0.180419, -0.169461
1187 Y'UV 0.783460, -0.157383, -0.208443
1188 JPEG-Y'CbCr 0.783460, 0.319581, 0.330539
1189 L*u*v* 88.456154, -51.330414, 76.405526
1190 L*a*b* 88.456154, -54.671483, 51.662818
1191 L*C*H* 88.456154, 75.219797, 136.620717
1192 HSV 110.200859, 0.520200, 0.966567
1193 HSL 110.200859, 0.882623, 0.715163
1194 HSI 111.244375, 0.295985, 0.658734
1195 Y'CbCr 187.577791, 87.586330, 90.040886
cristy8d24e062013-05-07 12:48:19 +00001196 */
cristy80e870e2013-05-07 12:23:02 +00001197 (void) FormatLocaleFile(stdout,"validate colorspaces:\n");
cristy8d24e062013-05-07 12:48:19 +00001198 for (test=0; test < 26; test++)
1199 {
1200 CatchException(exception);
1201 (void) FormatLocaleFile(stdout," test %.20g: ",(double) test);
1202 switch (test)
cristy80e870e2013-05-07 12:23:02 +00001203 {
cristy8d24e062013-05-07 12:48:19 +00001204 case 0: status=ValidateHSIToRGB(); break;
1205 case 1: status=ValidateRGBToHSI(); break;
1206 case 2: status=ValidateHSLToRGB(); break;
1207 case 3: status=ValidateRGBToHSL(); break;
1208 case 4: status=ValidateHSVToRGB(); break;
1209 case 5: status=ValidateRGBToHSV(); break;
1210 case 6: status=ValidateJPEGYCbCrToRGB(); break;
1211 case 7: status=ValidateRGBToJPEGYCbCr(); break;
1212 case 8: status=ValidateLabToRGB(); break;
1213 case 9: status=ValidateRGBToLab(); break;
1214 case 10: status=ValidateLchToRGB(); break;
1215 case 11: status=ValidateRGBToLch(); break;
1216 case 12: status=ValidateLMSToRGB(); break;
1217 case 13: status=ValidateRGBToLMS(); break;
1218 case 14: status=ValidateLuvToRGB(); break;
1219 case 15: status=ValidateRGBToLuv(); break;
1220 case 16: status=ValidateXYZToRGB(); break;
1221 case 17: status=ValidateRGBToXYZ(); break;
1222 case 18: status=ValidateYDbDrToRGB(); break;
1223 case 19: status=ValidateRGBToYDbDr(); break;
1224 case 20: status=ValidateYIQToRGB(); break;
1225 case 21: status=ValidateRGBToYIQ(); break;
1226 case 22: status=ValidateYPbPrToRGB(); break;
1227 case 23: status=ValidateRGBToYPbPr(); break;
1228 case 24: status=ValidateYUVToRGB(); break;
1229 case 25: status=ValidateRGBToYUV(); break;
1230 default: status=MagickFalse;
cristy80e870e2013-05-07 12:23:02 +00001231 }
cristyb8588ab2013-05-07 13:17:38 +00001232 if (status == MagickFalse)
cristy8d24e062013-05-07 12:48:19 +00001233 {
1234 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1235 GetMagickModule());
1236 (*fail)++;
1237 continue;
1238 }
1239 (void) FormatLocaleFile(stdout,"... pass.\n");
1240 }
cristy80e870e2013-05-07 12:23:02 +00001241 (void) FormatLocaleFile(stdout,
1242 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1243 (double) (test-(*fail)),(double) *fail);
1244 return(test);
1245}
1246
1247/*
1248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1249% %
1250% %
1251% %
cristy3ed852e2009-09-05 21:47:34 +00001252% V a l i d a t e C o m p a r e C o m m a n d %
1253% %
1254% %
1255% %
1256%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1257%
1258% ValidateCompareCommand() validates the ImageMagick compare command line
1259% program and returns the number of validation tests that passed and failed.
1260%
1261% The format of the ValidateCompareCommand method is:
1262%
cristybb503372010-05-27 20:51:26 +00001263% size_t ValidateCompareCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001264% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001265% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001266%
1267% A description of each parameter follows:
1268%
1269% o image_info: the image info.
1270%
1271% o reference_filename: the reference image filename.
1272%
1273% o output_filename: the output image filename.
1274%
1275% o fail: return the number of validation tests that pass.
1276%
1277% o exception: return any errors or warnings in this structure.
1278%
1279*/
cristybb503372010-05-27 20:51:26 +00001280static size_t ValidateCompareCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001281 const char *reference_filename,const char *output_filename,size_t *fail,
1282 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001283{
1284 char
1285 **arguments,
1286 command[MaxTextExtent];
1287
1288 int
1289 number_arguments;
1290
1291 MagickBooleanType
1292 status;
1293
cristybb503372010-05-27 20:51:26 +00001294 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001295 i,
1296 j;
1297
cristybb503372010-05-27 20:51:26 +00001298 size_t
cristy3ed852e2009-09-05 21:47:34 +00001299 test;
1300
1301 test=0;
cristyb51dff52011-05-19 16:55:47 +00001302 (void) FormatLocaleFile(stdout,"validate compare command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00001303 for (i=0; compare_options[i] != (char *) NULL; i++)
1304 {
1305 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00001306 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00001307 compare_options[i]);
cristyb51dff52011-05-19 16:55:47 +00001308 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
cristy3ed852e2009-09-05 21:47:34 +00001309 compare_options[i],reference_filename,reference_filename,output_filename);
1310 arguments=StringToArgv(command,&number_arguments);
1311 if (arguments == (char **) NULL)
1312 {
cristy1e604812011-05-19 18:07:50 +00001313 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1314 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001315 (*fail)++;
1316 continue;
1317 }
cristy8a9106f2011-07-05 14:39:26 +00001318 status=CompareImagesCommand(image_info,number_arguments,arguments,
cristy3ed852e2009-09-05 21:47:34 +00001319 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00001320 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00001321 arguments[j]=DestroyString(arguments[j]);
1322 arguments=(char **) RelinquishMagickMemory(arguments);
1323 if (status != MagickFalse)
1324 {
cristy1e604812011-05-19 18:07:50 +00001325 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1326 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001327 (*fail)++;
1328 continue;
1329 }
cristyb51dff52011-05-19 16:55:47 +00001330 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00001331 }
cristyb51dff52011-05-19 16:55:47 +00001332 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00001333 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1334 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001335 return(test);
1336}
1337
1338/*
1339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1340% %
1341% %
1342% %
1343% V a l i d a t e C o m p o s i t e C o m m a n d %
1344% %
1345% %
1346% %
1347%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1348%
1349% ValidateCompositeCommand() validates the ImageMagick composite command line
1350% program and returns the number of validation tests that passed and failed.
1351%
1352% The format of the ValidateCompositeCommand method is:
1353%
cristybb503372010-05-27 20:51:26 +00001354% size_t ValidateCompositeCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001355% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001356% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001357%
1358% A description of each parameter follows:
1359%
1360% o image_info: the image info.
1361%
1362% o reference_filename: the reference image filename.
1363%
1364% o output_filename: the output image filename.
1365%
1366% o fail: return the number of validation tests that pass.
1367%
1368% o exception: return any errors or warnings in this structure.
1369%
1370*/
cristybb503372010-05-27 20:51:26 +00001371static size_t ValidateCompositeCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001372 const char *reference_filename,const char *output_filename,size_t *fail,
1373 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001374{
1375 char
1376 **arguments,
1377 command[MaxTextExtent];
1378
1379 int
1380 number_arguments;
1381
1382 MagickBooleanType
1383 status;
1384
cristybb503372010-05-27 20:51:26 +00001385 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001386 i,
1387 j;
1388
cristybb503372010-05-27 20:51:26 +00001389 size_t
cristy3ed852e2009-09-05 21:47:34 +00001390 test;
1391
1392 test=0;
cristyb51dff52011-05-19 16:55:47 +00001393 (void) FormatLocaleFile(stdout,"validate composite command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00001394 for (i=0; composite_options[i] != (char *) NULL; i++)
1395 {
1396 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00001397 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00001398 composite_options[i]);
cristyb51dff52011-05-19 16:55:47 +00001399 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
cristy3ed852e2009-09-05 21:47:34 +00001400 reference_filename,composite_options[i],reference_filename,
1401 output_filename);
1402 arguments=StringToArgv(command,&number_arguments);
1403 if (arguments == (char **) NULL)
1404 {
cristy1e604812011-05-19 18:07:50 +00001405 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1406 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001407 (*fail)++;
1408 continue;
1409 }
1410 status=CompositeImageCommand(image_info,number_arguments,arguments,
1411 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00001412 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00001413 arguments[j]=DestroyString(arguments[j]);
1414 arguments=(char **) RelinquishMagickMemory(arguments);
1415 if (status != MagickFalse)
1416 {
cristy1e604812011-05-19 18:07:50 +00001417 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1418 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001419 (*fail)++;
1420 continue;
1421 }
cristyb51dff52011-05-19 16:55:47 +00001422 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00001423 }
cristyb51dff52011-05-19 16:55:47 +00001424 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00001425 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1426 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001427 return(test);
1428}
1429
1430/*
1431%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1432% %
1433% %
1434% %
1435% V a l i d a t e C o n v e r t C o m m a n d %
1436% %
1437% %
1438% %
1439%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1440%
1441% ValidateConvertCommand() validates the ImageMagick convert command line
1442% program and returns the number of validation tests that passed and failed.
1443%
1444% The format of the ValidateConvertCommand method is:
1445%
cristybb503372010-05-27 20:51:26 +00001446% size_t ValidateConvertCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001447% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001448% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001449%
1450% A description of each parameter follows:
1451%
1452% o image_info: the image info.
1453%
1454% o reference_filename: the reference image filename.
1455%
1456% o output_filename: the output image filename.
1457%
1458% o fail: return the number of validation tests that pass.
1459%
1460% o exception: return any errors or warnings in this structure.
1461%
1462*/
cristybb503372010-05-27 20:51:26 +00001463static size_t ValidateConvertCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001464 const char *reference_filename,const char *output_filename,size_t *fail,
1465 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001466{
1467 char
1468 **arguments,
1469 command[MaxTextExtent];
1470
1471 int
1472 number_arguments;
1473
1474 MagickBooleanType
1475 status;
1476
cristybb503372010-05-27 20:51:26 +00001477 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001478 i,
1479 j;
1480
cristybb503372010-05-27 20:51:26 +00001481 size_t
cristy3ed852e2009-09-05 21:47:34 +00001482 test;
1483
1484 test=0;
cristyb51dff52011-05-19 16:55:47 +00001485 (void) FormatLocaleFile(stdout,"validate convert command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00001486 for (i=0; convert_options[i] != (char *) NULL; i++)
1487 {
1488 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00001489 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++,
cristy6aa47ad2010-05-28 19:32:32 +00001490 convert_options[i]);
cristyb51dff52011-05-19 16:55:47 +00001491 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
cristy3ed852e2009-09-05 21:47:34 +00001492 reference_filename,convert_options[i],reference_filename,output_filename);
1493 arguments=StringToArgv(command,&number_arguments);
1494 if (arguments == (char **) NULL)
1495 {
cristy1e604812011-05-19 18:07:50 +00001496 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1497 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001498 (*fail)++;
1499 continue;
1500 }
1501 status=ConvertImageCommand(image_info,number_arguments,arguments,
1502 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00001503 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00001504 arguments[j]=DestroyString(arguments[j]);
1505 arguments=(char **) RelinquishMagickMemory(arguments);
1506 if (status != MagickFalse)
1507 {
cristy1e604812011-05-19 18:07:50 +00001508 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1509 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001510 (*fail)++;
1511 continue;
1512 }
cristyb51dff52011-05-19 16:55:47 +00001513 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00001514 }
cristyb51dff52011-05-19 16:55:47 +00001515 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00001516 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1517 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001518 return(test);
1519}
1520
1521/*
1522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1523% %
1524% %
1525% %
1526% V a l i d a t e I d e n t i f y C o m m a n d %
1527% %
1528% %
1529% %
1530%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1531%
1532% ValidateIdentifyCommand() validates the ImageMagick identify command line
1533% program and returns the number of validation tests that passed and failed.
1534%
1535% The format of the ValidateIdentifyCommand method is:
1536%
cristybb503372010-05-27 20:51:26 +00001537% size_t ValidateIdentifyCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001538% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001539% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001540%
1541% A description of each parameter follows:
1542%
1543% o image_info: the image info.
1544%
1545% o reference_filename: the reference image filename.
1546%
1547% o output_filename: the output image filename.
1548%
1549% o fail: return the number of validation tests that pass.
1550%
1551% o exception: return any errors or warnings in this structure.
1552%
1553*/
cristybb503372010-05-27 20:51:26 +00001554static size_t ValidateIdentifyCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001555 const char *reference_filename,const char *output_filename,size_t *fail,
1556 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001557{
1558 char
1559 **arguments,
1560 command[MaxTextExtent];
1561
1562 int
1563 number_arguments;
1564
1565 MagickBooleanType
1566 status;
1567
cristybb503372010-05-27 20:51:26 +00001568 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001569 i,
1570 j;
1571
cristybb503372010-05-27 20:51:26 +00001572 size_t
cristy3ed852e2009-09-05 21:47:34 +00001573 test;
1574
1575 (void) output_filename;
1576 test=0;
cristyb51dff52011-05-19 16:55:47 +00001577 (void) FormatLocaleFile(stdout,"validate identify command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00001578 for (i=0; identify_options[i] != (char *) NULL; i++)
1579 {
1580 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00001581 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) test++,
cristy6aa47ad2010-05-28 19:32:32 +00001582 identify_options[i]);
cristyb51dff52011-05-19 16:55:47 +00001583 (void) FormatLocaleString(command,MaxTextExtent,"%s %s",
cristy3ed852e2009-09-05 21:47:34 +00001584 identify_options[i],reference_filename);
1585 arguments=StringToArgv(command,&number_arguments);
1586 if (arguments == (char **) NULL)
1587 {
cristy1e604812011-05-19 18:07:50 +00001588 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1589 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001590 (*fail)++;
1591 continue;
1592 }
1593 status=IdentifyImageCommand(image_info,number_arguments,arguments,
1594 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00001595 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00001596 arguments[j]=DestroyString(arguments[j]);
1597 arguments=(char **) RelinquishMagickMemory(arguments);
1598 if (status != MagickFalse)
1599 {
cristy1e604812011-05-19 18:07:50 +00001600 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1601 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001602 (*fail)++;
1603 continue;
1604 }
cristyb51dff52011-05-19 16:55:47 +00001605 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00001606 }
cristyb51dff52011-05-19 16:55:47 +00001607 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00001608 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1609 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001610 return(test);
1611}
1612
1613/*
1614%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1615% %
1616% %
1617% %
1618% 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 %
1619% %
1620% %
1621% %
1622%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1623%
1624% ValidateImageFormatsInMemory() validates the ImageMagick image formats in
1625% memory and returns the number of validation tests that passed and failed.
1626%
1627% The format of the ValidateImageFormatsInMemory method is:
1628%
cristybb503372010-05-27 20:51:26 +00001629% size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001630% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001631% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001632%
1633% A description of each parameter follows:
1634%
1635% o image_info: the image info.
1636%
1637% o reference_filename: the reference image filename.
1638%
1639% o output_filename: the output image filename.
1640%
1641% o fail: return the number of validation tests that pass.
1642%
1643% o exception: return any errors or warnings in this structure.
1644%
1645*/
glennrp4084cda2012-12-11 14:13:35 +00001646
cristy725833f2012-12-13 17:40:53 +00001647/*
1648 Enable this to count remaining $TMPDIR/magick-* files. Note that the count
1649 includes any files left over from other runs.
1650*/
1651#undef MagickCountTempFiles
glennrp4084cda2012-12-11 14:13:35 +00001652
cristybb503372010-05-27 20:51:26 +00001653static size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001654 const char *reference_filename,const char *output_filename,size_t *fail,
1655 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001656{
1657 char
glennrp4084cda2012-12-11 14:13:35 +00001658#ifdef MagickCountTempFiles
glennrp4084cda2012-12-11 14:13:35 +00001659 path[MaxTextExtent],
cristy77b33ba2013-03-28 13:23:13 +00001660 SystemCommand[MaxTextExtent],
glennrp4084cda2012-12-11 14:13:35 +00001661#endif
cristy3ed852e2009-09-05 21:47:34 +00001662 size[MaxTextExtent];
1663
1664 const MagickInfo
1665 *magick_info;
1666
1667 double
1668 distortion,
1669 fuzz;
1670
1671 Image
1672 *difference_image,
cristy2c404222012-06-10 15:36:30 +00001673 *ping_image,
cristy6b9ae3f2012-06-10 15:39:34 +00001674 *reconstruct_image,
cristy100b8d92012-01-08 00:32:49 +00001675 *reference_image;
cristy3ed852e2009-09-05 21:47:34 +00001676
1677 MagickBooleanType
1678 status;
1679
cristybb503372010-05-27 20:51:26 +00001680 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001681 i,
1682 j;
1683
1684 size_t
cristy100b8d92012-01-08 00:32:49 +00001685 length,
1686 test;
cristy3ed852e2009-09-05 21:47:34 +00001687
1688 unsigned char
1689 *blob;
1690
cristy3ed852e2009-09-05 21:47:34 +00001691 test=0;
cristyb51dff52011-05-19 16:55:47 +00001692 (void) FormatLocaleFile(stdout,"validate image formats in memory:\n");
glennrp4084cda2012-12-11 14:13:35 +00001693
1694#ifdef MagickCountTempFiles
1695 (void)GetPathTemplate(path);
glennrp33fb8032013-01-07 18:43:03 +00001696 /* Remove file template except for the leading "/path/to/magick-" */
glennrp4084cda2012-12-11 14:13:35 +00001697 path[strlen(path)-17]='\0';
1698 (void) FormatLocaleFile(stdout," tmp path is '%s*'\n",path);
1699#endif
1700
cristy3ed852e2009-09-05 21:47:34 +00001701 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
1702 {
1703 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
1704 if ((magick_info == (const MagickInfo *) NULL) ||
1705 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
1706 (magick_info->encoder == (EncodeImageHandler *) NULL))
1707 continue;
cristy5f1c1ff2010-12-23 21:38:06 +00001708 for (j=0; reference_types[j].type != UndefinedType; j++)
cristy3ed852e2009-09-05 21:47:34 +00001709 {
1710 /*
1711 Generate reference image.
1712 */
1713 CatchException(exception);
cristy1e604812011-05-19 18:07:50 +00001714 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits",
1715 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic(
cristy7998e5f2009-10-08 02:45:33 +00001716 MagickCompressOptions,reference_formats[i].compression),
cristy042ee782011-04-22 18:48:30 +00001717 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
cristy75a26232010-06-03 17:15:02 +00001718 (double) reference_types[j].depth);
cristy3ed852e2009-09-05 21:47:34 +00001719 (void) CopyMagickString(image_info->filename,reference_filename,
1720 MaxTextExtent);
1721 reference_image=ReadImage(image_info,exception);
1722 if (reference_image == (Image *) NULL)
1723 {
cristy1e604812011-05-19 18:07:50 +00001724 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1725 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001726 (*fail)++;
1727 continue;
1728 }
1729 /*
1730 Write reference image.
1731 */
cristyb51dff52011-05-19 16:55:47 +00001732 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",
cristy75a26232010-06-03 17:15:02 +00001733 (double) reference_image->columns,(double) reference_image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001734 (void) CloneString(&image_info->size,size);
1735 image_info->depth=reference_types[j].depth;
cristyb51dff52011-05-19 16:55:47 +00001736 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00001737 reference_formats[i].magick,output_filename);
cristy018f07f2011-09-04 21:15:19 +00001738 status=SetImageType(reference_image,reference_types[j].type,exception);
cristy3ed852e2009-09-05 21:47:34 +00001739 if (status == MagickFalse)
1740 {
cristy1e604812011-05-19 18:07:50 +00001741 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1742 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001743 (*fail)++;
1744 reference_image=DestroyImage(reference_image);
1745 continue;
1746 }
cristy8a11cb12011-10-19 23:53:34 +00001747 status=SetImageDepth(reference_image,reference_types[j].depth,exception);
cristy3ed852e2009-09-05 21:47:34 +00001748 if (status == MagickFalse)
1749 {
cristy1e604812011-05-19 18:07:50 +00001750 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1751 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001752 (*fail)++;
1753 reference_image=DestroyImage(reference_image);
1754 continue;
1755 }
cristy7998e5f2009-10-08 02:45:33 +00001756 reference_image->compression=reference_formats[i].compression;
cristy6f9e0d32011-08-28 16:32:09 +00001757 status=WriteImage(image_info,reference_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00001758 reference_image=DestroyImage(reference_image);
1759 if (status == MagickFalse)
1760 {
cristy1e604812011-05-19 18:07:50 +00001761 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1762 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001763 (*fail)++;
1764 continue;
1765 }
1766 /*
cristy2c404222012-06-10 15:36:30 +00001767 Ping reference image.
cristy3ed852e2009-09-05 21:47:34 +00001768 */
cristyb51dff52011-05-19 16:55:47 +00001769 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00001770 reference_formats[i].magick,output_filename);
cristy2c404222012-06-10 15:36:30 +00001771 ping_image=PingImage(image_info,exception);
1772 if (ping_image == (Image *) NULL)
1773 {
1774 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1775 GetMagickModule());
1776 (*fail)++;
1777 continue;
1778 }
1779 ping_image=DestroyImage(ping_image);
1780 /*
1781 Read reference image.
1782 */
cristy3ed852e2009-09-05 21:47:34 +00001783 reference_image=ReadImage(image_info,exception);
1784 if (reference_image == (Image *) NULL)
1785 {
cristy1e604812011-05-19 18:07:50 +00001786 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1787 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001788 (*fail)++;
1789 continue;
1790 }
1791 /*
1792 Write reference image.
1793 */
cristyb51dff52011-05-19 16:55:47 +00001794 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00001795 reference_formats[i].magick,output_filename);
1796 (void) CopyMagickString(image_info->magick,reference_formats[i].magick,
1797 MaxTextExtent);
1798 reference_image->depth=reference_types[j].depth;
cristy7998e5f2009-10-08 02:45:33 +00001799 reference_image->compression=reference_formats[i].compression;
cristy3ed852e2009-09-05 21:47:34 +00001800 length=8192;
1801 blob=ImageToBlob(image_info,reference_image,&length,exception);
1802 if (blob == (unsigned char *) NULL)
1803 {
cristy1e604812011-05-19 18:07:50 +00001804 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1805 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001806 (*fail)++;
1807 reference_image=DestroyImage(reference_image);
1808 continue;
1809 }
1810 /*
cristy2c404222012-06-10 15:36:30 +00001811 Ping reference blob.
1812 */
1813 ping_image=PingBlob(image_info,blob,length,exception);
1814 if (ping_image == (Image *) NULL)
1815 {
1816 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1817 GetMagickModule());
1818 (*fail)++;
1819 blob=(unsigned char *) RelinquishMagickMemory(blob);
1820 continue;
1821 }
1822 ping_image=DestroyImage(ping_image);
1823 /*
cristy3ed852e2009-09-05 21:47:34 +00001824 Read reconstruct image.
1825 */
cristyb51dff52011-05-19 16:55:47 +00001826 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00001827 reference_formats[i].magick,output_filename);
1828 reconstruct_image=BlobToImage(image_info,blob,length,exception);
1829 blob=(unsigned char *) RelinquishMagickMemory(blob);
1830 if (reconstruct_image == (Image *) NULL)
1831 {
cristy1e604812011-05-19 18:07:50 +00001832 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1833 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001834 (*fail)++;
1835 reference_image=DestroyImage(reference_image);
1836 continue;
1837 }
1838 /*
1839 Compare reference to reconstruct image.
1840 */
cristy93540ab2013-03-30 19:59:41 +00001841 fuzz=0.003; /* grayscale */
cristy3ed852e2009-09-05 21:47:34 +00001842 if (reference_formats[i].fuzz != 0.0)
1843 fuzz=reference_formats[i].fuzz;
cristy8a9106f2011-07-05 14:39:26 +00001844 difference_image=CompareImages(reference_image,reconstruct_image,
cristy864c6a82012-06-19 16:45:22 +00001845 RootMeanSquaredErrorMetric,&distortion,exception);
cristy3ed852e2009-09-05 21:47:34 +00001846 reconstruct_image=DestroyImage(reconstruct_image);
1847 reference_image=DestroyImage(reference_image);
1848 if (difference_image == (Image *) NULL)
1849 {
cristy1e604812011-05-19 18:07:50 +00001850 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1851 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001852 (*fail)++;
1853 continue;
1854 }
1855 difference_image=DestroyImage(difference_image);
cristy14154222012-06-15 23:21:49 +00001856 if ((QuantumScale*distortion) > fuzz)
cristy3ed852e2009-09-05 21:47:34 +00001857 {
cristyb51dff52011-05-19 16:55:47 +00001858 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
cristy14154222012-06-15 23:21:49 +00001859 QuantumScale*distortion);
cristy3ed852e2009-09-05 21:47:34 +00001860 (*fail)++;
1861 continue;
1862 }
glennrp4084cda2012-12-11 14:13:35 +00001863#ifdef MagickCountTempFiles
1864 (void) FormatLocaleFile(stdout,"... pass, ");
1865 (void) fflush(stdout);
1866 SystemCommand[0]='\0';
cristy77b33ba2013-03-28 13:23:13 +00001867 (void) strncat(SystemCommand,"echo `ls ",9);
1868 (void) strncat(SystemCommand,path,MaxTextExtent-31);
1869 (void) strncat(SystemCommand,"* | wc -w` tmp files.",20);
1870 (void) system(SystemCommand);
glennrp4084cda2012-12-11 14:13:35 +00001871 (void) fflush(stdout);
1872#else
1873 (void) FormatLocaleFile(stdout,"... pass\n");
1874#endif
cristy3ed852e2009-09-05 21:47:34 +00001875 }
1876 }
cristyb51dff52011-05-19 16:55:47 +00001877 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00001878 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1879 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001880 return(test);
1881}
1882
1883/*
1884%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1885% %
1886% %
1887% %
1888% 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 %
1889% %
1890% %
1891% %
1892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1893%
1894% ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk
1895% and returns the number of validation tests that passed and failed.
1896%
1897% The format of the ValidateImageFormatsOnDisk method is:
1898%
cristybb503372010-05-27 20:51:26 +00001899% size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001900% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001901% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001902%
1903% A description of each parameter follows:
1904%
1905% o image_info: the image info.
1906%
1907% o reference_filename: the reference image filename.
1908%
1909% o output_filename: the output image filename.
1910%
1911% o fail: return the number of validation tests that pass.
1912%
1913% o exception: return any errors or warnings in this structure.
1914%
1915*/
cristybb503372010-05-27 20:51:26 +00001916static size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00001917 const char *reference_filename,const char *output_filename,size_t *fail,
1918 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001919{
1920 char
1921 size[MaxTextExtent];
1922
1923 const MagickInfo
1924 *magick_info;
1925
1926 double
1927 distortion,
1928 fuzz;
1929
1930 Image
1931 *difference_image,
1932 *reference_image,
1933 *reconstruct_image;
1934
1935 MagickBooleanType
1936 status;
1937
cristybb503372010-05-27 20:51:26 +00001938 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001939 i,
1940 j;
1941
cristybb503372010-05-27 20:51:26 +00001942 size_t
cristy3ed852e2009-09-05 21:47:34 +00001943 test;
1944
1945 test=0;
cristyb51dff52011-05-19 16:55:47 +00001946 (void) FormatLocaleFile(stdout,"validate image formats on disk:\n");
cristy3ed852e2009-09-05 21:47:34 +00001947 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
1948 {
1949 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
1950 if ((magick_info == (const MagickInfo *) NULL) ||
1951 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
1952 (magick_info->encoder == (EncodeImageHandler *) NULL))
1953 continue;
cristy5f1c1ff2010-12-23 21:38:06 +00001954 for (j=0; reference_types[j].type != UndefinedType; j++)
cristy3ed852e2009-09-05 21:47:34 +00001955 {
1956 /*
1957 Generate reference image.
1958 */
1959 CatchException(exception);
cristy1e604812011-05-19 18:07:50 +00001960 (void) FormatLocaleFile(stdout," test %.20g: %s/%s/%s/%.20g-bits",
1961 (double) (test++),reference_formats[i].magick,CommandOptionToMnemonic(
cristy7998e5f2009-10-08 02:45:33 +00001962 MagickCompressOptions,reference_formats[i].compression),
cristy042ee782011-04-22 18:48:30 +00001963 CommandOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
cristy75a26232010-06-03 17:15:02 +00001964 (double) reference_types[j].depth);
cristy3ed852e2009-09-05 21:47:34 +00001965 (void) CopyMagickString(image_info->filename,reference_filename,
1966 MaxTextExtent);
1967 reference_image=ReadImage(image_info,exception);
1968 if (reference_image == (Image *) NULL)
1969 {
cristy1e604812011-05-19 18:07:50 +00001970 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1971 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001972 (*fail)++;
1973 continue;
1974 }
1975 /*
1976 Write reference image.
1977 */
cristyb51dff52011-05-19 16:55:47 +00001978 (void) FormatLocaleString(size,MaxTextExtent,"%.20gx%.20g",
cristy75a26232010-06-03 17:15:02 +00001979 (double) reference_image->columns,(double) reference_image->rows);
cristy3ed852e2009-09-05 21:47:34 +00001980 (void) CloneString(&image_info->size,size);
1981 image_info->depth=reference_types[j].depth;
cristyb51dff52011-05-19 16:55:47 +00001982 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00001983 reference_formats[i].magick,output_filename);
cristy018f07f2011-09-04 21:15:19 +00001984 status=SetImageType(reference_image,reference_types[j].type,exception);
cristy3ed852e2009-09-05 21:47:34 +00001985 if (status == MagickFalse)
1986 {
cristy1e604812011-05-19 18:07:50 +00001987 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1988 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001989 (*fail)++;
1990 reference_image=DestroyImage(reference_image);
1991 continue;
1992 }
cristy8a11cb12011-10-19 23:53:34 +00001993 status=SetImageDepth(reference_image,reference_types[j].depth,exception);
cristy3ed852e2009-09-05 21:47:34 +00001994 if (status == MagickFalse)
1995 {
cristy1e604812011-05-19 18:07:50 +00001996 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
1997 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001998 (*fail)++;
1999 reference_image=DestroyImage(reference_image);
2000 continue;
2001 }
cristy7998e5f2009-10-08 02:45:33 +00002002 reference_image->compression=reference_formats[i].compression;
cristy6f9e0d32011-08-28 16:32:09 +00002003 status=WriteImage(image_info,reference_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002004 reference_image=DestroyImage(reference_image);
2005 if (status == MagickFalse)
2006 {
cristy1e604812011-05-19 18:07:50 +00002007 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2008 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002009 (*fail)++;
2010 continue;
2011 }
2012 /*
2013 Read reference image.
2014 */
cristyb51dff52011-05-19 16:55:47 +00002015 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00002016 reference_formats[i].magick,output_filename);
2017 reference_image=ReadImage(image_info,exception);
2018 if (reference_image == (Image *) NULL)
2019 {
cristy1e604812011-05-19 18:07:50 +00002020 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2021 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002022 (*fail)++;
2023 continue;
2024 }
2025 /*
2026 Write reference image.
2027 */
cristyb51dff52011-05-19 16:55:47 +00002028 (void) FormatLocaleString(reference_image->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00002029 reference_formats[i].magick,output_filename);
2030 reference_image->depth=reference_types[j].depth;
cristy7998e5f2009-10-08 02:45:33 +00002031 reference_image->compression=reference_formats[i].compression;
cristy6f9e0d32011-08-28 16:32:09 +00002032 status=WriteImage(image_info,reference_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002033 if (status == MagickFalse)
2034 {
cristy1e604812011-05-19 18:07:50 +00002035 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2036 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002037 (*fail)++;
2038 reference_image=DestroyImage(reference_image);
2039 continue;
2040 }
2041 /*
2042 Read reconstruct image.
2043 */
cristyb51dff52011-05-19 16:55:47 +00002044 (void) FormatLocaleString(image_info->filename,MaxTextExtent,"%s:%s",
cristy3ed852e2009-09-05 21:47:34 +00002045 reference_formats[i].magick,output_filename);
2046 reconstruct_image=ReadImage(image_info,exception);
2047 if (reconstruct_image == (Image *) NULL)
2048 {
cristy1e604812011-05-19 18:07:50 +00002049 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2050 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002051 (*fail)++;
2052 reference_image=DestroyImage(reference_image);
2053 continue;
2054 }
2055 /*
2056 Compare reference to reconstruct image.
2057 */
cristy93540ab2013-03-30 19:59:41 +00002058 fuzz=0.003; /* grayscale */
cristy3ed852e2009-09-05 21:47:34 +00002059 if (reference_formats[i].fuzz != 0.0)
2060 fuzz=reference_formats[i].fuzz;
cristy8a9106f2011-07-05 14:39:26 +00002061 difference_image=CompareImages(reference_image,reconstruct_image,
cristy864c6a82012-06-19 16:45:22 +00002062 RootMeanSquaredErrorMetric,&distortion,exception);
cristy3ed852e2009-09-05 21:47:34 +00002063 reconstruct_image=DestroyImage(reconstruct_image);
2064 reference_image=DestroyImage(reference_image);
2065 if (difference_image == (Image *) NULL)
2066 {
cristy1e604812011-05-19 18:07:50 +00002067 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2068 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002069 (*fail)++;
2070 continue;
2071 }
2072 difference_image=DestroyImage(difference_image);
cristy14154222012-06-15 23:21:49 +00002073 if ((QuantumScale*distortion) > fuzz)
cristy3ed852e2009-09-05 21:47:34 +00002074 {
cristyb51dff52011-05-19 16:55:47 +00002075 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
cristy14154222012-06-15 23:21:49 +00002076 QuantumScale*distortion);
cristy3ed852e2009-09-05 21:47:34 +00002077 (*fail)++;
2078 continue;
2079 }
cristyb51dff52011-05-19 16:55:47 +00002080 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00002081 }
2082 }
cristyb51dff52011-05-19 16:55:47 +00002083 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00002084 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
2085 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00002086 return(test);
2087}
2088
2089/*
2090%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2091% %
2092% %
2093% %
2094% 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 %
2095% %
2096% %
2097% %
2098%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2099%
2100% ValidateImportExportPixels() validates the pixel import and export methods.
2101% It returns the number of validation tests that passed and failed.
2102%
2103% The format of the ValidateImportExportPixels method is:
2104%
cristybb503372010-05-27 20:51:26 +00002105% size_t ValidateImportExportPixels(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00002106% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00002107% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002108%
2109% A description of each parameter follows:
2110%
2111% o image_info: the image info.
2112%
2113% o reference_filename: the reference image filename.
2114%
2115% o output_filename: the output image filename.
2116%
2117% o fail: return the number of validation tests that pass.
2118%
2119% o exception: return any errors or warnings in this structure.
2120%
2121*/
cristybb503372010-05-27 20:51:26 +00002122static size_t ValidateImportExportPixels(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00002123 const char *reference_filename,const char *output_filename,size_t *fail,
2124 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002125{
2126 double
2127 distortion;
2128
2129 Image
2130 *difference_image,
2131 *reference_image,
2132 *reconstruct_image;
2133
2134 MagickBooleanType
2135 status;
2136
cristybb503372010-05-27 20:51:26 +00002137 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002138 i,
2139 j;
2140
2141 size_t
2142 length;
2143
2144 unsigned char
2145 *pixels;
2146
cristybb503372010-05-27 20:51:26 +00002147 size_t
cristy3ed852e2009-09-05 21:47:34 +00002148 test;
2149
2150 (void) output_filename;
2151 test=0;
cristy1e604812011-05-19 18:07:50 +00002152 (void) FormatLocaleFile(stdout,
2153 "validate the import and export of image pixels:\n");
cristy3ed852e2009-09-05 21:47:34 +00002154 for (i=0; reference_map[i] != (char *) NULL; i++)
2155 {
2156 for (j=0; reference_storage[j].type != UndefinedPixel; j++)
2157 {
2158 /*
2159 Generate reference image.
2160 */
2161 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00002162 (void) FormatLocaleFile(stdout," test %.20g: %s/%s",(double) (test++),
cristy042ee782011-04-22 18:48:30 +00002163 reference_map[i],CommandOptionToMnemonic(MagickStorageOptions,
cristy3ed852e2009-09-05 21:47:34 +00002164 reference_storage[j].type));
2165 (void) CopyMagickString(image_info->filename,reference_filename,
2166 MaxTextExtent);
2167 reference_image=ReadImage(image_info,exception);
2168 if (reference_image == (Image *) NULL)
2169 {
cristy1e604812011-05-19 18:07:50 +00002170 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2171 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002172 (*fail)++;
2173 continue;
2174 }
2175 if (LocaleNCompare(reference_map[i],"cmy",3) == 0)
cristy2c404222012-06-10 15:36:30 +00002176 (void) SetImageColorspace(reference_image,CMYKColorspace,exception);
cristy3ed852e2009-09-05 21:47:34 +00002177 length=strlen(reference_map[i])*reference_image->columns*
2178 reference_image->rows*reference_storage[j].quantum;
2179 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
2180 if (pixels == (unsigned char *) NULL)
2181 {
cristy1e604812011-05-19 18:07:50 +00002182 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2183 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002184 (*fail)++;
2185 reference_image=DestroyImage(reference_image);
2186 continue;
2187 }
2188 (void) ResetMagickMemory(pixels,0,length*sizeof(*pixels));
2189 status=ExportImagePixels(reference_image,0,0,reference_image->columns,
2190 reference_image->rows,reference_map[i],reference_storage[j].type,pixels,
2191 exception);
2192 if (status == MagickFalse)
2193 {
cristy1e604812011-05-19 18:07:50 +00002194 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2195 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002196 (*fail)++;
2197 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2198 reference_image=DestroyImage(reference_image);
2199 continue;
2200 }
cristyd55c9352011-10-20 15:29:22 +00002201 (void) SetImageBackgroundColor(reference_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002202 status=ImportImagePixels(reference_image,0,0,reference_image->columns,
2203 reference_image->rows,reference_map[i],reference_storage[j].type,
cristy018f07f2011-09-04 21:15:19 +00002204 pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00002205 if (status == MagickFalse)
2206 {
cristy1e604812011-05-19 18:07:50 +00002207 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2208 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002209 (*fail)++;
2210 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2211 reference_image=DestroyImage(reference_image);
2212 continue;
2213 }
2214 /*
2215 Read reconstruct image.
2216 */
cristy9950d572011-10-01 18:22:35 +00002217 reconstruct_image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +00002218 (void) SetImageExtent(reconstruct_image,reference_image->columns,
cristy655a8d12011-08-05 19:24:28 +00002219 reference_image->rows,exception);
2220 (void) SetImageColorspace(reconstruct_image,reference_image->colorspace,
2221 exception);
cristyd55c9352011-10-20 15:29:22 +00002222 (void) SetImageBackgroundColor(reconstruct_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002223 status=ImportImagePixels(reconstruct_image,0,0,reconstruct_image->columns,
2224 reconstruct_image->rows,reference_map[i],reference_storage[j].type,
cristy018f07f2011-09-04 21:15:19 +00002225 pixels,exception);
cristy3ed852e2009-09-05 21:47:34 +00002226 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
2227 if (status == MagickFalse)
2228 {
cristy1e604812011-05-19 18:07:50 +00002229 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2230 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002231 (*fail)++;
2232 reference_image=DestroyImage(reference_image);
2233 continue;
2234 }
2235 /*
2236 Compare reference to reconstruct image.
2237 */
cristy8a9106f2011-07-05 14:39:26 +00002238 difference_image=CompareImages(reference_image,reconstruct_image,
cristy864c6a82012-06-19 16:45:22 +00002239 RootMeanSquaredErrorMetric,&distortion,exception);
cristy3ed852e2009-09-05 21:47:34 +00002240 reconstruct_image=DestroyImage(reconstruct_image);
2241 reference_image=DestroyImage(reference_image);
2242 if (difference_image == (Image *) NULL)
2243 {
cristy1e604812011-05-19 18:07:50 +00002244 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2245 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002246 (*fail)++;
2247 continue;
2248 }
2249 difference_image=DestroyImage(difference_image);
cristy14154222012-06-15 23:21:49 +00002250 if ((QuantumScale*distortion) > 0.0)
cristy3ed852e2009-09-05 21:47:34 +00002251 {
cristyb51dff52011-05-19 16:55:47 +00002252 (void) FormatLocaleFile(stdout,"... fail (with distortion %g).\n",
cristy14154222012-06-15 23:21:49 +00002253 QuantumScale*distortion);
cristy3ed852e2009-09-05 21:47:34 +00002254 (*fail)++;
2255 continue;
2256 }
cristyb51dff52011-05-19 16:55:47 +00002257 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00002258 }
2259 }
cristyb51dff52011-05-19 16:55:47 +00002260 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00002261 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
2262 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00002263 return(test);
2264}
2265
2266/*
2267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2268% %
2269% %
2270% %
2271% V a l i d a t e M o n t a g e C o m m a n d %
2272% %
2273% %
2274% %
2275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2276%
2277% ValidateMontageCommand() validates the ImageMagick montage command line
2278% program and returns the number of validation tests that passed and failed.
2279%
2280% The format of the ValidateMontageCommand method is:
2281%
cristybb503372010-05-27 20:51:26 +00002282% size_t ValidateMontageCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00002283% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00002284% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002285%
2286% A description of each parameter follows:
2287%
2288% o image_info: the image info.
2289%
2290% o reference_filename: the reference image filename.
2291%
2292% o output_filename: the output image filename.
2293%
2294% o fail: return the number of validation tests that pass.
2295%
2296% o exception: return any errors or warnings in this structure.
2297%
2298*/
cristybb503372010-05-27 20:51:26 +00002299static size_t ValidateMontageCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00002300 const char *reference_filename,const char *output_filename,size_t *fail,
2301 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002302{
2303 char
2304 **arguments,
2305 command[MaxTextExtent];
2306
2307 int
2308 number_arguments;
2309
2310 MagickBooleanType
2311 status;
2312
cristybb503372010-05-27 20:51:26 +00002313 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002314 i,
2315 j;
2316
cristybb503372010-05-27 20:51:26 +00002317 size_t
cristy3ed852e2009-09-05 21:47:34 +00002318 test;
2319
2320 test=0;
cristyb51dff52011-05-19 16:55:47 +00002321 (void) FormatLocaleFile(stdout,"validate montage command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00002322 for (i=0; montage_options[i] != (char *) NULL; i++)
2323 {
2324 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00002325 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00002326 montage_options[i]);
cristyb51dff52011-05-19 16:55:47 +00002327 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s %s",
cristy3ed852e2009-09-05 21:47:34 +00002328 reference_filename,montage_options[i],reference_filename,
2329 output_filename);
2330 arguments=StringToArgv(command,&number_arguments);
2331 if (arguments == (char **) NULL)
2332 {
cristy1e604812011-05-19 18:07:50 +00002333 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2334 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002335 (*fail)++;
2336 continue;
2337 }
2338 status=MontageImageCommand(image_info,number_arguments,arguments,
2339 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00002340 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00002341 arguments[j]=DestroyString(arguments[j]);
2342 arguments=(char **) RelinquishMagickMemory(arguments);
2343 if (status != MagickFalse)
2344 {
cristy1e604812011-05-19 18:07:50 +00002345 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2346 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002347 (*fail)++;
2348 continue;
2349 }
cristyb51dff52011-05-19 16:55:47 +00002350 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00002351 }
cristyb51dff52011-05-19 16:55:47 +00002352 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00002353 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
2354 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00002355 return(test);
2356}
2357
2358/*
2359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2360% %
2361% %
2362% %
2363% V a l i d a t e S t r e a m C o m m a n d %
2364% %
2365% %
2366% %
2367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2368%
2369% ValidateStreamCommand() validates the ImageMagick stream command line
2370% program and returns the number of validation tests that passed and failed.
2371%
2372% The format of the ValidateStreamCommand method is:
2373%
cristybb503372010-05-27 20:51:26 +00002374% size_t ValidateStreamCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00002375% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00002376% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002377%
2378% A description of each parameter follows:
2379%
2380% o image_info: the image info.
2381%
2382% o reference_filename: the reference image filename.
2383%
2384% o output_filename: the output image filename.
2385%
2386% o fail: return the number of validation tests that pass.
2387%
2388% o exception: return any errors or warnings in this structure.
2389%
2390*/
cristybb503372010-05-27 20:51:26 +00002391static size_t ValidateStreamCommand(ImageInfo *image_info,
cristy0d772ed2012-11-10 14:34:50 +00002392 const char *reference_filename,const char *output_filename,size_t *fail,
2393 ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00002394{
2395 char
2396 **arguments,
2397 command[MaxTextExtent];
2398
2399 int
2400 number_arguments;
2401
2402 MagickBooleanType
2403 status;
2404
cristybb503372010-05-27 20:51:26 +00002405 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002406 i,
2407 j;
2408
cristybb503372010-05-27 20:51:26 +00002409 size_t
cristy3ed852e2009-09-05 21:47:34 +00002410 test;
2411
2412 test=0;
cristyb51dff52011-05-19 16:55:47 +00002413 (void) FormatLocaleFile(stdout,"validate stream command line program:\n");
cristy3ed852e2009-09-05 21:47:34 +00002414 for (i=0; stream_options[i] != (char *) NULL; i++)
2415 {
2416 CatchException(exception);
cristyb51dff52011-05-19 16:55:47 +00002417 (void) FormatLocaleFile(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00002418 stream_options[i]);
cristyb51dff52011-05-19 16:55:47 +00002419 (void) FormatLocaleString(command,MaxTextExtent,"%s %s %s",
cristy3ed852e2009-09-05 21:47:34 +00002420 stream_options[i],reference_filename,output_filename);
2421 arguments=StringToArgv(command,&number_arguments);
2422 if (arguments == (char **) NULL)
2423 {
cristy1e604812011-05-19 18:07:50 +00002424 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2425 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002426 (*fail)++;
2427 continue;
2428 }
2429 status=StreamImageCommand(image_info,number_arguments,arguments,
2430 (char **) NULL,exception);
cristye42f6582012-02-11 17:59:50 +00002431 for (j=0; j < (ssize_t) number_arguments; j++)
cristy3ed852e2009-09-05 21:47:34 +00002432 arguments[j]=DestroyString(arguments[j]);
2433 arguments=(char **) RelinquishMagickMemory(arguments);
2434 if (status != MagickFalse)
2435 {
cristy1e604812011-05-19 18:07:50 +00002436 (void) FormatLocaleFile(stdout,"... fail @ %s/%s/%lu.\n",
2437 GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00002438 (*fail)++;
2439 continue;
2440 }
cristyb51dff52011-05-19 16:55:47 +00002441 (void) FormatLocaleFile(stdout,"... pass.\n");
cristy3ed852e2009-09-05 21:47:34 +00002442 }
cristyb51dff52011-05-19 16:55:47 +00002443 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00002444 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
2445 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00002446 return(test);
2447}
2448
2449/*
2450%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2451% %
2452% %
2453% %
2454% M a i n %
2455% %
2456% %
2457% %
2458%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2459%
2460%
2461*/
2462
2463static MagickBooleanType ValidateUsage(void)
2464{
2465 const char
2466 **p;
2467
2468 static const char
2469 *miscellaneous[]=
2470 {
2471 "-debug events display copious debugging information",
2472 "-help print program options",
2473 "-log format format of debugging information",
2474 "-validate type validation type",
2475 "-version print version information",
2476 (char *) NULL
2477 },
2478 *settings[]=
2479 {
2480 "-regard-warnings pay attention to warning messages",
2481 "-verbose print detailed information about the image",
2482 (char *) NULL
2483 };
2484
cristybb503372010-05-27 20:51:26 +00002485 (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
cristy3ed852e2009-09-05 21:47:34 +00002486 (void) printf("Copyright: %s\n\n",GetMagickCopyright());
cristyb28d6472009-10-17 20:13:35 +00002487 (void) printf("Features: %s\n",GetMagickFeatures());
cristy3ed852e2009-09-05 21:47:34 +00002488 (void) printf("Usage: %s [options ...] reference-file\n",GetClientName());
2489 (void) printf("\nValidate Settings:\n");
2490 for (p=settings; *p != (char *) NULL; p++)
2491 (void) printf(" %s\n",*p);
2492 (void) printf("\nMiscellaneous Options:\n");
2493 for (p=miscellaneous; *p != (char *) NULL; p++)
2494 (void) printf(" %s\n",*p);
2495 return(MagickTrue);
2496}
2497
2498int main(int argc,char **argv)
2499{
2500#define DestroyValidate() \
2501{ \
cristy3ed852e2009-09-05 21:47:34 +00002502 image_info=DestroyImageInfo(image_info); \
2503 exception=DestroyExceptionInfo(exception); \
2504}
2505#define ThrowValidateException(asperity,tag,option) \
2506{ \
2507 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
2508 option); \
2509 CatchException(exception); \
2510 DestroyValidate(); \
2511 return(MagickFalse); \
2512}
2513
2514 char
2515 output_filename[MaxTextExtent],
2516 reference_filename[MaxTextExtent],
2517 *option;
2518
2519 double
2520 elapsed_time,
2521 user_time;
2522
2523 ExceptionInfo
2524 *exception;
2525
2526 Image
2527 *reference_image;
2528
2529 ImageInfo
2530 *image_info;
2531
2532 MagickBooleanType
2533 regard_warnings,
2534 status;
2535
cristy9cafe592012-11-17 21:17:59 +00002536 MagickSizeType
2537 memory_resource,
2538 map_resource;
2539
cristybb503372010-05-27 20:51:26 +00002540 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002541 i;
2542
2543 TimerInfo
2544 *timer;
2545
cristybb503372010-05-27 20:51:26 +00002546 size_t
cristy3ed852e2009-09-05 21:47:34 +00002547 fail,
2548 iterations,
2549 tests;
2550
2551 ValidateType
2552 type;
2553
2554 /*
2555 Validate the ImageMagick image processing suite.
2556 */
cristyb4d552c2012-12-13 15:42:17 +00002557 MagickCoreGenesis(*argv,MagickTrue);
cristyef2fdc62012-12-12 11:16:48 +00002558 (void) setlocale(LC_ALL,"");
2559 (void) setlocale(LC_NUMERIC,"C");
cristy3ed852e2009-09-05 21:47:34 +00002560 iterations=1;
2561 status=MagickFalse;
2562 type=AllValidate;
2563 regard_warnings=MagickFalse;
cristyd8862902011-02-20 21:12:27 +00002564 (void) regard_warnings;
cristy3ed852e2009-09-05 21:47:34 +00002565 exception=AcquireExceptionInfo();
2566 image_info=AcquireImageInfo();
2567 (void) CopyMagickString(image_info->filename,ReferenceFilename,MaxTextExtent);
cristybb503372010-05-27 20:51:26 +00002568 for (i=1; i < (ssize_t) argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00002569 {
2570 option=argv[i];
cristy042ee782011-04-22 18:48:30 +00002571 if (IsCommandOption(option) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +00002572 {
2573 (void) CopyMagickString(image_info->filename,option,MaxTextExtent);
2574 continue;
2575 }
2576 switch (*(option+1))
2577 {
2578 case 'b':
2579 {
2580 if (LocaleCompare("bench",option+1) == 0)
2581 {
cristye27293e2009-12-18 02:53:20 +00002582 iterations=StringToUnsignedLong(argv[++i]);
cristy3ed852e2009-09-05 21:47:34 +00002583 break;
2584 }
2585 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2586 }
2587 case 'd':
2588 {
2589 if (LocaleCompare("debug",option+1) == 0)
2590 {
2591 (void) SetLogEventMask(argv[++i]);
2592 break;
2593 }
2594 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2595 }
2596 case 'h':
2597 {
2598 if (LocaleCompare("help",option+1) == 0)
2599 {
2600 (void) ValidateUsage();
2601 return(0);
2602 }
2603 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2604 }
2605 case 'l':
2606 {
2607 if (LocaleCompare("log",option+1) == 0)
2608 {
2609 if (*option != '+')
2610 (void) SetLogFormat(argv[i+1]);
2611 break;
2612 }
2613 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2614 }
2615 case 'r':
2616 {
2617 if (LocaleCompare("regard-warnings",option+1) == 0)
2618 {
2619 regard_warnings=MagickTrue;
2620 break;
2621 }
2622 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2623 }
2624 case 'v':
2625 {
2626 if (LocaleCompare("validate",option+1) == 0)
2627 {
cristybb503372010-05-27 20:51:26 +00002628 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00002629 validate;
2630
2631 if (*option == '+')
2632 break;
2633 i++;
cristybb503372010-05-27 20:51:26 +00002634 if (i == (ssize_t) argc)
cristy3ed852e2009-09-05 21:47:34 +00002635 ThrowValidateException(OptionError,"MissingArgument",option);
cristy042ee782011-04-22 18:48:30 +00002636 validate=ParseCommandOption(MagickValidateOptions,MagickFalse,
cristy3ed852e2009-09-05 21:47:34 +00002637 argv[i]);
2638 if (validate < 0)
2639 ThrowValidateException(OptionError,"UnrecognizedValidateType",
2640 argv[i]);
2641 type=(ValidateType) validate;
2642 break;
2643 }
2644 if ((LocaleCompare("version",option+1) == 0) ||
2645 (LocaleCompare("-version",option+1) == 0))
2646 {
cristyb51dff52011-05-19 16:55:47 +00002647 (void) FormatLocaleFile(stdout,"Version: %s\n",
cristybb503372010-05-27 20:51:26 +00002648 GetMagickVersion((size_t *) NULL));
cristy1e604812011-05-19 18:07:50 +00002649 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n",
2650 GetMagickCopyright());
2651 (void) FormatLocaleFile(stdout,"Features: %s\n\n",
2652 GetMagickFeatures());
cristy3ed852e2009-09-05 21:47:34 +00002653 return(0);
2654 }
2655 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2656 }
2657 default:
2658 ThrowValidateException(OptionError,"UnrecognizedOption",option)
2659 }
2660 }
cristy205e21f2009-09-28 19:01:46 +00002661 timer=(TimerInfo *) NULL;
cristy8b76e552009-09-28 18:20:20 +00002662 if (iterations > 1)
2663 timer=AcquireTimerInfo();
cristy3ed852e2009-09-05 21:47:34 +00002664 reference_image=ReadImage(image_info,exception);
2665 tests=0;
2666 fail=0;
2667 if (reference_image == (Image *) NULL)
2668 fail++;
2669 else
2670 {
2671 if (LocaleCompare(image_info->filename,ReferenceFilename) == 0)
2672 (void) CopyMagickString(reference_image->magick,ReferenceImageFormat,
2673 MaxTextExtent);
2674 (void) AcquireUniqueFilename(reference_filename);
2675 (void) AcquireUniqueFilename(output_filename);
2676 (void) CopyMagickString(reference_image->filename,reference_filename,
2677 MaxTextExtent);
cristy6f9e0d32011-08-28 16:32:09 +00002678 status=WriteImage(image_info,reference_image,exception);
cristy3ed852e2009-09-05 21:47:34 +00002679 reference_image=DestroyImage(reference_image);
2680 if (status == MagickFalse)
2681 fail++;
2682 else
2683 {
cristyb51dff52011-05-19 16:55:47 +00002684 (void) FormatLocaleFile(stdout,"Version: %s\n",
cristybb503372010-05-27 20:51:26 +00002685 GetMagickVersion((size_t *) NULL));
cristyb51dff52011-05-19 16:55:47 +00002686 (void) FormatLocaleFile(stdout,"Copyright: %s\n\n",
cristy3ed852e2009-09-05 21:47:34 +00002687 GetMagickCopyright());
cristy1e604812011-05-19 18:07:50 +00002688 (void) FormatLocaleFile(stdout,
2689 "ImageMagick Validation Suite (%s)\n\n",CommandOptionToMnemonic(
2690 MagickValidateOptions,(ssize_t) type));
cristy80e870e2013-05-07 12:23:02 +00002691 if ((type & ColorspaceValidate) != 0)
cristy572e0972013-05-07 12:51:28 +00002692 tests+=ValidateColorspaces(image_info,&fail,exception);
cristy3ed852e2009-09-05 21:47:34 +00002693 if ((type & CompareValidate) != 0)
2694 tests+=ValidateCompareCommand(image_info,reference_filename,
2695 output_filename,&fail,exception);
2696 if ((type & CompositeValidate) != 0)
2697 tests+=ValidateCompositeCommand(image_info,reference_filename,
2698 output_filename,&fail,exception);
2699 if ((type & ConvertValidate) != 0)
2700 tests+=ValidateConvertCommand(image_info,reference_filename,
2701 output_filename,&fail,exception);
cristy247eebde2013-06-13 01:01:43 +00002702 if ((type & FormatsDiskValidate) != 0)
cristyf044a4d2012-11-17 21:10:20 +00002703 {
cristy9cafe592012-11-17 21:17:59 +00002704 memory_resource=SetMagickResourceLimit(MemoryResource,0);
cristy247eebde2013-06-13 01:01:43 +00002705 map_resource=SetMagickResourceLimit(MapResource,0);
2706 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] ");
cristyf044a4d2012-11-17 21:10:20 +00002707 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
2708 output_filename,&fail,exception);
2709 (void) FormatLocaleFile(stdout,"[pixel-cache: disk] ");
cristy247eebde2013-06-13 01:01:43 +00002710 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
cristyf044a4d2012-11-17 21:10:20 +00002711 output_filename,&fail,exception);
cristy9cafe592012-11-17 21:17:59 +00002712 (void) SetMagickResourceLimit(MemoryResource,memory_resource);
2713 (void) SetMagickResourceLimit(MapResource,map_resource);
cristyf044a4d2012-11-17 21:10:20 +00002714 }
cristy247eebde2013-06-13 01:01:43 +00002715 if ((type & FormatsMapValidate) != 0)
cristybda201a2012-11-08 16:44:00 +00002716 {
cristy247eebde2013-06-13 01:01:43 +00002717 memory_resource=SetMagickResourceLimit(MemoryResource,0);
2718 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] ");
2719 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
cristybda201a2012-11-08 16:44:00 +00002720 output_filename,&fail,exception);
cristy34c290f2012-11-09 00:44:12 +00002721 (void) FormatLocaleFile(stdout,"[pixel-cache: memory-mapped] ");
cristybda201a2012-11-08 16:44:00 +00002722 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
2723 output_filename,&fail,exception);
cristy9cafe592012-11-17 21:17:59 +00002724 (void) SetMagickResourceLimit(MemoryResource,memory_resource);
cristy247eebde2013-06-13 01:01:43 +00002725 }
2726 if ((type & FormatsMemoryValidate) != 0)
2727 {
2728 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] ");
2729 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
2730 output_filename,&fail,exception);
2731 (void) FormatLocaleFile(stdout,"[pixel-cache: memory] ");
2732 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
2733 output_filename,&fail,exception);
cristybda201a2012-11-08 16:44:00 +00002734 }
cristy3ed852e2009-09-05 21:47:34 +00002735 if ((type & IdentifyValidate) != 0)
2736 tests+=ValidateIdentifyCommand(image_info,reference_filename,
2737 output_filename,&fail,exception);
2738 if ((type & ImportExportValidate) != 0)
2739 tests+=ValidateImportExportPixels(image_info,reference_filename,
2740 output_filename,&fail,exception);
2741 if ((type & MontageValidate) != 0)
2742 tests+=ValidateMontageCommand(image_info,reference_filename,
2743 output_filename,&fail,exception);
2744 if ((type & StreamValidate) != 0)
2745 tests+=ValidateStreamCommand(image_info,reference_filename,
2746 output_filename,&fail,exception);
cristyb51dff52011-05-19 16:55:47 +00002747 (void) FormatLocaleFile(stdout,
cristy75a26232010-06-03 17:15:02 +00002748 "validation suite: %.20g tests; %.20g passed; %.20g failed.\n",
2749 (double) tests,(double) (tests-fail),(double) fail);
cristy3ed852e2009-09-05 21:47:34 +00002750 }
2751 (void) RelinquishUniqueFileResource(output_filename);
2752 (void) RelinquishUniqueFileResource(reference_filename);
2753 }
2754 if (exception->severity != UndefinedException)
2755 CatchException(exception);
2756 if (iterations > 1)
2757 {
2758 elapsed_time=GetElapsedTime(timer);
2759 user_time=GetUserTime(timer);
cristyb51dff52011-05-19 16:55:47 +00002760 (void) FormatLocaleFile(stderr,
cristy75a26232010-06-03 17:15:02 +00002761 "Performance: %.20gi %gips %0.3fu %ld:%02ld.%03ld\n",(double)
cristy6aa47ad2010-05-28 19:32:32 +00002762 iterations,1.0*iterations/elapsed_time,user_time,(long)
2763 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)),
2764 (long) (1000.0*(elapsed_time-floor(elapsed_time))));
cristy8b76e552009-09-28 18:20:20 +00002765 timer=DestroyTimerInfo(timer);
cristy3ed852e2009-09-05 21:47:34 +00002766 }
2767 DestroyValidate();
2768 MagickCoreTerminus();
2769 return(fail == 0 ? 0 : 1);
2770}