1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % M M AAA GGGG IIIII CCCC K K %
7 % MM MM A A G I C K K %
8 % M M M AAAAA G GGG I C KKK %
9 % M M A A G G I C K K %
10 % M M A A GGGG IIIII CCCC K K %
11 % %
12 % %
13 % Perform "Magick" on Images via the Command Line Interface %
14 % %
15 % Dragon Computing %
16 % Anthony Thyssen %
17 % January 2012 %
18 % %
19 % %
20 % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
22 % %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
25 % %
26 % https://imagemagick.org/script/license.php %
27 % %
28 % Unless required by applicable law or agreed to in writing, software %
29 % distributed under the License is distributed on an "AS IS" BASIS, %
30 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31 % See the License for the specific language governing permissions and %
32 % limitations under the License. %
33 % %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 % Read CLI arguments, script files, and pipelines, to provide options that
37 % manipulate images from many different formats.
38 %
39 */
40
41 /*
42 Include declarations.
43 */
44 #include "MagickWand/studio.h"
45 #include "MagickWand/MagickWand.h"
46
47 /*
48 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
49 % %
50 % %
51 % %
52 % M a i n %
53 % %
54 % %
55 % %
56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
57 %
58 %
59 */
60
MagickMain(int argc,char ** argv)61 static int MagickMain(int argc,char **argv)
62 {
63 #define MagickCommandSize(name,use_metadata,command) \
64 { (name), sizeof(name)-1, (use_metadata), (command) }
65
66 typedef struct _CommandInfo
67 {
68 const char
69 *client_name;
70
71 size_t
72 extent;
73
74 MagickBooleanType
75 use_metadata;
76
77 MagickCommand
78 command;
79 } CommandInfo;
80
81 const CommandInfo
82 MagickCommands[] =
83 {
84 MagickCommandSize("magick", MagickFalse, MagickImageCommand),
85 MagickCommandSize("convert", MagickFalse, ConvertImageCommand),
86 MagickCommandSize("composite", MagickFalse, CompositeImageCommand),
87 MagickCommandSize("identify", MagickTrue, IdentifyImageCommand),
88 MagickCommandSize("animate", MagickFalse, AnimateImageCommand),
89 MagickCommandSize("compare", MagickTrue, CompareImagesCommand),
90 MagickCommandSize("conjure", MagickFalse, ConjureImageCommand),
91 MagickCommandSize("display", MagickFalse, DisplayImageCommand),
92 MagickCommandSize("import", MagickFalse, ImportImageCommand),
93 MagickCommandSize("mogrify", MagickFalse, MogrifyImageCommand),
94 MagickCommandSize("montage", MagickFalse, MontageImageCommand),
95 MagickCommandSize("stream", MagickFalse, StreamImageCommand)
96 };
97
98 char
99 client_name[MagickPathExtent],
100 *metadata;
101
102 ExceptionInfo
103 *exception;
104
105 ImageInfo
106 *image_info;
107
108 int
109 exit_code,
110 offset;
111
112 MagickBooleanType
113 status;
114
115 ssize_t
116 i;
117
118 size_t
119 number_commands;
120
121 MagickCoreGenesis(*argv,MagickTrue);
122 exception=AcquireExceptionInfo();
123 image_info=AcquireImageInfo();
124 GetPathComponent(argv[0],TailPath,client_name);
125 number_commands=sizeof(MagickCommands)/sizeof(MagickCommands[0]);
126 for (i=0; i < (ssize_t) number_commands; i++)
127 {
128 offset=LocaleNCompare(MagickCommands[i].client_name,client_name,
129 MagickCommands[i].extent);
130 if (offset == 0)
131 break;
132 }
133 i%=(number_commands);
134 if ((i == 0) && (argc > 1))
135 {
136 for (i=1; i < (ssize_t) number_commands; i++)
137 {
138 offset=LocaleCompare(MagickCommands[i].client_name,argv[1]);
139 if (offset == 0)
140 {
141 argc--;
142 argv++;
143 break;
144 }
145 }
146 i%=number_commands;
147 }
148 metadata=(char *) NULL;
149 status=MagickCommandGenesis(image_info,MagickCommands[i].command,argc,argv,
150 MagickCommands[i].use_metadata ? &metadata : (char **) NULL,exception);
151 if (metadata != (char *) NULL)
152 {
153 (void) fputs(metadata,stdout);
154 metadata=DestroyString(metadata);
155 }
156 if (MagickCommands[i].command != CompareImagesCommand)
157 exit_code=status != MagickFalse ? 0 : 1;
158 else
159 {
160 if (status == MagickFalse)
161 exit_code=2;
162 else
163 {
164 const char
165 *option;
166
167 option=GetImageOption(image_info,"compare:dissimilar");
168 exit_code=IsStringTrue(option) ? 1 : 0;
169 }
170 }
171 image_info=DestroyImageInfo(image_info);
172 exception=DestroyExceptionInfo(exception);
173 MagickCoreTerminus();
174 return(exit_code);
175 }
176
177 #if !defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__CYGWIN__) || defined(__MINGW32__)
main(int argc,char ** argv)178 int main(int argc,char **argv)
179 {
180 return(MagickMain(argc,argv));
181 }
182 #else
wmain(int argc,wchar_t * argv[])183 int wmain(int argc,wchar_t *argv[])
184 {
185 char
186 **utf8;
187
188 int
189 status;
190
191 int
192 i;
193
194 utf8=NTArgvToUTF8(argc,argv);
195 status=MagickMain(argc,utf8);
196 for (i=0; i < argc; i++)
197 utf8[i]=DestroyString(utf8[i]);
198 utf8=(char **) RelinquishMagickMemory(utf8);
199 return(status);
200 }
201 #endif
202