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,®ion_info->x,®ion_info->y,
370 ®ion_info->width,®ion_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