1 /*
2 % Copyright (C) 2003-2012 GraphicsMagick Group
3 % Copyright (C) 2003 ImageMagick Studio
4 %
5 % This program is covered by multiple licenses, which are described in
6 % Copyright.txt. You should have received a copy of Copyright.txt with this
7 % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
8 %
9 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 %                                                                             %
11 %                                                                             %
12 %                                                                             %
13 %         IIIII  M   M       CCCC    OOO   M   M  PPPP    AAA   TTTTT         %
14 %           I    MM MM      C       O   O  MM MM  P   P  A   A    T           %
15 %           I    M M M      C       O   O  M M M  PPPP   AAAAA    T           %
16 %           I    M   M      C       O   O  M   M  P      A   A    T           %
17 %         IIIII  M   M       CCCC    OOO   M   M  P      A   A    T           %
18 %                                                                             %
19 %                                                                             %
20 %                     ImageMagick Compatability Methods                       %
21 %                                                                             %
22 %                                                                             %
23 %                             Software Design                                 %
24 %                               John Cristy                                   %
25 %                              January 2003                                   %
26 %                                                                             %
27 %                                                                             %
28 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
29 %
30 %
31 % THIS MODULE IS SCHEDULED FOR DELETION. IT CONTAINS DEAD CODE WHICH REMAINS
32 % ONLY TO SUPPORT THE PREVIOUSLY EXISTING ABI.
33 */
34 
35 /*
36   Include declarations.
37 */
38 #include "magick/studio.h"
39 #include "magick/constitute.h"
40 #include "magick/error.h"
41 #include "magick/utility.h"
42 #include "wand/wand_api.h"
43 #include "wand/wand_private.h"
44 
45 /*
46   Legacy definitions to compile code below with same exported symbols as
47   before.
48 */
49 #define AcquireMagickMemory(memory) malloc(memory)
50 #define AcquireUniqueFileResource(char_pointer) AcquireTemporaryFileName(char_pointer)
51   /* #define CopyMagickString GMPrivateCopyMagickString */
52   /* #define FormatMagickString GMPrivateFormatMagickString */
53 #define GetAffineMatrix(affine_matrix) IdentityAffine(affine_matrix)
54 #define InheritException(copy,original) CopyException(copy,original)
55 #define RelinquishUniqueFileResource LiberateTemporaryFile
56 #define ThrowMagickException ThrowException
57 
58 #define PsiNegative YNegative
59 #define PsiValue XValue
60 #define RhoValue WidthValue
61 #define SigmaValue HeightValue
62 #define XiNegative XNegative
63 #define XiValue YValue
64 
65 #define ConcatenateMagickString GMPrivateConcatenateMagickString
66 #define GeometryInfo GMPrivateGeometryInfo
67 #define ImportImagePixels GMPrivateImportImagePixels
68 #define ParseAbsoluteGeometry GMPrivateParseAbsoluteGeometry
69 #define ParseGeometry GMPrivateParseGeometry
70 #define RelinquishMagickMemory GMPrivateRelinquishMagickMemory
71 #define ResizeMagickMemory GMPrivateResizeMagickMemory
72 #define SetGeometryInfo GMPrivateSetGeometryInfo
73 #define _GeometryInfo _GMPrivateGeometryInfo
74 
75 #define ExportImagePixels DispatchImage
76 
77 typedef struct _GeometryInfo
78 {
79   double
80     rho,
81     sigma,
82     xi,
83     psi;
84 } GeometryInfo;
85 
86 typedef struct _MagickPixelPacket
87 {
88   ColorspaceType
89     colorspace;
90 
91   unsigned int
92     matte;
93 
94   Quantum
95     red,
96     green,
97     blue,
98     opacity;
99 
100   IndexPacket
101     index;
102 } MagickPixelPacket;
103 
104 
105 extern WandExport void
106   *RelinquishMagickMemory(void *),
107   *ResizeMagickMemory(void *memory,const size_t size),
108    SetGeometryInfo(GeometryInfo *geometry_info);
109 
110 extern WandExport int
111   FormatMagickString(char *,const size_t,const char *,...)
112     MAGICK_ATTRIBUTE((format (printf,3,4))),
113   FormatMagickStringList(char *string,const size_t length,
114     const char *format,va_list operands);
115 
116 extern WandExport unsigned int
117   ImportImagePixels(Image *image,const long x_offset,
118     const long y_offset,const unsigned long columns,const unsigned long rows,
119     const char *map,const StorageType type,const void *pixels),
120   ParseAbsoluteGeometry(const char *geometry,RectangleInfo *region_info),
121   ParseGeometry(const char *geometry,GeometryInfo *geometry_info),
122   QueryMagickColor(const char *,MagickPixelPacket *,ExceptionInfo *);
123 
124 extern WandExport size_t
125   ConcatenateMagickString(char *,const char *,const size_t),
126   CopyMagickString(char *,const char *,const size_t);
127 
128 /*
129 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
130 %                                                                             %
131 %                                                                             %
132 %                                                                             %
133 %   C o p y M a g i c k S t r i n g                                           %
134 %                                                                             %
135 %                                                                             %
136 %                                                                             %
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 %
139 %  CopyMagickString() copies the source string to the destination string.  The
140 %  destination buffer is always null-terminated even if the string must be
141 %  truncated.
142 %
143 %  The format of the CopyMagickString method is:
144 %
145 %      size_t CopyMagickString(const char *destination,char *source,
146 %        const size_t length)
147 %
148 %  A description of each parameter follows:
149 %
150 %    o destination: The destination string.
151 %
152 %    o source: The source string.
153 %
154 %    o length: The length of the destination string.
155 %
156 %
157 */
CopyMagickString(char * destination,const char * source,const size_t length)158 WandExport size_t CopyMagickString(char *destination,const char *source,
159   const size_t length)
160 {
161   return(strlcpy(destination,source,length));
162 }
163 
164 /*
165 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
166 %                                                                             %
167 %                                                                             %
168 %                                                                             %
169 %  F o r m a t M a g i c k S t r i n g                                        %
170 %                                                                             %
171 %                                                                             %
172 %                                                                             %
173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
174 %
175 %  FormatMagickString() prints formatted output of a variable argument list.
176 %
177 %  The format of the FormatMagickString method is:
178 %
179 %      void FormatMagickString(char *string,const size_t length,
180 %        const char *format,...)
181 %
182 %  A description of each parameter follows.
183 %
184 %   o string:  FormatMagickString() returns the formatted string in this
185 %     character buffer.
186 %
187 %   o length: The maximum length of the string.
188 %
189 %   o format:  A string describing the format to use to write the remaining
190 %     arguments.
191 %
192 %
193 */
194 WandExport int FormatMagickStringList(char *string,const size_t length,
195                                       const char *format,va_list operands)
196   MAGICK_ATTRIBUTE((__format__ (__printf__,3,0)));
FormatMagickStringList(char * string,const size_t length,const char * format,va_list operands)197 WandExport int FormatMagickStringList(char *string,const size_t length,
198                                       const char *format,va_list operands)
199 {
200   int
201     count;
202 
203 #if defined(HAVE_VSNPRINTF)
204   count=vsnprintf(string,length,format,operands);
205 #else
206   count=vsprintf(string,format,operands);
207 #endif
208 
209   return(count);
210 }
FormatMagickString(char * string,const size_t length,const char * format,...)211 WandExport int FormatMagickString(char *string,const size_t length,
212   const char *format,...)
213 {
214   int
215     count;
216 
217   va_list
218     operands;
219 
220   va_start(operands, format);
221   count=FormatMagickStringList(string,length,format,operands);
222   va_end(operands);
223   return (count);
224 }
225 
226 /*
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 %                                                                             %
229 %                                                                             %
230 %                                                                             %
231 %   C o n c a t e n a t e M a g i c k S t r i n g                             %
232 %                                                                             %
233 %                                                                             %
234 %                                                                             %
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 %
237 %  ConcatenateMagickString() concatenates the source string to the destination
238 %  string.  The destination buffer is always null-terminated even if the
239 %  string must be truncated.
240 %
241 %  The format of the ConcatenateMagickString method is:
242 %
243 %      size_t ConcatenateMagickString(char *destination,const char *source,
244 %        const size_t length)
245 %
246 %  A description of each parameter follows:
247 %
248 %    o destination: The destination string.
249 %
250 %    o source: The source string.
251 %
252 %    o length: The length of the destination string.
253 %
254 %
255 */
ConcatenateMagickString(char * destination,const char * source,const size_t length)256 WandExport size_t ConcatenateMagickString(char *destination,
257   const char *source,const size_t length)
258 {
259   return(strlcat(destination,source,length));
260 }
261 /*
262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
263 %                                                                             %
264 %                                                                             %
265 %                                                                             %
266 %   I m p o r t I m a g e P i x e l s                                         %
267 %                                                                             %
268 %                                                                             %
269 %                                                                             %
270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
271 %
272 %  ImportImagePixels() accepts pixel data and stores in the image at the
273 %  location you specify.  The method returns True on success otherwise False
274 %  if an error is encountered.  The pixel data can be either char, short int,
275 %  int, long, float, or double in the order specified by map.
276 %
277 %  Suppose your want want to upload the first scanline of a 640x480 image from
278 %  character data in red-green-blue order:
279 %
280 %      ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
281 %
282 %  The format of the ImportImagePixels method is:
283 %
284 %      unsigned int ImportImagePixels(Image *image,const long x_offset,
285 %        const long y_offset,const unsigned long columns,
286 %        const unsigned long rows,const char *map,const StorageType type,
287 %        const void *pixels)
288 %
289 %  A description of each parameter follows:
290 %
291 %    o image: The image.
292 %
293 %    o x_offset, y_offset: Offset (from top left) on base image on which
294 %      to composite image data.
295 %
296 %    o map:  This string reflects the expected ordering of the pixel array.
297 %      It can be any combination or order of R = red, G = green, B = blue,
298 %      A = alpha (same as Transparency), O = Opacity, T = Transparency,
299 %      C = cyan, Y = yellow, M = magenta, K = black, or I = intensity
300 %      (for grayscale). Specify "P" = pad, to skip over a quantum which is
301 %      intentionally ignored. Creation of an alpha channel for CMYK images
302 %      is currently not supported.
303 %
304 %    o type: Define the data type of the pixels.  Float and double types are
305 %      normalized to [0..1] otherwise [0..MaxRGB].  Choose from these types:
306 %      CharPixel, ShortPixel, IntegerPixel, LongPixel, FloatPixel, or
307 %      DoublePixel.
308 %
309 %    o pixels: This array of values contain the pixel components as defined by
310 %      map and type.  You must preallocate this array where the expected
311 %      length varies depending on the values of width, height, map, and type.
312 %
313 %
314 */
ImportImagePixels(Image * image,const long x_offset,const long y_offset,const unsigned long columns,const unsigned long rows,const char * map,const StorageType type,const void * pixels)315 WandExport unsigned int ImportImagePixels(Image *image,const long x_offset,
316   const long y_offset,const unsigned long columns,const unsigned long rows,
317   const char *map,const StorageType type,const void *pixels)
318 {
319   Image
320     *constitute_image;
321 
322   assert(image != (Image *) NULL);
323   assert(image->signature == MagickSignature);
324 
325   constitute_image=
326     ConstituteImage(columns,rows,map,type,pixels,&image->exception);
327   if (constitute_image)
328     {
329       (void) CompositeImage(image,CopyCompositeOp,constitute_image,x_offset,
330                             y_offset);
331       DestroyImage(constitute_image);
332       return (image->exception.severity == UndefinedException);
333     }
334   return (False);
335 }
336 
337 /*
338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339 %                                                                             %
340 %                                                                             %
341 %                                                                             %
342 %   P a r s e A b s o l u t e G e o m e t r y                                 %
343 %                                                                             %
344 %                                                                             %
345 %                                                                             %
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 %
348 %  ParseAbsoluteGeometry() returns a region as defined by the geometry string.
349 %
350 %  The format of the ParseAbsoluteGeometry method is:
351 %
352 %      unsigned int ParseAbsoluteGeometry(const char *geometry,
353 %        RectangeInfo *region_info)
354 %
355 %  A description of each parameter follows:
356 %
357 %    o geometry:  The geometry (e.g. 100x100+10+10).
358 %
359 %    o region_info: The region as defined by the geometry string.
360 %
361 %
362 */
ParseAbsoluteGeometry(const char * geometry,RectangleInfo * region_info)363 WandExport unsigned int ParseAbsoluteGeometry(const char *geometry,
364   RectangleInfo *region_info)
365 {
366   unsigned int
367     flags;
368 
369   flags=GetGeometry(geometry,&region_info->x,&region_info->y,
370     &region_info->width,&region_info->height);
371   return(flags);
372 }
373 
374 /*
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 %                                                                             %
377 %                                                                             %
378 %                                                                             %
379 %   P a r s e G e o m e t r y                                                 %
380 %                                                                             %
381 %                                                                             %
382 %                                                                             %
383 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
384 %
385 %  ParseGeometry() parses a geometry specification and returns the sigma,
386 %  rho, xi, and psi values.  It also returns flags that indicates which
387 %  of the four values (sigma, rho, xi, psi) were located in the string, and
388 %  whether the xi or pi values are negative.  In addition, there are flags to
389 %  report any meta characters (%, !, <, or >).
390 %
391 %  The format of the ParseGeometry method is:
392 %
393 %      unsigned int ParseGeometry(const char *geometry,
394 %        GeometryInfo *geometry_info)
395 %
396 %  A description of each parameter follows:
397 %
398 %    o geometry:  The geometry.
399 %
400 %    o geometry_info:  returns the parsed width/height/x/y in this structure.
401 %
402 %
403 */
MoveStringForward(char * dst,const char * src,size_t dstlen)404 static inline char *MoveStringForward(char *dst,const char *src,size_t dstlen)
405 {
406   const size_t srclen = strlen(src);
407   const size_t movelen = Min(dstlen,srclen+1);
408   (void) memmove(dst,src,movelen);
409   dst[movelen-1]='\0';
410   return dst;
411 }
ParseGeometry(const char * geometry,GeometryInfo * geometry_info)412 WandExport unsigned int ParseGeometry(const char *geometry,
413   GeometryInfo *geometry_info)
414 {
415   char
416     *p,
417     pedantic_geometry[MaxTextExtent],
418     *q;
419 
420   unsigned int
421     flags;
422 
423   double
424     double_val;
425 
426   /*
427     Remove whitespaces meta characters from geometry specification.
428   */
429   assert(geometry_info != (GeometryInfo *) NULL);
430   flags=NoValue;
431   if ((geometry == (char *) NULL) || (*geometry == '\0'))
432     return(flags);
433   if (strlcpy(pedantic_geometry,geometry,sizeof(pedantic_geometry))
434       >= sizeof(pedantic_geometry))
435     return(flags);
436   for (p=pedantic_geometry; *p != '\0'; )
437   {
438     if (isspace((int) (*p)))
439       {
440         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
441         continue;
442       }
443     switch (*p)
444     {
445       case '%':
446       {
447         flags|=PercentValue;
448         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
449         break;
450       }
451       case '!':
452       {
453         flags|=AspectValue;
454         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
455         break;
456       }
457       case '<':
458       {
459         flags|=LessValue;
460         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
461         break;
462       }
463       case '>':
464       {
465         flags|=GreaterValue;
466         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
467         break;
468       }
469       case '@':
470       {
471         flags|=AreaValue;
472         (void) MoveStringForward(p,p+1,sizeof(pedantic_geometry));
473         break;
474       }
475       case '-':
476       case '.':
477       case '+':
478       case '0':
479       case '1':
480       case '2':
481       case '3':
482       case '4':
483       case '5':
484       case '6':
485       case '7':
486       case '8':
487       case '9':
488       case 'x':
489       case 'X':
490       case ',':
491       case '/':
492       {
493         p++;
494         break;
495       }
496       default:
497       {
498         ExceptionInfo
499           exception;
500 
501         Image
502           *image;
503 
504         ImageInfo
505           *image_info;
506 
507         /*
508           See if we can grab geometry from an image.
509         */
510         GetExceptionInfo(&exception);
511         image_info=CloneImageInfo((ImageInfo *) NULL);
512         (void) strlcpy(image_info->filename,geometry,sizeof(image_info->filename));
513         image=PingImage(image_info,&exception);
514         if (image != (Image *) NULL)
515           {
516             geometry_info->rho=image->columns;
517             geometry_info->sigma=image->rows;
518             flags|=RhoValue | SigmaValue;
519             DestroyImage(image);
520           }
521         DestroyImageInfo(image_info);
522         DestroyExceptionInfo(&exception);
523         return(flags);
524       }
525     }
526   }
527   /*
528     Parse rho, sigma, xi, and psi.
529   */
530   p=pedantic_geometry;
531   if (*p == '\0')
532     return(flags);
533   q=p;
534   double_val=strtod(p,&q);
535   (void) double_val;
536   if ((*q == 'x') || (*q == 'X') || (*q == '/') || (*q == ',') || (*q =='\0'))
537     {
538       /*
539         Parse rho.
540       */
541       q=p;
542       if (LocaleNCompare(p,"0x",2) == 0)
543         geometry_info->rho=strtol(p,&p,10);
544       else
545         geometry_info->rho=strtod(p,&p);
546       if (p != q)
547         flags|=RhoValue;
548     }
549   if ((*p == 'x') || (*p == 'X') || (*p == '/') || (*p == ','))
550     {
551       /*
552         Parse sigma.
553       */
554       p++;
555       q=p;
556       geometry_info->sigma=strtod(p,&p);
557       if (p != q)
558         flags|=SigmaValue;
559     }
560   if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/'))
561     {
562       /*
563         Parse xi value.
564       */
565       if ((*p == ',') || (*p == '/'))
566         p++;
567       q=p;
568       geometry_info->xi=strtod(p,&p);
569       if (p != q)
570         {
571           flags|=XiValue;
572           if (*q == '-')
573             flags|=XiNegative;
574         }
575       if ((*p == '+') || (*p == '-') || (*p == ',') || (*p == '/'))
576         {
577           /*
578             Parse psi value.
579           */
580           if ((*p == ',') || (*p == '/'))
581             p++;
582           q=p;
583           geometry_info->psi=strtod(p,&p);
584           if (p != q)
585             {
586               flags|=PsiValue;
587               if (*q == '-')
588                 flags|=PsiNegative;
589             }
590         }
591     }
592   return(flags);
593 }
594 
595 /*
596 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
597 %                                                                             %
598 %                                                                             %
599 %                                                                             %
600 %   R e l i n q u i s h M a g i c k M e m o r y                               %
601 %                                                                             %
602 %                                                                             %
603 %                                                                             %
604 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
605 %
606 %  RelinquishMagickMemory() frees memory that has already been allocated with
607 %  AcquireMagickMemory().
608 %
609 %  The format of the RelinquishMagickMemory method is:
610 %
611 %      void *RelinquishMagickMemory(void *memory)
612 %
613 %  A description of each parameter follows:
614 %
615 %    o memory: A pointer to a block of memory to free for reuse.
616 %
617 %
618 */
RelinquishMagickMemory(void * memory)619 WandExport void *RelinquishMagickMemory(void *memory)
620 {
621   if (memory == (void *) NULL)
622     return((void *) NULL);
623   free(memory);
624   return((void *) NULL);
625 }
626 
627 /*
628 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629 %                                                                             %
630 %                                                                             %
631 %                                                                             %
632 %   R e s i z e M a g i c k M e m o r y                                       %
633 %                                                                             %
634 %                                                                             %
635 %                                                                             %
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637 %
638 %  ResizeMagickMemory() changes the size of the memory and returns a pointer to
639 %  the (possibly moved) block.  The contents will be unchanged up to the
640 %  lesser of the new and old sizes.
641 %
642 %  The format of the ResizeMagickMemory method is:
643 %
644 %      void *ResizeMagickMemory(void *memory,const size_t size)
645 %
646 %  A description of each parameter follows:
647 %
648 %    o memory: A pointer to a memory allocation.  On return the pointer
649 %      may change but the contents of the original allocation will not.
650 %
651 %    o size: The new size of the allocated memory.
652 %
653 %
654 */
ResizeMagickMemory(void * memory,const size_t size)655 WandExport void *ResizeMagickMemory(void *memory,const size_t size)
656 {
657   void
658     *allocation;
659 
660   if (memory == (void *) NULL)
661     return(AcquireMagickMemory(size));
662   allocation=realloc(memory,size);
663   if (allocation == (void *) NULL)
664     (void) RelinquishMagickMemory(memory);
665   return(allocation);
666 }
667 
668 
669 /*
670 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
671 %                                                                             %
672 %                                                                             %
673 %                                                                             %
674 %   Q u e r y M a g i c k C o l o r                                           %
675 %                                                                             %
676 %                                                                             %
677 %                                                                             %
678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
679 %
680 %  QueryMagickColor() returns the red, green, blue, and opacity intensities
681 %  for a given color name.
682 %
683 %  The format of the QueryMagickColor method is:
684 %
685 %      unsigned int QueryMagickColor(const char *name,MagickPixelPacket *color,
686 %        ExceptionInfo *exception)
687 %
688 %  A description of each parameter follows:
689 %
690 %    o name: The color name (e.g. white, blue, yellow).
691 %
692 %    o color: The red, green, blue, and opacity intensities values of the
693 %      named color in this structure.
694 %
695 %    o exception: Return any errors or warnings in this structure.
696 %
697 %
698 */
QueryMagickColor(const char * name,MagickPixelPacket * color,ExceptionInfo * exception)699 WandExport unsigned int QueryMagickColor(const char *name,
700   MagickPixelPacket *color,ExceptionInfo *exception)
701 {
702   PixelPacket
703     pixel;
704 
705   unsigned int
706     status;
707 
708   status=QueryColorDatabase(name,&pixel,exception);
709   color->colorspace=RGBColorspace;
710   color->matte=0;
711   color->red=pixel.red;
712   color->green=pixel.green;
713   color->blue=pixel.blue;
714   color->opacity=pixel.opacity;
715   color->index=0;
716   return status;
717 }
718