compare.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %               CCCC   OOO   M   M  PPPP    AAA   RRRR    EEEEE               %
00007 %              C      O   O  MM MM  P   P  A   A  R   R   E                   %
00008 %              C      O   O  M M M  PPPP   AAAAA  RRRR    EEE                 %
00009 %              C      O   O  M   M  P      A   A  R R     E                   %
00010 %               CCCC   OOO   M   M  P      A   A  R  R    EEEEE               %
00011 %                                                                             %
00012 %                                                                             %
00013 %                         Image Comparison Methods                            %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                               December 2003                                 %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
00042 */
00043 #include "wand/studio.h"
00044 #include "wand/MagickWand.h"
00045 #include "wand/mogrify-private.h"
00046 
00047 /*
00048 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00049 %                                                                             %
00050 %                                                                             %
00051 %                                                                             %
00052 %   C o m p a r e I m a g e C o m m a n d                                     %
00053 %                                                                             %
00054 %                                                                             %
00055 %                                                                             %
00056 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00057 %
00058 %  CompareImageCommand() compares two images and returns the difference between
00059 %  them as a distortion metric and as a new image visually annotating their
00060 %  differences.
00061 %
00062 %  The format of the CompareImageCommand method is:
00063 %
00064 %      MagickBooleanType CompareImageCommand(ImageInfo *image_info,int argc,
00065 %        char **argv,char **metadata,ExceptionInfo *exception)
00066 %
00067 %  A description of each parameter follows:
00068 %
00069 %    o image_info: the image info.
00070 %
00071 %    o argc: the number of elements in the argument vector.
00072 %
00073 %    o argv: A text array containing the command line arguments.
00074 %
00075 %    o metadata: any metadata is returned here.
00076 %
00077 %    o exception: return any errors or warnings in this structure.
00078 %
00079 */
00080 
00081 static void CompareUsage(void)
00082 {
00083   const char
00084     **p;
00085 
00086   static const char
00087     *miscellaneous[]=
00088     {
00089       "-debug events        display copious debugging information",
00090       "-help                print program options",
00091       "-list type           print a list of supported option arguments",
00092       "-log format          format of debugging information",
00093       (char *) NULL
00094     },
00095     *settings[]=
00096     {
00097       "-alpha option        activate, deactivate, reset, or set the alpha channel",
00098       "-authenticate password",
00099       "                     decipher image with this password",
00100       "-channel type        apply option to select image channels",
00101       "-colorspace type     alternate image colorspace",
00102       "-compose operator    set image composite operator",
00103       "-compress type       type of pixel compression when writing the image",
00104       "-decipher filename   convert cipher pixels to plain pixels",
00105       "-define format:option",
00106       "                     define one or more image format options",
00107       "-density geometry    horizontal and vertical density of the image",
00108       "-depth value         image depth",
00109       "-encipher filename   convert plain pixels to cipher pixels",
00110       "-extract geometry    extract area from image",
00111       "-format \"string\"     output formatted image characteristics",
00112       "-fuzz distance       colors within this distance are considered equal",
00113       "-highlight-color color",
00114       "                     empasize pixel differences with this color",
00115       "-identify            identify the format and characteristics of the image",
00116       "-interlace type      type of image interlacing scheme",
00117       "-limit type value    pixel cache resource limit",
00118       "-lowlight-color color",
00119       "                     de-emphasize pixel differences with this color",
00120       "-metric type         measure differences between images with this metric",
00121       "-monitor             monitor progress",
00122       "-passphrase filename get the passphrase from this file",
00123       "-profile filename    add, delete, or apply an image profile",
00124       "-quality value       JPEG/MIFF/PNG compression level",
00125       "-quiet               suppress all warning messages",
00126       "-quantize colorspace reduce colors in this colorspace",
00127       "-regard-warnings     pay attention to warning messages",
00128       "-respect-parenthesis settings remain in effect until parenthesis boundary",
00129       "-sampling-factor geometry",
00130       "                     horizontal and vertical sampling factor",
00131       "-seed value          seed a new sequence of pseudo-random numbers",
00132       "-set attribute value set an image attribute",
00133       "-size geometry       width and height of image",
00134       "-transparent-color color",
00135       "                     transparent color",
00136       "-type type           image type",
00137       "-verbose             print detailed information about the image",
00138       "-version             print version information",
00139       "-virtual-pixel method",
00140       "                     virtual pixel access method",
00141       (char *) NULL
00142     };
00143 
00144   (void) printf("Version: %s\n",GetMagickVersion((unsigned long *) NULL));
00145   (void) printf("Copyright: %s\n\n",GetMagickCopyright());
00146   (void) printf("Usage: %s [options ...] image reconstruct difference\n",
00147     GetClientName());
00148   (void) printf("\nImage Settings:\n");
00149   for (p=settings; *p != (char *) NULL; p++)
00150     (void) printf("  %s\n",*p);
00151   (void) printf("\nMiscellaneous Options:\n");
00152   for (p=miscellaneous; *p != (char *) NULL; p++)
00153     (void) printf("  %s\n",*p);
00154   (void) printf(
00155     "\nBy default, the image format of `file' is determined by its magic\n");
00156   (void) printf(
00157     "number.  To specify a particular image format, precede the filename\n");
00158   (void) printf(
00159     "with an image format name and a colon (i.e. ps:image) or specify the\n");
00160   (void) printf(
00161     "image type as the filename suffix (i.e. image.ps).  Specify 'file' as\n");
00162   (void) printf("'-' for standard input or output.\n");
00163   exit(0);
00164 }
00165 
00166 WandExport MagickBooleanType CompareImageCommand(ImageInfo *image_info,
00167   int argc,char **argv,char **metadata,ExceptionInfo *exception)
00168 {
00169 #define DestroyCompare() \
00170 { \
00171   DestroyImageStack(); \
00172   for (i=0; i < (long) argc; i++) \
00173     argv[i]=DestroyString(argv[i]); \
00174   argv=(char **) RelinquishMagickMemory(argv); \
00175 }
00176 #define ThrowCompareException(asperity,tag,option) \
00177 { \
00178   if (exception->severity < (asperity)) \
00179     (void) ThrowMagickException(exception,GetMagickModule(),asperity,tag, \
00180       "`%s'",option); \
00181   DestroyCompare(); \
00182   return(MagickFalse); \
00183 }
00184 #define ThrowCompareInvalidArgumentException(option,argument) \
00185 { \
00186   (void) ThrowMagickException(exception,GetMagickModule(),OptionError, \
00187     "InvalidArgument","`%s': %s",argument,option); \
00188   DestroyCompare(); \
00189   return(MagickFalse); \
00190 }
00191 
00192   char
00193     *filename,
00194     *option;
00195 
00196   const char
00197     *format;
00198 
00199   ChannelType
00200     channels;
00201 
00202   double
00203     distortion;
00204 
00205   Image
00206     *difference_image,
00207     *image,
00208     *reconstruct_image;
00209 
00210   ImageStack
00211     image_stack[MaxImageStackDepth+1];
00212 
00213   long
00214     j,
00215     k;
00216 
00217   MagickBooleanType
00218     fire,
00219     pend;
00220 
00221   MagickStatusType
00222     status;
00223 
00224   MetricType
00225     metric;
00226 
00227   register long
00228     i;
00229 
00230   /*
00231     Set defaults.
00232   */
00233   assert(image_info != (ImageInfo *) NULL);
00234   assert(image_info->signature == MagickSignature);
00235   if (image_info->debug != MagickFalse)
00236     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00237   assert(exception != (ExceptionInfo *) NULL);
00238   if (argc == 2)
00239     {
00240       option=argv[1];
00241       if ((LocaleCompare("version",option+1) == 0) ||
00242           (LocaleCompare("-version",option+1) == 0))
00243         {
00244           (void) fprintf(stdout,"Version: %s\n",
00245             GetMagickVersion((unsigned long *) NULL));
00246           (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
00247           return(MagickFalse);
00248         }
00249     }
00250   if (argc < 3)
00251     CompareUsage();
00252   channels=AllChannels;
00253   difference_image=NewImageList();
00254   distortion=0.0;
00255   format=(char *) NULL;
00256   j=1;
00257   k=0;
00258   metric=UndefinedMetric;
00259   NewImageStack();
00260   option=(char *) NULL;
00261   pend=MagickFalse;
00262   reconstruct_image=NewImageList();
00263   status=MagickTrue;
00264   /*
00265     Compare an image.
00266   */
00267   ReadCommandlLine(argc,&argv);
00268   status=ExpandFilenames(&argc,&argv);
00269   if (status == MagickFalse)
00270     ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed",
00271       strerror(errno));
00272   for (i=1; i < (long) (argc-1); i++)
00273   {
00274     option=argv[i];
00275     if (LocaleCompare(option,"(") == 0)
00276       {
00277         FireImageStack(MagickTrue,MagickTrue,pend);
00278         if (k == MaxImageStackDepth)
00279           ThrowCompareException(OptionError,"ParenthesisNestedTooDeeply",
00280             option);
00281         PushImageStack();
00282         continue;
00283       }
00284     if (LocaleCompare(option,")") == 0)
00285       {
00286         FireImageStack(MagickTrue,MagickTrue,MagickTrue);
00287         if (k == 0)
00288           ThrowCompareException(OptionError,"UnableToParseExpression",option);
00289         PopImageStack();
00290         continue;
00291       }
00292     if (IsMagickOption(option) == MagickFalse)
00293       {
00294         Image
00295           *images;
00296 
00297         /*
00298           Read input image.
00299         */
00300         FireImageStack(MagickTrue,MagickTrue,pend);
00301         filename=argv[i];
00302         if ((LocaleCompare(filename,"--") == 0) && (i < (argc-1)))
00303           filename=argv[++i];
00304         (void) CopyMagickString(image_info->filename,filename,MaxTextExtent);
00305         images=ReadImages(image_info,exception);
00306         status&=(images != (Image *) NULL) &&
00307           (exception->severity < ErrorException);
00308         if (images == (Image *) NULL)
00309           continue;
00310         AppendImageStack(images);
00311         continue;
00312       }
00313     pend=image != (Image *) NULL ? MagickTrue : MagickFalse;
00314     switch (*(option+1))
00315     {
00316       case 'a':
00317       {
00318         if (LocaleCompare("alpha",option+1) == 0)
00319           {
00320             long
00321               type;
00322 
00323             if (*option == '+')
00324               break;
00325             i++;
00326             if (i == (long) argc)
00327               ThrowCompareException(OptionError,"MissingArgument",option);
00328             type=ParseMagickOption(MagickAlphaOptions,MagickFalse,argv[i]);
00329             if (type < 0)
00330               ThrowCompareException(OptionError,"UnrecognizedAlphaChannelType",
00331                 argv[i]);
00332             break;
00333           }
00334         if (LocaleCompare("authenticate",option+1) == 0)
00335           {
00336             if (*option == '+')
00337               break;
00338             i++;
00339             if (i == (long) argc)
00340               ThrowCompareException(OptionError,"MissingArgument",option);
00341             break;
00342           }
00343         ThrowCompareException(OptionError,"UnrecognizedOption",option);
00344       }
00345       case 'c':
00346       {
00347         if (LocaleCompare("cache",option+1) == 0)
00348           {
00349             if (*option == '+')
00350               break;
00351             i++;
00352             if (i == (long) argc)
00353               ThrowCompareException(OptionError,"MissingArgument",option);
00354             if (IsGeometry(argv[i]) == MagickFalse)
00355               ThrowCompareInvalidArgumentException(option,argv[i]);
00356             break;
00357           }
00358         if (LocaleCompare("channel",option+1) == 0)
00359           {
00360             long
00361               channel;
00362 
00363             if (*option == '+')
00364               break;
00365             i++;
00366             if (i == (long) (argc-1))
00367               ThrowCompareException(OptionError,"MissingArgument",option);
00368             channel=ParseChannelOption(argv[i]);
00369             if (channel < 0)
00370               ThrowCompareException(OptionError,"UnrecognizedChannelType",
00371                 argv[i]);
00372             channels=(ChannelType) channel;
00373             break;
00374           }
00375         if (LocaleCompare("colorspace",option+1) == 0)
00376           {
00377             long
00378               colorspace;
00379 
00380             if (*option == '+')
00381               break;
00382             i++;
00383             if (i == (long) (argc-1))
00384               ThrowCompareException(OptionError,"MissingArgument",option);
00385             colorspace=ParseMagickOption(MagickColorspaceOptions,MagickFalse,
00386               argv[i]);
00387             if (colorspace < 0)
00388               ThrowCompareException(OptionError,"UnrecognizedColorspace",
00389                 argv[i]);
00390             break;
00391           }
00392         if (LocaleCompare("compose",option+1) == 0)
00393           {
00394             long
00395               compose;
00396 
00397             if (*option == '+')
00398               break;
00399             i++;
00400             if (i == (long) argc)
00401               ThrowCompareException(OptionError,"MissingArgument",option);
00402             compose=ParseMagickOption(MagickComposeOptions,MagickFalse,
00403               argv[i]);
00404             if (compose < 0)
00405               ThrowCompareException(OptionError,"UnrecognizedComposeOperator",
00406                 argv[i]);
00407             break;
00408           }
00409         if (LocaleCompare("compress",option+1) == 0)
00410           {
00411             long
00412               compress;
00413 
00414             if (*option == '+')
00415               break;
00416             i++;
00417             if (i == (long) (argc-1))
00418               ThrowCompareException(OptionError,"MissingArgument",option);
00419             compress=ParseMagickOption(MagickCompressOptions,MagickFalse,
00420               argv[i]);
00421             if (compress < 0)
00422               ThrowCompareException(OptionError,"UnrecognizedImageCompression",
00423                 argv[i]);
00424             break;
00425           }
00426         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00427       }
00428       case 'd':
00429       {
00430         if (LocaleCompare("debug",option+1) == 0)
00431           {
00432             LogEventType
00433               event_mask;
00434 
00435             if (*option == '+')
00436               break;
00437             i++;
00438             if (i == (long) argc)
00439               ThrowCompareException(OptionError,"MissingArgument",option);
00440             event_mask=SetLogEventMask(argv[i]);
00441             if (event_mask == UndefinedEvents)
00442               ThrowCompareException(OptionError,"UnrecognizedEventType",
00443                 argv[i]);
00444             break;
00445           }
00446         if (LocaleCompare("decipher",option+1) == 0)
00447           {
00448             if (*option == '+')
00449               break;
00450             i++;
00451             if (i == (long) (argc-1))
00452               ThrowCompareException(OptionError,"MissingArgument",option);
00453             break;
00454           }
00455         if (LocaleCompare("define",option+1) == 0)
00456           {
00457             i++;
00458             if (i == (long) argc)
00459               ThrowCompareException(OptionError,"MissingArgument",option);
00460             if (*option == '+')
00461               {
00462                 const char
00463                   *define;
00464 
00465                 define=GetImageOption(image_info,argv[i]);
00466                 if (define == (const char *) NULL)
00467                   ThrowCompareException(OptionError,"NoSuchOption",argv[i]);
00468                 break;
00469               }
00470             break;
00471           }
00472         if (LocaleCompare("density",option+1) == 0)
00473           {
00474             if (*option == '+')
00475               break;
00476             i++;
00477             if (i == (long) argc)
00478               ThrowCompareException(OptionError,"MissingArgument",option);
00479             if (IsGeometry(argv[i]) == MagickFalse)
00480               ThrowCompareInvalidArgumentException(option,argv[i]);
00481             break;
00482           }
00483         if (LocaleCompare("depth",option+1) == 0)
00484           {
00485             if (*option == '+')
00486               break;
00487             i++;
00488             if (i == (long) argc)
00489               ThrowCompareException(OptionError,"MissingArgument",option);
00490             if (IsGeometry(argv[i]) == MagickFalse)
00491               ThrowCompareInvalidArgumentException(option,argv[i]);
00492             break;
00493           }
00494         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00495       }
00496       case 'e':
00497       {
00498         if (LocaleCompare("encipher",option+1) == 0)
00499           {
00500             if (*option == '+')
00501               break;
00502             i++;
00503             if (i == (long) (argc-1))
00504               ThrowCompareException(OptionError,"MissingArgument",option);
00505             break;
00506           }
00507         if (LocaleCompare("extract",option+1) == 0)
00508           {
00509             if (*option == '+')
00510               break;
00511             i++;
00512             if (i == (long) (argc-1))
00513               ThrowCompareException(OptionError,"MissingArgument",option);
00514             if (IsGeometry(argv[i]) == MagickFalse)
00515               ThrowCompareInvalidArgumentException(option,argv[i]);
00516             break;
00517           }
00518         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00519       }
00520       case 'f':
00521       {
00522         if (LocaleCompare("format",option+1) == 0)
00523           {
00524             if (*option == '+')
00525               break;
00526             i++;
00527             if (i == (long) argc)
00528               ThrowCompareException(OptionError,"MissingArgument",option);
00529             format=argv[i];
00530             break;
00531           }
00532         if (LocaleCompare("fuzz",option+1) == 0)
00533           {
00534             if (*option == '+')
00535               break;
00536             i++;
00537             if (i == (long) (argc-1))
00538               ThrowCompareException(OptionError,"MissingArgument",option);
00539             if (IsGeometry(argv[i]) == MagickFalse)
00540               ThrowCompareInvalidArgumentException(option,argv[i]);
00541             break;
00542           }
00543         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00544       }
00545       case 'h':
00546       {
00547         if ((LocaleCompare("help",option+1) == 0) ||
00548             (LocaleCompare("-help",option+1) == 0))
00549           CompareUsage();
00550         if (LocaleCompare("highlight-color",option+1) == 0)
00551           {
00552             if (*option == '+')
00553               break;
00554             i++;
00555             if (i == (long) (argc-1))
00556               ThrowCompareException(OptionError,"MissingArgument",option);
00557             break;
00558           }
00559         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00560       }
00561       case 'i':
00562       {
00563         if (LocaleCompare("identify",option+1) == 0)
00564           break;
00565         if (LocaleCompare("interlace",option+1) == 0)
00566           {
00567             long
00568               interlace;
00569 
00570             if (*option == '+')
00571               break;
00572             i++;
00573             if (i == (long) argc)
00574               ThrowCompareException(OptionError,"MissingArgument",option);
00575             interlace=ParseMagickOption(MagickInterlaceOptions,MagickFalse,
00576               argv[i]);
00577             if (interlace < 0)
00578               ThrowCompareException(OptionError,"UnrecognizedInterlaceType",
00579                 argv[i]);
00580             break;
00581           }
00582         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00583       }
00584       case 'l':
00585       {
00586         if (LocaleCompare("limit",option+1) == 0)
00587           {
00588             char
00589               *p;
00590 
00591             long
00592               resource;
00593 
00594             if (*option == '+')
00595               break;
00596             i++;
00597             if (i == (long) argc)
00598               ThrowCompareException(OptionError,"MissingArgument",option);
00599             resource=ParseMagickOption(MagickResourceOptions,MagickFalse,
00600               argv[i]);
00601             if (resource < 0)
00602               ThrowCompareException(OptionError,"UnrecognizedResourceType",
00603                 argv[i]);
00604             i++;
00605             if (i == (long) argc)
00606               ThrowCompareException(OptionError,"MissingArgument",option);
00607             (void) strtod(argv[i],&p);
00608             if ((p == argv[i]) && (LocaleCompare("unlimited",argv[i]) != 0))
00609               ThrowCompareInvalidArgumentException(option,argv[i]);
00610             break;
00611           }
00612         if (LocaleCompare("log",option+1) == 0)
00613           {
00614             if (*option == '+')
00615               break;
00616             i++;
00617             if ((i == (long) argc) || (strchr(argv[i],'%') == (char *) NULL))
00618               ThrowCompareException(OptionError,"MissingArgument",option);
00619             break;
00620           }
00621         if (LocaleCompare("lowlight-color",option+1) == 0)
00622           {
00623             if (*option == '+')
00624               break;
00625             i++;
00626             if (i == (long) (argc-1))
00627               ThrowCompareException(OptionError,"MissingArgument",option);
00628             break;
00629           }
00630         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00631       }
00632       case 'm':
00633       {
00634         if (LocaleCompare("matte",option+1) == 0)
00635           break;
00636         if (LocaleCompare("metric",option+1) == 0)
00637           {
00638             long
00639               type;
00640 
00641             if (*option == '+')
00642               break;
00643             i++;
00644             if (i == (long) argc)
00645               ThrowCompareException(OptionError,"MissingArgument",option);
00646             type=ParseMagickOption(MagickMetricOptions,MagickTrue,argv[i]);
00647             if (type < 0)
00648               ThrowCompareException(OptionError,"UnrecognizedMetricType",
00649                 argv[i]);
00650             metric=(MetricType) type;
00651             break;
00652           }
00653         if (LocaleCompare("monitor",option+1) == 0)
00654           break;
00655         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00656       }
00657       case 'p':
00658       {
00659         if (LocaleCompare("passphrase",option+1) == 0)
00660           {
00661             if (*option == '+')
00662               break;
00663             i++;
00664             if (i == (long) argc)
00665               ThrowCompareException(OptionError,"MissingArgument",option);
00666             break;
00667           }
00668         if (LocaleCompare("profile",option+1) == 0)
00669           {
00670             i++;
00671             if (i == (long) (argc-1))
00672               ThrowCompareException(OptionError,"MissingArgument",option);
00673             break;
00674           }
00675         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00676       }
00677       case 'q':
00678       {
00679         if (LocaleCompare("quality",option+1) == 0)
00680           {
00681             if (*option == '+')
00682               break;
00683             i++;
00684             if (i == (long) (argc-1))
00685               ThrowCompareException(OptionError,"MissingArgument",option);
00686             if (IsGeometry(argv[i]) == MagickFalse)
00687               ThrowCompareInvalidArgumentException(option,argv[i]);
00688             break;
00689           }
00690         if (LocaleCompare("quantize",option+1) == 0)
00691           {
00692             long
00693               colorspace;
00694 
00695             if (*option == '+')
00696               break;
00697             i++;
00698             if (i == (long) (argc-1))
00699               ThrowCompareException(OptionError,"MissingArgument",option);
00700             colorspace=ParseMagickOption(MagickColorspaceOptions,
00701               MagickFalse,argv[i]);
00702             if (colorspace < 0)
00703               ThrowCompareException(OptionError,"UnrecognizedColorspace",
00704                 argv[i]);
00705             break;
00706           }
00707         if (LocaleCompare("quiet",option+1) == 0)
00708           break;
00709         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00710       }
00711       case 'r':
00712       {
00713         if (LocaleCompare("regard-warnings",option+1) == 0)
00714           break;
00715         if (LocaleCompare("respect-parenthesis",option+1) == 0)
00716           {
00717             respect_parenthesis=(*option == '-') ? MagickTrue : MagickFalse;
00718             break;
00719           }
00720         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00721       }
00722       case 's':
00723       {
00724         if (LocaleCompare("sampling-factor",option+1) == 0)
00725           {
00726             if (*option == '+')
00727               break;
00728             i++;
00729             if (i == (long) argc)
00730               ThrowCompareException(OptionError,"MissingArgument",option);
00731             if (IsGeometry(argv[i]) == MagickFalse)
00732               ThrowCompareInvalidArgumentException(option,argv[i]);
00733             break;
00734           }
00735         if (LocaleCompare("seed",option+1) == 0)
00736           {
00737             if (*option == '+')
00738               break;
00739             i++;
00740             if (i == (long) (argc-1))
00741               ThrowCompareException(OptionError,"MissingArgument",option);
00742             if (IsGeometry(argv[i]) == MagickFalse)
00743               ThrowCompareInvalidArgumentException(option,argv[i]);
00744             break;
00745           }
00746         if (LocaleCompare("set",option+1) == 0)
00747           {
00748             i++;
00749             if (i == (long) argc)
00750               ThrowCompareException(OptionError,"MissingArgument",option);
00751             if (*option == '+')
00752               break;
00753             i++;
00754             if (i == (long) argc)
00755               ThrowCompareException(OptionError,"MissingArgument",option);
00756             break;
00757           }
00758         if (LocaleCompare("size",option+1) == 0)
00759           {
00760             if (*option == '+')
00761               break;
00762             i++;
00763             if (i == (long) argc)
00764               ThrowCompareException(OptionError,"MissingArgument",option);
00765             if (IsGeometry(argv[i]) == MagickFalse)
00766               ThrowCompareInvalidArgumentException(option,argv[i]);
00767             break;
00768           }
00769         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00770       }
00771       case 't':
00772       {
00773         if (LocaleCompare("transparent-color",option+1) == 0)
00774           {
00775             if (*option == '+')
00776               break;
00777             i++;
00778             if (i == (long) (argc-1))
00779               ThrowCompareException(OptionError,"MissingArgument",option);
00780             break;
00781           }
00782         if (LocaleCompare("type",option+1) == 0)
00783           {
00784             long
00785               type;
00786 
00787             if (*option == '+')
00788               break;
00789             i++;
00790             if (i == (long) argc)
00791               ThrowCompareException(OptionError,"MissingArgument",option);
00792             type=ParseMagickOption(MagickTypeOptions,MagickFalse,argv[i]);
00793             if (type < 0)
00794               ThrowCompareException(OptionError,"UnrecognizedImageType",
00795                 argv[i]);
00796             break;
00797           }
00798         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00799       }
00800       case 'v':
00801       {
00802         if (LocaleCompare("verbose",option+1) == 0)
00803           break;
00804         if ((LocaleCompare("version",option+1) == 0) ||
00805             (LocaleCompare("-version",option+1) == 0))
00806           {
00807             (void) fprintf(stdout,"Version: %s\n",
00808               GetMagickVersion((unsigned long *) NULL));
00809             (void) fprintf(stdout,"Copyright: %s\n\n",GetMagickCopyright());
00810             break;
00811           }
00812         if (LocaleCompare("virtual-pixel",option+1) == 0)
00813           {
00814             long
00815               method;
00816 
00817             if (*option == '+')
00818               break;
00819             i++;
00820             if (i == (long) (argc-1))
00821               ThrowCompareException(OptionError,"MissingArgument",option);
00822             method=ParseMagickOption(MagickVirtualPixelOptions,MagickFalse,
00823               argv[i]);
00824             if (method < 0)
00825               ThrowCompareException(OptionError,
00826                 "UnrecognizedVirtualPixelMethod",argv[i]);
00827             break;
00828           }
00829         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00830       }
00831       case '?':
00832         break;
00833       default:
00834         ThrowCompareException(OptionError,"UnrecognizedOption",option)
00835     }
00836     fire=ParseMagickOption(MagickImageListOptions,MagickFalse,option+1) < 0 ? 
00837       MagickFalse : MagickTrue;
00838     if (fire != MagickFalse)
00839       FireImageStack(MagickTrue,MagickTrue,MagickTrue);
00840   }
00841   if (k != 0)
00842     ThrowCompareException(OptionError,"UnbalancedParenthesis",argv[i]);
00843   if (i-- != (long) (argc-1))
00844     ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]);
00845   if ((image == (Image *) NULL) ||
00846       (GetImageListLength(image) < 2))
00847     ThrowCompareException(OptionError,"MissingAnImageFilename",argv[i]);
00848   FinalizeImageSettings(image_info,image);
00849   image=GetImageFromList(image,0);
00850   reconstruct_image=GetImageFromList(image,1);
00851   difference_image=CompareImageChannels(image,reconstruct_image,channels,
00852     metric,&distortion,exception);
00853   if (difference_image == (Image *) NULL)
00854     status=0;
00855   else
00856     {
00857       if (image_info->verbose != MagickFalse)
00858         (void) IsImagesEqual(image,reconstruct_image);
00859       status&=WriteImages(image_info,difference_image,argv[argc-1],exception);
00860       if ((metadata != (char **) NULL) && (format != (char *) NULL))
00861         {
00862           char
00863             *text;
00864 
00865           text=InterpretImageProperties(image_info,difference_image,format);
00866           if (text == (char *) NULL)
00867             ThrowCompareException(ResourceLimitError,"MemoryAllocationFailed",
00868               strerror(errno));
00869           (void) ConcatenateString(&(*metadata),text);
00870           (void) ConcatenateString(&(*metadata),"\n");
00871           text=DestroyString(text);
00872         }
00873       difference_image=DestroyImageList(difference_image);
00874       if (image_info->verbose == MagickFalse)
00875         switch (metric)
00876         {
00877           case MeanAbsoluteErrorMetric:
00878           case MeanSquaredErrorMetric:
00879           case RootMeanSquaredErrorMetric:
00880           case PeakAbsoluteErrorMetric:
00881           {
00882             (void) fprintf(stderr,"%g (%g)\n",distortion,(double) (QuantumScale*
00883               distortion));
00884             break;
00885           }
00886           case AbsoluteErrorMetric:
00887           case PeakSignalToNoiseRatioMetric:
00888           {
00889             (void) fprintf(stderr,"%g\n",distortion);
00890             break;
00891           }
00892           case MeanErrorPerPixelMetric:
00893           {
00894             (void) fprintf(stderr,"%g (%g, %g)\n",distortion,
00895               image->error.normalized_mean_error,
00896               image->error.normalized_maximum_error);
00897             break;
00898           }
00899           case UndefinedMetric:
00900             break;
00901         }
00902       else
00903         {
00904           double
00905             *channel_distortion;
00906 
00907  
00908           channel_distortion=GetImageChannelDistortions(image,reconstruct_image,
00909             metric,&image->exception);
00910           (void) fprintf(stderr,"Image: %s\n",image->filename);
00911           (void) fprintf(stderr,"  Channel distortion: %s\n",
00912             MagickOptionToMnemonic(MagickMetricOptions,(long) metric));
00913           switch (metric)
00914           {
00915             case MeanAbsoluteErrorMetric:
00916             case MeanSquaredErrorMetric:
00917             case RootMeanSquaredErrorMetric:
00918             case PeakAbsoluteErrorMetric:
00919             {
00920               switch (image->colorspace)
00921               {
00922                 case RGBColorspace:
00923                 default:
00924                 {
00925                   (void) fprintf(stderr,"    red: %g (%g)\n",
00926                     channel_distortion[RedChannel],(double) QuantumScale*
00927                     channel_distortion[RedChannel]);
00928                   (void) fprintf(stderr,"    green: %g (%g)\n",
00929                     channel_distortion[GreenChannel],(double) QuantumScale*
00930                     channel_distortion[GreenChannel]);
00931                   (void) fprintf(stderr,"    blue: %g (%g)\n",
00932                     channel_distortion[BlueChannel],(double) QuantumScale*
00933                     channel_distortion[BlueChannel]);
00934                   if (image->matte != MagickFalse)
00935                     (void) fprintf(stderr,"    alpha: %g (%g)\n",
00936                       channel_distortion[OpacityChannel],(double) QuantumScale*
00937                       channel_distortion[OpacityChannel]);
00938                   break;
00939                 }
00940                 case CMYKColorspace:
00941                 {
00942                   (void) fprintf(stderr,"    cyan: %g (%g)\n",
00943                     channel_distortion[CyanChannel],(double) QuantumScale*
00944                     channel_distortion[CyanChannel]);
00945                   (void) fprintf(stderr,"    magenta: %g (%g)\n",
00946                     channel_distortion[MagentaChannel],(double) QuantumScale*
00947                     channel_distortion[MagentaChannel]);
00948                   (void) fprintf(stderr,"    yellow: %g (%g)\n",
00949                     channel_distortion[YellowChannel],(double) QuantumScale*
00950                     channel_distortion[YellowChannel]);
00951                   (void) fprintf(stderr,"    black: %g (%g)\n",
00952                     channel_distortion[BlackChannel],(double) QuantumScale*
00953                     channel_distortion[BlackChannel]);
00954                   if (image->matte != MagickFalse)
00955                     (void) fprintf(stderr,"    alpha: %g (%g)\n",
00956                       channel_distortion[OpacityChannel],(double) QuantumScale*
00957                       channel_distortion[OpacityChannel]);
00958                   break;
00959                 }
00960                 case GRAYColorspace:
00961                 {
00962                   (void) fprintf(stderr,"    gray: %g (%g)\n",
00963                     channel_distortion[GrayChannel],(double) QuantumScale*
00964                     channel_distortion[GrayChannel]);
00965                   if (image->matte != MagickFalse)
00966                     (void) fprintf(stderr,"    alpha: %g (%g)\n",
00967                       channel_distortion[OpacityChannel],(double) QuantumScale*
00968                       channel_distortion[OpacityChannel]);
00969                   break;
00970                 }
00971               }
00972               (void) fprintf(stderr,"    all: %g (%g)\n",
00973                 channel_distortion[AllChannels],(double) QuantumScale*
00974                 channel_distortion[AllChannels]);
00975               break;
00976             }
00977             case AbsoluteErrorMetric:
00978             case PeakSignalToNoiseRatioMetric:
00979             {
00980               switch (image->colorspace)
00981               {
00982                 case RGBColorspace:
00983                 default:
00984                 {
00985                   (void) fprintf(stderr,"    red: %g\n",
00986                     channel_distortion[RedChannel]);
00987                   (void) fprintf(stderr,"    green: %g\n",
00988                     channel_distortion[GreenChannel]);
00989                   (void) fprintf(stderr,"    blue: %g\n",
00990                     channel_distortion[BlueChannel]);
00991                   if (image->matte != MagickFalse)
00992                     (void) fprintf(stderr,"    alpha: %g\n",
00993                       channel_distortion[OpacityChannel]);
00994                   break;
00995                 }
00996                 case CMYKColorspace:
00997                 {
00998                   (void) fprintf(stderr,"    cyan: %g\n",
00999                     channel_distortion[CyanChannel]);
01000                   (void) fprintf(stderr,"    magenta: %g\n",
01001                     channel_distortion[MagentaChannel]);
01002                   (void) fprintf(stderr,"    yellow: %g\n",
01003                     channel_distortion[YellowChannel]);
01004                   (void) fprintf(stderr,"    black: %g\n",
01005                     channel_distortion[BlackChannel]);
01006                   if (image->matte != MagickFalse)
01007                     (void) fprintf(stderr,"    alpha: %g\n",
01008                       channel_distortion[OpacityChannel]);
01009                   break;
01010                 }
01011                 case GRAYColorspace:
01012                 {
01013                   (void) fprintf(stderr,"    gray: %g\n",
01014                     channel_distortion[GrayChannel]);
01015                   if (image->matte != MagickFalse)
01016                     (void) fprintf(stderr,"    alpha: %g\n",
01017                       channel_distortion[OpacityChannel]);
01018                   break;
01019                 }
01020               }
01021               (void) fprintf(stderr,"    all: %g\n",
01022                 channel_distortion[AllChannels]);
01023               break;
01024             }
01025             case MeanErrorPerPixelMetric:
01026             {
01027               (void) fprintf(stderr,"    %g (%g, %g)\n",
01028                 channel_distortion[AllChannels],
01029                 image->error.normalized_mean_error,
01030                 image->error.normalized_maximum_error);
01031               break;
01032             }
01033             case UndefinedMetric:
01034               break;
01035           }
01036           channel_distortion=(double *) RelinquishMagickMemory(
01037             channel_distortion);
01038         }
01039     }
01040   DestroyCompare();
01041   return(status != 0 ? MagickTrue : MagickFalse);
01042 }

Generated on Sat Nov 22 23:45:25 2008 for MagickWand by  doxygen 1.5.7.1