blob: 04fd84244e90fa84f047182f212cc17137778d10 [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% %
cristy16af1cb2009-12-11 21:38:29 +000021% Copyright 1999-2010 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>
48#include "wand/MagickWand.h"
cristya0b81c32010-01-22 02:54:33 +000049#include "magick/string-private.h"
cristy3ed852e2009-09-05 21:47:34 +000050#include "validate.h"
51
52/*
53%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
54% %
55% %
56% %
57% V a l i d a t e C o m p a r e C o m m a n d %
58% %
59% %
60% %
61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62%
63% ValidateCompareCommand() validates the ImageMagick compare command line
64% program and returns the number of validation tests that passed and failed.
65%
66% The format of the ValidateCompareCommand method is:
67%
cristybb503372010-05-27 20:51:26 +000068% size_t ValidateCompareCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +000069% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +000070% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +000071%
72% A description of each parameter follows:
73%
74% o image_info: the image info.
75%
76% o reference_filename: the reference image filename.
77%
78% o output_filename: the output image filename.
79%
80% o fail: return the number of validation tests that pass.
81%
82% o exception: return any errors or warnings in this structure.
83%
84*/
cristybb503372010-05-27 20:51:26 +000085static size_t ValidateCompareCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +000086 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +000087 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +000088{
89 char
90 **arguments,
91 command[MaxTextExtent];
92
93 int
94 number_arguments;
95
96 MagickBooleanType
97 status;
98
cristybb503372010-05-27 20:51:26 +000099 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000100 i,
101 j;
102
cristybb503372010-05-27 20:51:26 +0000103 size_t
cristy3ed852e2009-09-05 21:47:34 +0000104 test;
105
106 test=0;
107 (void) fprintf(stdout,"validate compare command line program:\n");
108 for (i=0; compare_options[i] != (char *) NULL; i++)
109 {
110 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000111 (void) fprintf(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +0000112 compare_options[i]);
cristy3ed852e2009-09-05 21:47:34 +0000113 (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
114 compare_options[i],reference_filename,reference_filename,output_filename);
115 arguments=StringToArgv(command,&number_arguments);
116 if (arguments == (char **) NULL)
117 {
cristy66688e52010-06-03 17:32:17 +0000118 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000119 (*fail)++;
120 continue;
121 }
122 status=CompareImageCommand(image_info,number_arguments,arguments,
123 (char **) NULL,exception);
124 for (j=0; j < number_arguments; j++)
125 arguments[j]=DestroyString(arguments[j]);
126 arguments=(char **) RelinquishMagickMemory(arguments);
127 if (status != MagickFalse)
128 {
cristy66688e52010-06-03 17:32:17 +0000129 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000130 (*fail)++;
131 continue;
132 }
133 (void) fprintf(stdout,"... pass.\n");
134 }
cristy75a26232010-06-03 17:15:02 +0000135 (void) fprintf(stdout,
136 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
137 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000138 return(test);
139}
140
141/*
142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143% %
144% %
145% %
146% V a l i d a t e C o m p o s i t e C o m m a n d %
147% %
148% %
149% %
150%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151%
152% ValidateCompositeCommand() validates the ImageMagick composite command line
153% program and returns the number of validation tests that passed and failed.
154%
155% The format of the ValidateCompositeCommand method is:
156%
cristybb503372010-05-27 20:51:26 +0000157% size_t ValidateCompositeCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000158% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000159% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000160%
161% A description of each parameter follows:
162%
163% o image_info: the image info.
164%
165% o reference_filename: the reference image filename.
166%
167% o output_filename: the output image filename.
168%
169% o fail: return the number of validation tests that pass.
170%
171% o exception: return any errors or warnings in this structure.
172%
173*/
cristybb503372010-05-27 20:51:26 +0000174static size_t ValidateCompositeCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000175 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000176 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000177{
178 char
179 **arguments,
180 command[MaxTextExtent];
181
182 int
183 number_arguments;
184
185 MagickBooleanType
186 status;
187
cristybb503372010-05-27 20:51:26 +0000188 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000189 i,
190 j;
191
cristybb503372010-05-27 20:51:26 +0000192 size_t
cristy3ed852e2009-09-05 21:47:34 +0000193 test;
194
195 test=0;
196 (void) fprintf(stdout,"validate composite command line program:\n");
197 for (i=0; composite_options[i] != (char *) NULL; i++)
198 {
199 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000200 (void) fprintf(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +0000201 composite_options[i]);
cristy3ed852e2009-09-05 21:47:34 +0000202 (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
203 reference_filename,composite_options[i],reference_filename,
204 output_filename);
205 arguments=StringToArgv(command,&number_arguments);
206 if (arguments == (char **) NULL)
207 {
cristy66688e52010-06-03 17:32:17 +0000208 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000209 (*fail)++;
210 continue;
211 }
212 status=CompositeImageCommand(image_info,number_arguments,arguments,
213 (char **) NULL,exception);
214 for (j=0; j < number_arguments; j++)
215 arguments[j]=DestroyString(arguments[j]);
216 arguments=(char **) RelinquishMagickMemory(arguments);
217 if (status != MagickFalse)
218 {
cristy66688e52010-06-03 17:32:17 +0000219 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000220 (*fail)++;
221 continue;
222 }
223 (void) fprintf(stdout,"... pass.\n");
224 }
cristy75a26232010-06-03 17:15:02 +0000225 (void) fprintf(stdout,
226 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
227 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000228 return(test);
229}
230
231/*
232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233% %
234% %
235% %
236% V a l i d a t e C o n v e r t C o m m a n d %
237% %
238% %
239% %
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241%
242% ValidateConvertCommand() validates the ImageMagick convert command line
243% program and returns the number of validation tests that passed and failed.
244%
245% The format of the ValidateConvertCommand method is:
246%
cristybb503372010-05-27 20:51:26 +0000247% size_t ValidateConvertCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000248% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000249% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000250%
251% A description of each parameter follows:
252%
253% o image_info: the image info.
254%
255% o reference_filename: the reference image filename.
256%
257% o output_filename: the output image filename.
258%
259% o fail: return the number of validation tests that pass.
260%
261% o exception: return any errors or warnings in this structure.
262%
263*/
cristybb503372010-05-27 20:51:26 +0000264static size_t ValidateConvertCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000265 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000266 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000267{
268 char
269 **arguments,
270 command[MaxTextExtent];
271
272 int
273 number_arguments;
274
275 MagickBooleanType
276 status;
277
cristybb503372010-05-27 20:51:26 +0000278 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000279 i,
280 j;
281
cristybb503372010-05-27 20:51:26 +0000282 size_t
cristy3ed852e2009-09-05 21:47:34 +0000283 test;
284
285 test=0;
286 (void) fprintf(stdout,"validate convert command line program:\n");
287 for (i=0; convert_options[i] != (char *) NULL; i++)
288 {
289 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000290 (void) fprintf(stdout," test %.20g: %s",(double) test++,
cristy6aa47ad2010-05-28 19:32:32 +0000291 convert_options[i]);
cristy3ed852e2009-09-05 21:47:34 +0000292 (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
293 reference_filename,convert_options[i],reference_filename,output_filename);
294 arguments=StringToArgv(command,&number_arguments);
295 if (arguments == (char **) NULL)
296 {
cristy66688e52010-06-03 17:32:17 +0000297 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000298 (*fail)++;
299 continue;
300 }
301 status=ConvertImageCommand(image_info,number_arguments,arguments,
302 (char **) NULL,exception);
303 for (j=0; j < number_arguments; j++)
304 arguments[j]=DestroyString(arguments[j]);
305 arguments=(char **) RelinquishMagickMemory(arguments);
306 if (status != MagickFalse)
307 {
cristy66688e52010-06-03 17:32:17 +0000308 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000309 (*fail)++;
310 continue;
311 }
312 (void) fprintf(stdout,"... pass.\n");
313 }
cristy75a26232010-06-03 17:15:02 +0000314 (void) fprintf(stdout,
315 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
316 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000317 return(test);
318}
319
320/*
321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
322% %
323% %
324% %
325% V a l i d a t e I d e n t i f y C o m m a n d %
326% %
327% %
328% %
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330%
331% ValidateIdentifyCommand() validates the ImageMagick identify command line
332% program and returns the number of validation tests that passed and failed.
333%
334% The format of the ValidateIdentifyCommand method is:
335%
cristybb503372010-05-27 20:51:26 +0000336% size_t ValidateIdentifyCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000337% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000338% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000339%
340% A description of each parameter follows:
341%
342% o image_info: the image info.
343%
344% o reference_filename: the reference image filename.
345%
346% o output_filename: the output image filename.
347%
348% o fail: return the number of validation tests that pass.
349%
350% o exception: return any errors or warnings in this structure.
351%
352*/
cristybb503372010-05-27 20:51:26 +0000353static size_t ValidateIdentifyCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000354 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000355 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000356{
357 char
358 **arguments,
359 command[MaxTextExtent];
360
361 int
362 number_arguments;
363
364 MagickBooleanType
365 status;
366
cristybb503372010-05-27 20:51:26 +0000367 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000368 i,
369 j;
370
cristybb503372010-05-27 20:51:26 +0000371 size_t
cristy3ed852e2009-09-05 21:47:34 +0000372 test;
373
374 (void) output_filename;
375 test=0;
376 (void) fprintf(stdout,"validate identify command line program:\n");
377 for (i=0; identify_options[i] != (char *) NULL; i++)
378 {
379 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000380 (void) fprintf(stdout," test %.20g: %s",(double) test++,
cristy6aa47ad2010-05-28 19:32:32 +0000381 identify_options[i]);
cristy3ed852e2009-09-05 21:47:34 +0000382 (void) FormatMagickString(command,MaxTextExtent,"%s %s",
383 identify_options[i],reference_filename);
384 arguments=StringToArgv(command,&number_arguments);
385 if (arguments == (char **) NULL)
386 {
cristy66688e52010-06-03 17:32:17 +0000387 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000388 (*fail)++;
389 continue;
390 }
391 status=IdentifyImageCommand(image_info,number_arguments,arguments,
392 (char **) NULL,exception);
393 for (j=0; j < number_arguments; j++)
394 arguments[j]=DestroyString(arguments[j]);
395 arguments=(char **) RelinquishMagickMemory(arguments);
396 if (status != MagickFalse)
397 {
cristy66688e52010-06-03 17:32:17 +0000398 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000399 (*fail)++;
400 continue;
401 }
402 (void) fprintf(stdout,"... pass.\n");
403 }
cristy75a26232010-06-03 17:15:02 +0000404 (void) fprintf(stdout,
405 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
406 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000407 return(test);
408}
409
410/*
411%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412% %
413% %
414% %
415% 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 %
416% %
417% %
418% %
419%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420%
421% ValidateImageFormatsInMemory() validates the ImageMagick image formats in
422% memory and returns the number of validation tests that passed and failed.
423%
424% The format of the ValidateImageFormatsInMemory method is:
425%
cristybb503372010-05-27 20:51:26 +0000426% size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000427% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000428% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000429%
430% A description of each parameter follows:
431%
432% o image_info: the image info.
433%
434% o reference_filename: the reference image filename.
435%
436% o output_filename: the output image filename.
437%
438% o fail: return the number of validation tests that pass.
439%
440% o exception: return any errors or warnings in this structure.
441%
442*/
cristybb503372010-05-27 20:51:26 +0000443static size_t ValidateImageFormatsInMemory(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000444 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000445 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000446{
447 char
448 size[MaxTextExtent];
449
450 const MagickInfo
451 *magick_info;
452
453 double
454 distortion,
455 fuzz;
456
457 Image
458 *difference_image,
459 *reference_image,
460 *reconstruct_image;
461
462 MagickBooleanType
463 status;
464
cristybb503372010-05-27 20:51:26 +0000465 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000466 i,
467 j;
468
469 size_t
470 length;
471
472 unsigned char
473 *blob;
474
cristybb503372010-05-27 20:51:26 +0000475 size_t
cristy3ed852e2009-09-05 21:47:34 +0000476 test;
477
478 test=0;
479 (void) fprintf(stdout,"validate image formats in memory:\n");
480 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
481 {
482 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
483 if ((magick_info == (const MagickInfo *) NULL) ||
484 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
485 (magick_info->encoder == (EncodeImageHandler *) NULL))
486 continue;
487 for (j=0; reference_types[j].type != UndefinedType; j++)
488 {
489 /*
490 Generate reference image.
491 */
492 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000493 (void) fprintf(stdout," test %.20g: %s/%s/%s/%.20g-bits",(double)
494 (test++),reference_formats[i].magick,MagickOptionToMnemonic(
cristy7998e5f2009-10-08 02:45:33 +0000495 MagickCompressOptions,reference_formats[i].compression),
496 MagickOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
cristy75a26232010-06-03 17:15:02 +0000497 (double) reference_types[j].depth);
cristy3ed852e2009-09-05 21:47:34 +0000498 (void) CopyMagickString(image_info->filename,reference_filename,
499 MaxTextExtent);
500 reference_image=ReadImage(image_info,exception);
501 if (reference_image == (Image *) NULL)
502 {
cristy66688e52010-06-03 17:32:17 +0000503 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000504 (*fail)++;
505 continue;
506 }
507 /*
508 Write reference image.
509 */
cristy75a26232010-06-03 17:15:02 +0000510 (void) FormatMagickString(size,MaxTextExtent,"%.20gx%.20g",
511 (double) reference_image->columns,(double) reference_image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000512 (void) CloneString(&image_info->size,size);
513 image_info->depth=reference_types[j].depth;
514 (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
515 reference_formats[i].magick,output_filename);
516 status=SetImageType(reference_image,reference_types[j].type);
517 InheritException(exception,&reference_image->exception);
518 if (status == MagickFalse)
519 {
cristy66688e52010-06-03 17:32:17 +0000520 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000521 (*fail)++;
522 reference_image=DestroyImage(reference_image);
523 continue;
524 }
525 status=SetImageDepth(reference_image,reference_types[j].depth);
526 InheritException(exception,&reference_image->exception);
527 if (status == MagickFalse)
528 {
cristy66688e52010-06-03 17:32:17 +0000529 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000530 (*fail)++;
531 reference_image=DestroyImage(reference_image);
532 continue;
533 }
cristy7998e5f2009-10-08 02:45:33 +0000534 reference_image->compression=reference_formats[i].compression;
cristy3ed852e2009-09-05 21:47:34 +0000535 status=WriteImage(image_info,reference_image);
536 InheritException(exception,&reference_image->exception);
537 reference_image=DestroyImage(reference_image);
538 if (status == MagickFalse)
539 {
cristy66688e52010-06-03 17:32:17 +0000540 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000541 (*fail)++;
542 continue;
543 }
544 /*
545 Read reference image.
546 */
547 (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
548 reference_formats[i].magick,output_filename);
549 reference_image=ReadImage(image_info,exception);
550 if (reference_image == (Image *) NULL)
551 {
cristy66688e52010-06-03 17:32:17 +0000552 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000553 (*fail)++;
554 continue;
555 }
556 /*
557 Write reference image.
558 */
559 (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
560 reference_formats[i].magick,output_filename);
561 (void) CopyMagickString(image_info->magick,reference_formats[i].magick,
562 MaxTextExtent);
563 reference_image->depth=reference_types[j].depth;
cristy7998e5f2009-10-08 02:45:33 +0000564 reference_image->compression=reference_formats[i].compression;
cristy3ed852e2009-09-05 21:47:34 +0000565 length=8192;
566 blob=ImageToBlob(image_info,reference_image,&length,exception);
567 if (blob == (unsigned char *) NULL)
568 {
cristy66688e52010-06-03 17:32:17 +0000569 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000570 (*fail)++;
571 reference_image=DestroyImage(reference_image);
572 continue;
573 }
574 /*
575 Read reconstruct image.
576 */
577 (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
578 reference_formats[i].magick,output_filename);
579 reconstruct_image=BlobToImage(image_info,blob,length,exception);
580 blob=(unsigned char *) RelinquishMagickMemory(blob);
581 if (reconstruct_image == (Image *) NULL)
582 {
cristy66688e52010-06-03 17:32:17 +0000583 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000584 (*fail)++;
585 reference_image=DestroyImage(reference_image);
586 continue;
587 }
588 /*
589 Compare reference to reconstruct image.
590 */
591 fuzz=0.0;
592 if (reference_formats[i].fuzz != 0.0)
593 fuzz=reference_formats[i].fuzz;
594#if defined(MAGICKCORE_HDRI_SUPPORT)
595 fuzz+=0.003;
596#endif
597 if (reference_image->colorspace != RGBColorspace)
598 fuzz+=0.3;
599 fuzz+=MagickEpsilon;
600 difference_image=CompareImageChannels(reference_image,reconstruct_image,
601 AllChannels,MeanSquaredErrorMetric,&distortion,exception);
602 reconstruct_image=DestroyImage(reconstruct_image);
603 reference_image=DestroyImage(reference_image);
604 if (difference_image == (Image *) NULL)
605 {
cristy66688e52010-06-03 17:32:17 +0000606 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000607 (*fail)++;
608 continue;
609 }
610 difference_image=DestroyImage(difference_image);
611 if ((distortion/QuantumRange) > fuzz)
612 {
cristye7f51092010-01-17 00:39:37 +0000613 (void) fprintf(stdout,"... fail (with distortion %g).\n",
cristy8cd5b312010-01-07 01:10:24 +0000614 distortion/QuantumRange);
cristy3ed852e2009-09-05 21:47:34 +0000615 (*fail)++;
616 continue;
617 }
618 (void) fprintf(stdout,"... pass.\n");
619 }
620 }
cristy75a26232010-06-03 17:15:02 +0000621 (void) fprintf(stdout,
622 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
623 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000624 return(test);
625}
626
627/*
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629% %
630% %
631% %
632% 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 %
633% %
634% %
635% %
636%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637%
638% ValidateImageFormatsOnDisk() validates the ImageMagick image formats on disk
639% and returns the number of validation tests that passed and failed.
640%
641% The format of the ValidateImageFormatsOnDisk method is:
642%
cristybb503372010-05-27 20:51:26 +0000643% size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000644% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000645% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000646%
647% A description of each parameter follows:
648%
649% o image_info: the image info.
650%
651% o reference_filename: the reference image filename.
652%
653% o output_filename: the output image filename.
654%
655% o fail: return the number of validation tests that pass.
656%
657% o exception: return any errors or warnings in this structure.
658%
659*/
cristybb503372010-05-27 20:51:26 +0000660static size_t ValidateImageFormatsOnDisk(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000661 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000662 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000663{
664 char
665 size[MaxTextExtent];
666
667 const MagickInfo
668 *magick_info;
669
670 double
671 distortion,
672 fuzz;
673
674 Image
675 *difference_image,
676 *reference_image,
677 *reconstruct_image;
678
679 MagickBooleanType
680 status;
681
cristybb503372010-05-27 20:51:26 +0000682 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000683 i,
684 j;
685
cristybb503372010-05-27 20:51:26 +0000686 size_t
cristy3ed852e2009-09-05 21:47:34 +0000687 test;
688
689 test=0;
690 (void) fprintf(stdout,"validate image formats on disk:\n");
691 for (i=0; reference_formats[i].magick != (char *) NULL; i++)
692 {
693 magick_info=GetMagickInfo(reference_formats[i].magick,exception);
694 if ((magick_info == (const MagickInfo *) NULL) ||
695 (magick_info->decoder == (DecodeImageHandler *) NULL) ||
696 (magick_info->encoder == (EncodeImageHandler *) NULL))
697 continue;
698 for (j=0; reference_types[j].type != UndefinedType; j++)
699 {
700 /*
701 Generate reference image.
702 */
703 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000704 (void) fprintf(stdout," test %.20g: %s/%s/%s/%.20g-bits",(double)
705 (test++),reference_formats[i].magick,MagickOptionToMnemonic(
cristy7998e5f2009-10-08 02:45:33 +0000706 MagickCompressOptions,reference_formats[i].compression),
707 MagickOptionToMnemonic(MagickTypeOptions,reference_types[j].type),
cristy75a26232010-06-03 17:15:02 +0000708 (double) reference_types[j].depth);
cristy3ed852e2009-09-05 21:47:34 +0000709 (void) CopyMagickString(image_info->filename,reference_filename,
710 MaxTextExtent);
711 reference_image=ReadImage(image_info,exception);
712 if (reference_image == (Image *) NULL)
713 {
cristy66688e52010-06-03 17:32:17 +0000714 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000715 (*fail)++;
716 continue;
717 }
718 /*
719 Write reference image.
720 */
cristy75a26232010-06-03 17:15:02 +0000721 (void) FormatMagickString(size,MaxTextExtent,"%.20gx%.20g",
722 (double) reference_image->columns,(double) reference_image->rows);
cristy3ed852e2009-09-05 21:47:34 +0000723 (void) CloneString(&image_info->size,size);
724 image_info->depth=reference_types[j].depth;
725 (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
726 reference_formats[i].magick,output_filename);
727 status=SetImageType(reference_image,reference_types[j].type);
728 InheritException(exception,&reference_image->exception);
729 if (status == MagickFalse)
730 {
cristy66688e52010-06-03 17:32:17 +0000731 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000732 (*fail)++;
733 reference_image=DestroyImage(reference_image);
734 continue;
735 }
736 status=SetImageDepth(reference_image,reference_types[j].depth);
737 InheritException(exception,&reference_image->exception);
738 if (status == MagickFalse)
739 {
cristy66688e52010-06-03 17:32:17 +0000740 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000741 (*fail)++;
742 reference_image=DestroyImage(reference_image);
743 continue;
744 }
cristy7998e5f2009-10-08 02:45:33 +0000745 reference_image->compression=reference_formats[i].compression;
cristy3ed852e2009-09-05 21:47:34 +0000746 status=WriteImage(image_info,reference_image);
747 InheritException(exception,&reference_image->exception);
748 reference_image=DestroyImage(reference_image);
749 if (status == MagickFalse)
750 {
cristy66688e52010-06-03 17:32:17 +0000751 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000752 (*fail)++;
753 continue;
754 }
755 /*
756 Read reference image.
757 */
758 (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
759 reference_formats[i].magick,output_filename);
760 reference_image=ReadImage(image_info,exception);
761 if (reference_image == (Image *) NULL)
762 {
cristy66688e52010-06-03 17:32:17 +0000763 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000764 (*fail)++;
765 continue;
766 }
767 /*
768 Write reference image.
769 */
770 (void) FormatMagickString(reference_image->filename,MaxTextExtent,"%s:%s",
771 reference_formats[i].magick,output_filename);
772 reference_image->depth=reference_types[j].depth;
cristy7998e5f2009-10-08 02:45:33 +0000773 reference_image->compression=reference_formats[i].compression;
cristy3ed852e2009-09-05 21:47:34 +0000774 status=WriteImage(image_info,reference_image);
775 InheritException(exception,&reference_image->exception);
776 if (status == MagickFalse)
777 {
cristy66688e52010-06-03 17:32:17 +0000778 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000779 (*fail)++;
780 reference_image=DestroyImage(reference_image);
781 continue;
782 }
783 /*
784 Read reconstruct image.
785 */
786 (void) FormatMagickString(image_info->filename,MaxTextExtent,"%s:%s",
787 reference_formats[i].magick,output_filename);
788 reconstruct_image=ReadImage(image_info,exception);
789 if (reconstruct_image == (Image *) NULL)
790 {
cristy66688e52010-06-03 17:32:17 +0000791 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000792 (*fail)++;
793 reference_image=DestroyImage(reference_image);
794 continue;
795 }
796 /*
797 Compare reference to reconstruct image.
798 */
799 fuzz=0.0;
800 if (reference_formats[i].fuzz != 0.0)
801 fuzz=reference_formats[i].fuzz;
802#if defined(MAGICKCORE_HDRI_SUPPORT)
803 fuzz+=0.003;
804#endif
805 if (reference_image->colorspace != RGBColorspace)
806 fuzz+=0.3;
807 fuzz+=MagickEpsilon;
808 difference_image=CompareImageChannels(reference_image,reconstruct_image,
809 AllChannels,MeanSquaredErrorMetric,&distortion,exception);
810 reconstruct_image=DestroyImage(reconstruct_image);
811 reference_image=DestroyImage(reference_image);
812 if (difference_image == (Image *) NULL)
813 {
cristy66688e52010-06-03 17:32:17 +0000814 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000815 (*fail)++;
816 continue;
817 }
818 difference_image=DestroyImage(difference_image);
819 if ((distortion/QuantumRange) > fuzz)
820 {
cristye7f51092010-01-17 00:39:37 +0000821 (void) fprintf(stdout,"... fail (with distortion %g).\n",
cristy8cd5b312010-01-07 01:10:24 +0000822 distortion/QuantumRange);
cristy3ed852e2009-09-05 21:47:34 +0000823 (*fail)++;
824 continue;
825 }
826 (void) fprintf(stdout,"... pass.\n");
827 }
828 }
cristy75a26232010-06-03 17:15:02 +0000829 (void) fprintf(stdout,
830 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
831 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +0000832 return(test);
833}
834
835/*
836%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
837% %
838% %
839% %
840% 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 %
841% %
842% %
843% %
844%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
845%
846% ValidateImportExportPixels() validates the pixel import and export methods.
847% It returns the number of validation tests that passed and failed.
848%
849% The format of the ValidateImportExportPixels method is:
850%
cristybb503372010-05-27 20:51:26 +0000851% size_t ValidateImportExportPixels(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000852% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000853% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000854%
855% A description of each parameter follows:
856%
857% o image_info: the image info.
858%
859% o reference_filename: the reference image filename.
860%
861% o output_filename: the output image filename.
862%
863% o fail: return the number of validation tests that pass.
864%
865% o exception: return any errors or warnings in this structure.
866%
867*/
cristybb503372010-05-27 20:51:26 +0000868static size_t ValidateImportExportPixels(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000869 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +0000870 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000871{
872 double
873 distortion;
874
875 Image
876 *difference_image,
877 *reference_image,
878 *reconstruct_image;
879
880 MagickBooleanType
881 status;
882
cristybb503372010-05-27 20:51:26 +0000883 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000884 i,
885 j;
886
887 size_t
888 length;
889
890 unsigned char
891 *pixels;
892
cristybb503372010-05-27 20:51:26 +0000893 size_t
cristy3ed852e2009-09-05 21:47:34 +0000894 test;
895
896 (void) output_filename;
897 test=0;
898 (void) fprintf(stdout,"validate the import and export of image pixels:\n");
899 for (i=0; reference_map[i] != (char *) NULL; i++)
900 {
901 for (j=0; reference_storage[j].type != UndefinedPixel; j++)
902 {
903 /*
904 Generate reference image.
905 */
906 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +0000907 (void) fprintf(stdout," test %.20g: %s/%s",(double) (test++),
cristy3ed852e2009-09-05 21:47:34 +0000908 reference_map[i],MagickOptionToMnemonic(MagickStorageOptions,
909 reference_storage[j].type));
910 (void) CopyMagickString(image_info->filename,reference_filename,
911 MaxTextExtent);
912 reference_image=ReadImage(image_info,exception);
913 if (reference_image == (Image *) NULL)
914 {
cristy66688e52010-06-03 17:32:17 +0000915 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000916 (*fail)++;
917 continue;
918 }
919 if (LocaleNCompare(reference_map[i],"cmy",3) == 0)
920 (void) TransformImageColorspace(reference_image,CMYKColorspace);
921 length=strlen(reference_map[i])*reference_image->columns*
922 reference_image->rows*reference_storage[j].quantum;
923 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
924 if (pixels == (unsigned char *) NULL)
925 {
cristy66688e52010-06-03 17:32:17 +0000926 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000927 (*fail)++;
928 reference_image=DestroyImage(reference_image);
929 continue;
930 }
931 (void) ResetMagickMemory(pixels,0,length*sizeof(*pixels));
932 status=ExportImagePixels(reference_image,0,0,reference_image->columns,
933 reference_image->rows,reference_map[i],reference_storage[j].type,pixels,
934 exception);
935 if (status == MagickFalse)
936 {
cristy66688e52010-06-03 17:32:17 +0000937 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000938 (*fail)++;
939 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
940 reference_image=DestroyImage(reference_image);
941 continue;
942 }
943 (void) SetImageBackgroundColor(reference_image);
944 status=ImportImagePixels(reference_image,0,0,reference_image->columns,
945 reference_image->rows,reference_map[i],reference_storage[j].type,
946 pixels);
947 InheritException(exception,&reference_image->exception);
948 if (status == MagickFalse)
949 {
cristy66688e52010-06-03 17:32:17 +0000950 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000951 (*fail)++;
952 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
953 reference_image=DestroyImage(reference_image);
954 continue;
955 }
956 /*
957 Read reconstruct image.
958 */
959 reconstruct_image=AcquireImage(image_info);
960 (void) SetImageExtent(reconstruct_image,reference_image->columns,
961 reference_image->rows);
962 (void) SetImageColorspace(reconstruct_image,reference_image->colorspace);
963 (void) SetImageBackgroundColor(reconstruct_image);
964 status=ImportImagePixels(reconstruct_image,0,0,reconstruct_image->columns,
965 reconstruct_image->rows,reference_map[i],reference_storage[j].type,
966 pixels);
967 InheritException(exception,&reconstruct_image->exception);
968 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
969 if (status == MagickFalse)
970 {
cristy66688e52010-06-03 17:32:17 +0000971 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000972 (*fail)++;
973 reference_image=DestroyImage(reference_image);
974 continue;
975 }
976 /*
977 Compare reference to reconstruct image.
978 */
979 difference_image=CompareImageChannels(reference_image,reconstruct_image,
980 AllChannels,MeanSquaredErrorMetric,&distortion,exception);
981 reconstruct_image=DestroyImage(reconstruct_image);
982 reference_image=DestroyImage(reference_image);
983 if (difference_image == (Image *) NULL)
984 {
cristy66688e52010-06-03 17:32:17 +0000985 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +0000986 (*fail)++;
987 continue;
988 }
989 difference_image=DestroyImage(difference_image);
990 if ((distortion/QuantumRange) > 0.0)
991 {
cristye7f51092010-01-17 00:39:37 +0000992 (void) fprintf(stdout,"... fail (with distortion %g).\n",
cristy8cd5b312010-01-07 01:10:24 +0000993 distortion/QuantumRange);
cristy3ed852e2009-09-05 21:47:34 +0000994 (*fail)++;
995 continue;
996 }
997 (void) fprintf(stdout,"... pass.\n");
998 }
999 }
cristy75a26232010-06-03 17:15:02 +00001000 (void) fprintf(stdout,
1001 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1002 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001003 return(test);
1004}
1005
1006/*
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008% %
1009% %
1010% %
1011% V a l i d a t e M o n t a g e C o m m a n d %
1012% %
1013% %
1014% %
1015%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1016%
1017% ValidateMontageCommand() validates the ImageMagick montage command line
1018% program and returns the number of validation tests that passed and failed.
1019%
1020% The format of the ValidateMontageCommand method is:
1021%
cristybb503372010-05-27 20:51:26 +00001022% size_t ValidateMontageCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001023% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001024% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001025%
1026% A description of each parameter follows:
1027%
1028% o image_info: the image info.
1029%
1030% o reference_filename: the reference image filename.
1031%
1032% o output_filename: the output image filename.
1033%
1034% o fail: return the number of validation tests that pass.
1035%
1036% o exception: return any errors or warnings in this structure.
1037%
1038*/
cristybb503372010-05-27 20:51:26 +00001039static size_t ValidateMontageCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001040 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001041 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001042{
1043 char
1044 **arguments,
1045 command[MaxTextExtent];
1046
1047 int
1048 number_arguments;
1049
1050 MagickBooleanType
1051 status;
1052
cristybb503372010-05-27 20:51:26 +00001053 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001054 i,
1055 j;
1056
cristybb503372010-05-27 20:51:26 +00001057 size_t
cristy3ed852e2009-09-05 21:47:34 +00001058 test;
1059
1060 test=0;
1061 (void) fprintf(stdout,"validate montage command line program:\n");
1062 for (i=0; montage_options[i] != (char *) NULL; i++)
1063 {
1064 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +00001065 (void) fprintf(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00001066 montage_options[i]);
cristy3ed852e2009-09-05 21:47:34 +00001067 (void) FormatMagickString(command,MaxTextExtent,"%s %s %s %s",
1068 reference_filename,montage_options[i],reference_filename,
1069 output_filename);
1070 arguments=StringToArgv(command,&number_arguments);
1071 if (arguments == (char **) NULL)
1072 {
cristy66688e52010-06-03 17:32:17 +00001073 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001074 (*fail)++;
1075 continue;
1076 }
1077 status=MontageImageCommand(image_info,number_arguments,arguments,
1078 (char **) NULL,exception);
1079 for (j=0; j < number_arguments; j++)
1080 arguments[j]=DestroyString(arguments[j]);
1081 arguments=(char **) RelinquishMagickMemory(arguments);
1082 if (status != MagickFalse)
1083 {
cristy66688e52010-06-03 17:32:17 +00001084 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001085 (*fail)++;
1086 continue;
1087 }
1088 (void) fprintf(stdout,"... pass.\n");
1089 }
cristy75a26232010-06-03 17:15:02 +00001090 (void) fprintf(stdout,
1091 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1092 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001093 return(test);
1094}
1095
1096/*
1097%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1098% %
1099% %
1100% %
1101% V a l i d a t e S t r e a m C o m m a n d %
1102% %
1103% %
1104% %
1105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1106%
1107% ValidateStreamCommand() validates the ImageMagick stream command line
1108% program and returns the number of validation tests that passed and failed.
1109%
1110% The format of the ValidateStreamCommand method is:
1111%
cristybb503372010-05-27 20:51:26 +00001112% size_t ValidateStreamCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001113% const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001114% size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001115%
1116% A description of each parameter follows:
1117%
1118% o image_info: the image info.
1119%
1120% o reference_filename: the reference image filename.
1121%
1122% o output_filename: the output image filename.
1123%
1124% o fail: return the number of validation tests that pass.
1125%
1126% o exception: return any errors or warnings in this structure.
1127%
1128*/
cristybb503372010-05-27 20:51:26 +00001129static size_t ValidateStreamCommand(ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +00001130 const char *reference_filename,const char *output_filename,
cristybb503372010-05-27 20:51:26 +00001131 size_t *fail,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +00001132{
1133 char
1134 **arguments,
1135 command[MaxTextExtent];
1136
1137 int
1138 number_arguments;
1139
1140 MagickBooleanType
1141 status;
1142
cristybb503372010-05-27 20:51:26 +00001143 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001144 i,
1145 j;
1146
cristybb503372010-05-27 20:51:26 +00001147 size_t
cristy3ed852e2009-09-05 21:47:34 +00001148 test;
1149
1150 test=0;
1151 (void) fprintf(stdout,"validate stream command line program:\n");
1152 for (i=0; stream_options[i] != (char *) NULL; i++)
1153 {
1154 CatchException(exception);
cristy75a26232010-06-03 17:15:02 +00001155 (void) fprintf(stdout," test %.20g: %s",(double) (test++),
cristy6aa47ad2010-05-28 19:32:32 +00001156 stream_options[i]);
cristy3ed852e2009-09-05 21:47:34 +00001157 (void) FormatMagickString(command,MaxTextExtent,"%s %s %s",
1158 stream_options[i],reference_filename,output_filename);
1159 arguments=StringToArgv(command,&number_arguments);
1160 if (arguments == (char **) NULL)
1161 {
cristy66688e52010-06-03 17:32:17 +00001162 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001163 (*fail)++;
1164 continue;
1165 }
1166 status=StreamImageCommand(image_info,number_arguments,arguments,
1167 (char **) NULL,exception);
1168 for (j=0; j < number_arguments; j++)
1169 arguments[j]=DestroyString(arguments[j]);
1170 arguments=(char **) RelinquishMagickMemory(arguments);
1171 if (status != MagickFalse)
1172 {
cristy66688e52010-06-03 17:32:17 +00001173 (void) fprintf(stdout,"... fail @ %s/%s/%lu.\n",GetMagickModule());
cristy3ed852e2009-09-05 21:47:34 +00001174 (*fail)++;
1175 continue;
1176 }
1177 (void) fprintf(stdout,"... pass.\n");
1178 }
cristy75a26232010-06-03 17:15:02 +00001179 (void) fprintf(stdout,
1180 " summary: %.20g subtests; %.20g passed; %.20g failed.\n",(double) test,
1181 (double) (test-(*fail)),(double) *fail);
cristy3ed852e2009-09-05 21:47:34 +00001182 return(test);
1183}
1184
1185/*
1186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1187% %
1188% %
1189% %
1190% M a i n %
1191% %
1192% %
1193% %
1194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1195%
1196%
1197*/
1198
1199static MagickBooleanType ValidateUsage(void)
1200{
1201 const char
1202 **p;
1203
1204 static const char
1205 *miscellaneous[]=
1206 {
1207 "-debug events display copious debugging information",
1208 "-help print program options",
1209 "-log format format of debugging information",
1210 "-validate type validation type",
1211 "-version print version information",
1212 (char *) NULL
1213 },
1214 *settings[]=
1215 {
1216 "-regard-warnings pay attention to warning messages",
1217 "-verbose print detailed information about the image",
1218 (char *) NULL
1219 };
1220
cristybb503372010-05-27 20:51:26 +00001221 (void) printf("Version: %s\n",GetMagickVersion((size_t *) NULL));
cristy3ed852e2009-09-05 21:47:34 +00001222 (void) printf("Copyright: %s\n\n",GetMagickCopyright());
cristyb28d6472009-10-17 20:13:35 +00001223 (void) printf("Features: %s\n",GetMagickFeatures());
cristy3ed852e2009-09-05 21:47:34 +00001224 (void) printf("Usage: %s [options ...] reference-file\n",GetClientName());
1225 (void) printf("\nValidate Settings:\n");
1226 for (p=settings; *p != (char *) NULL; p++)
1227 (void) printf(" %s\n",*p);
1228 (void) printf("\nMiscellaneous Options:\n");
1229 for (p=miscellaneous; *p != (char *) NULL; p++)
1230 (void) printf(" %s\n",*p);
1231 return(MagickTrue);
1232}
1233
1234int main(int argc,char **argv)
1235{
1236#define DestroyValidate() \
1237{ \
cristy3ed852e2009-09-05 21:47:34 +00001238 image_info=DestroyImageInfo(image_info); \
1239 exception=DestroyExceptionInfo(exception); \
1240}
1241#define ThrowValidateException(asperity,tag,option) \
1242{ \
1243 (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag,"`%s'", \
1244 option); \
1245 CatchException(exception); \
1246 DestroyValidate(); \
1247 return(MagickFalse); \
1248}
1249
1250 char
1251 output_filename[MaxTextExtent],
1252 reference_filename[MaxTextExtent],
1253 *option;
1254
1255 double
1256 elapsed_time,
1257 user_time;
1258
1259 ExceptionInfo
1260 *exception;
1261
1262 Image
1263 *reference_image;
1264
1265 ImageInfo
1266 *image_info;
1267
1268 MagickBooleanType
1269 regard_warnings,
1270 status;
1271
cristybb503372010-05-27 20:51:26 +00001272 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001273 i;
1274
1275 TimerInfo
1276 *timer;
1277
cristybb503372010-05-27 20:51:26 +00001278 size_t
cristy3ed852e2009-09-05 21:47:34 +00001279 fail,
1280 iterations,
1281 tests;
1282
1283 ValidateType
1284 type;
1285
1286 /*
1287 Validate the ImageMagick image processing suite.
1288 */
1289 MagickCoreGenesis(*argv,MagickFalse);
1290 iterations=1;
1291 status=MagickFalse;
1292 type=AllValidate;
1293 regard_warnings=MagickFalse;
1294 exception=AcquireExceptionInfo();
1295 image_info=AcquireImageInfo();
1296 (void) CopyMagickString(image_info->filename,ReferenceFilename,MaxTextExtent);
cristybb503372010-05-27 20:51:26 +00001297 for (i=1; i < (ssize_t) argc; i++)
cristy3ed852e2009-09-05 21:47:34 +00001298 {
1299 option=argv[i];
1300 if (IsMagickOption(option) == MagickFalse)
1301 {
1302 (void) CopyMagickString(image_info->filename,option,MaxTextExtent);
1303 continue;
1304 }
1305 switch (*(option+1))
1306 {
1307 case 'b':
1308 {
1309 if (LocaleCompare("bench",option+1) == 0)
1310 {
cristye27293e2009-12-18 02:53:20 +00001311 iterations=StringToUnsignedLong(argv[++i]);
cristy3ed852e2009-09-05 21:47:34 +00001312 break;
1313 }
1314 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1315 }
1316 case 'd':
1317 {
1318 if (LocaleCompare("debug",option+1) == 0)
1319 {
1320 (void) SetLogEventMask(argv[++i]);
1321 break;
1322 }
1323 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1324 }
1325 case 'h':
1326 {
1327 if (LocaleCompare("help",option+1) == 0)
1328 {
1329 (void) ValidateUsage();
1330 return(0);
1331 }
1332 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1333 }
1334 case 'l':
1335 {
1336 if (LocaleCompare("log",option+1) == 0)
1337 {
1338 if (*option != '+')
1339 (void) SetLogFormat(argv[i+1]);
1340 break;
1341 }
1342 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1343 }
1344 case 'r':
1345 {
1346 if (LocaleCompare("regard-warnings",option+1) == 0)
1347 {
1348 regard_warnings=MagickTrue;
1349 break;
1350 }
1351 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1352 }
1353 case 'v':
1354 {
1355 if (LocaleCompare("validate",option+1) == 0)
1356 {
cristybb503372010-05-27 20:51:26 +00001357 ssize_t
cristy3ed852e2009-09-05 21:47:34 +00001358 validate;
1359
1360 if (*option == '+')
1361 break;
1362 i++;
cristybb503372010-05-27 20:51:26 +00001363 if (i == (ssize_t) argc)
cristy3ed852e2009-09-05 21:47:34 +00001364 ThrowValidateException(OptionError,"MissingArgument",option);
1365 validate=ParseMagickOption(MagickValidateOptions,MagickFalse,
1366 argv[i]);
1367 if (validate < 0)
1368 ThrowValidateException(OptionError,"UnrecognizedValidateType",
1369 argv[i]);
1370 type=(ValidateType) validate;
1371 break;
1372 }
1373 if ((LocaleCompare("version",option+1) == 0) ||
1374 (LocaleCompare("-version",option+1) == 0))
1375 {
1376 (void) fprintf(stdout,"Version: %s\n",
cristybb503372010-05-27 20:51:26 +00001377 GetMagickVersion((size_t *) NULL));
cristy3ed852e2009-09-05 21:47:34 +00001378 (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
cristy104cea82009-10-25 02:26:51 +00001379 (void) fprintf(stdout,"Features: %s\n\n",GetMagickFeatures());
cristy3ed852e2009-09-05 21:47:34 +00001380 return(0);
1381 }
1382 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1383 }
1384 default:
1385 ThrowValidateException(OptionError,"UnrecognizedOption",option)
1386 }
1387 }
cristy205e21f2009-09-28 19:01:46 +00001388 timer=(TimerInfo *) NULL;
cristy8b76e552009-09-28 18:20:20 +00001389 if (iterations > 1)
1390 timer=AcquireTimerInfo();
cristy3ed852e2009-09-05 21:47:34 +00001391 reference_image=ReadImage(image_info,exception);
1392 tests=0;
1393 fail=0;
1394 if (reference_image == (Image *) NULL)
1395 fail++;
1396 else
1397 {
1398 if (LocaleCompare(image_info->filename,ReferenceFilename) == 0)
1399 (void) CopyMagickString(reference_image->magick,ReferenceImageFormat,
1400 MaxTextExtent);
1401 (void) AcquireUniqueFilename(reference_filename);
1402 (void) AcquireUniqueFilename(output_filename);
1403 (void) CopyMagickString(reference_image->filename,reference_filename,
1404 MaxTextExtent);
1405 status=WriteImage(image_info,reference_image);
1406 InheritException(exception,&reference_image->exception);
1407 reference_image=DestroyImage(reference_image);
1408 if (status == MagickFalse)
1409 fail++;
1410 else
1411 {
1412 (void) fprintf(stdout,"Version: %s\n",
cristybb503372010-05-27 20:51:26 +00001413 GetMagickVersion((size_t *) NULL));
cristy3ed852e2009-09-05 21:47:34 +00001414 (void) fprintf(stdout,"Copyright: %s\n\n",
1415 GetMagickCopyright());
1416 (void) fprintf(stdout,"ImageMagick Validation Suite (%s)\n\n",
cristybb503372010-05-27 20:51:26 +00001417 MagickOptionToMnemonic(MagickValidateOptions,(ssize_t) type));
cristy3ed852e2009-09-05 21:47:34 +00001418 if ((type & CompareValidate) != 0)
1419 tests+=ValidateCompareCommand(image_info,reference_filename,
1420 output_filename,&fail,exception);
1421 if ((type & CompositeValidate) != 0)
1422 tests+=ValidateCompositeCommand(image_info,reference_filename,
1423 output_filename,&fail,exception);
1424 if ((type & ConvertValidate) != 0)
1425 tests+=ValidateConvertCommand(image_info,reference_filename,
1426 output_filename,&fail,exception);
1427 if ((type & FormatsInMemoryValidate) != 0)
1428 tests+=ValidateImageFormatsInMemory(image_info,reference_filename,
1429 output_filename,&fail,exception);
1430 if ((type & FormatsOnDiskValidate) != 0)
1431 tests+=ValidateImageFormatsOnDisk(image_info,reference_filename,
1432 output_filename,&fail,exception);
1433 if ((type & IdentifyValidate) != 0)
1434 tests+=ValidateIdentifyCommand(image_info,reference_filename,
1435 output_filename,&fail,exception);
1436 if ((type & ImportExportValidate) != 0)
1437 tests+=ValidateImportExportPixels(image_info,reference_filename,
1438 output_filename,&fail,exception);
1439 if ((type & MontageValidate) != 0)
1440 tests+=ValidateMontageCommand(image_info,reference_filename,
1441 output_filename,&fail,exception);
1442 if ((type & StreamValidate) != 0)
1443 tests+=ValidateStreamCommand(image_info,reference_filename,
1444 output_filename,&fail,exception);
cristy75a26232010-06-03 17:15:02 +00001445 (void) fprintf(stdout,
1446 "validation suite: %.20g tests; %.20g passed; %.20g failed.\n",
1447 (double) tests,(double) (tests-fail),(double) fail);
cristy3ed852e2009-09-05 21:47:34 +00001448 }
1449 (void) RelinquishUniqueFileResource(output_filename);
1450 (void) RelinquishUniqueFileResource(reference_filename);
1451 }
1452 if (exception->severity != UndefinedException)
1453 CatchException(exception);
1454 if (iterations > 1)
1455 {
1456 elapsed_time=GetElapsedTime(timer);
1457 user_time=GetUserTime(timer);
cristy8cd5b312010-01-07 01:10:24 +00001458 (void) fprintf(stderr,
cristy75a26232010-06-03 17:15:02 +00001459 "Performance: %.20gi %gips %0.3fu %ld:%02ld.%03ld\n",(double)
cristy6aa47ad2010-05-28 19:32:32 +00001460 iterations,1.0*iterations/elapsed_time,user_time,(long)
1461 (elapsed_time/60.0),(long) ceil(fmod(elapsed_time,60.0)),
1462 (long) (1000.0*(elapsed_time-floor(elapsed_time))));
cristy8b76e552009-09-28 18:20:20 +00001463 timer=DestroyTimerInfo(timer);
cristy3ed852e2009-09-05 21:47:34 +00001464 }
1465 DestroyValidate();
1466 MagickCoreTerminus();
1467 return(fail == 0 ? 0 : 1);
1468}