2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % PPPP IIIII X X EEEEE L %
10 % P IIIII X X EEEEE LLLLL %
12 % MagickCore Methods to Import/Export Pixels %
19 % Copyright 1999-2013 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
25 % http://www.imagemagick.org/script/license.php %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 #include "MagickCore/studio.h"
42 #include "MagickCore/property.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/cache-private.h"
46 #include "MagickCore/color-private.h"
47 #include "MagickCore/draw.h"
48 #include "MagickCore/exception.h"
49 #include "MagickCore/exception-private.h"
50 #include "MagickCore/cache.h"
51 #include "MagickCore/constitute.h"
52 #include "MagickCore/delegate.h"
53 #include "MagickCore/geometry.h"
54 #include "MagickCore/image-private.h"
55 #include "MagickCore/list.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/monitor.h"
59 #include "MagickCore/option.h"
60 #include "MagickCore/pixel.h"
61 #include "MagickCore/pixel-accessor.h"
62 #include "MagickCore/pixel-private.h"
63 #include "MagickCore/quantum.h"
64 #include "MagickCore/quantum-private.h"
65 #include "MagickCore/resource_.h"
66 #include "MagickCore/semaphore.h"
67 #include "MagickCore/statistic.h"
68 #include "MagickCore/stream.h"
69 #include "MagickCore/string_.h"
70 #include "MagickCore/transform.h"
71 #include "MagickCore/utility.h"
73 #define LogPixelChannels(image) \
78 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%.20g]", \
79 image->filename,(double) image->number_channels); \
80 for (i=0; i < (ssize_t) image->number_channels; i++) \
83 traits[MaxTextExtent]; \
91 switch (GetPixelChannelChannel(image,i)) \
93 case RedPixelChannel: \
96 if (image->colorspace == CMYKColorspace) \
98 if (image->colorspace == GRAYColorspace) \
102 case GreenPixelChannel: \
105 if (image->colorspace == CMYKColorspace) \
109 case BluePixelChannel: \
112 if (image->colorspace == CMYKColorspace) \
116 case BlackPixelChannel: \
119 if (image->storage_class == PseudoClass) \
123 case IndexPixelChannel: \
128 case AlphaPixelChannel: \
133 case ReadMaskPixelChannel: \
138 case MetaPixelChannel: \
146 channel=GetPixelChannelChannel(image,i); \
148 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0) \
149 (void) ConcatenateMagickString(traits,"update,",MaxTextExtent); \
150 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0) \
151 (void) ConcatenateMagickString(traits,"blend,",MaxTextExtent); \
152 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0) \
153 (void) ConcatenateMagickString(traits,"copy,",MaxTextExtent); \
154 if (*traits == '\0') \
155 (void) ConcatenateMagickString(traits,"undefined,",MaxTextExtent); \
156 traits[strlen(traits)-1]='\0'; \
157 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)", \
158 (double) i,name,traits); \
163 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167 + A c q u i r e P i x e l C h a n n e l M a p %
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
173 % AcquirePixelChannelMap() acquires a pixel component map.
175 % The format of the AcquirePixelChannelMap() method is:
177 % PixelChannelMap *AcquirePixelChannelMap(void)
180 MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
188 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
189 sizeof(*channel_map));
190 if (channel_map == (PixelChannelMap *) NULL)
191 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
192 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
193 for (i=0; i < MaxPixelChannels; i++)
194 channel_map[i].channel=(PixelChannel) i;
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
203 + C l o n e P i x e l C h a n n e l M a p %
207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
209 % ClonePixelChannelMap() clones a pixel component map.
211 % The format of the ClonePixelChannelMap() method is:
213 % PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
215 % A description of each parameter follows:
217 % o channel_map: the pixel component map.
220 MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
225 assert(channel_map != (PixelChannelMap *) NULL);
226 clone_map=AcquirePixelChannelMap();
227 if (clone_map == (PixelChannelMap *) NULL)
228 return((PixelChannelMap *) NULL);
229 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
230 sizeof(*channel_map));
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239 + C l o n e P i x e l I n f o %
243 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
245 % ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
246 % pixel info is NULL, a new one.
248 % The format of the ClonePixelInfo method is:
250 % PixelInfo *ClonePixelInfo(const PixelInfo *pixel_info)
252 % A description of each parameter follows:
254 % o pixel_info: the pixel info.
257 MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
262 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
263 if (pixel_info == (PixelInfo *) NULL)
264 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
265 *pixel_info=(*pixel);
270 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274 % D e c o d e P i x e l G a m m a %
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 % DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel.
282 % The format of the DecodePixelGamma method is:
284 % double DecodePixelGamma(const MagickRealType pixel)
286 % A description of each parameter follows:
288 % o pixel: the pixel.
292 static inline double DecodeGamma(const double x)
304 static const double coefficient[] = /* terms for x^(7/5), x=1.5 */
306 1.7917488588043277509,
307 0.82045614371976854984,
308 0.027694100686325412819,
309 -0.00094244335181762134018,
310 0.000064355540911469709545,
311 -5.7224404636060757485e-06,
312 5.8767669437311184313e-07,
313 -6.6139920053589721168e-08,
314 7.9323242696227458163e-09
317 static const double powers_of_two[] = /* (2^x)^(7/5) */
320 2.6390158215457883983,
321 6.9644045063689921093,
322 1.8379173679952558018e+01,
323 4.8502930128332728543e+01
327 Compute x^2.4 == x*x^(7/5) == pow(x,2.4).
330 term[1]=4.0*frexp(x,&exponent)-3.0;
331 term[2]=2.0*term[1]*term[1]-term[0];
332 term[3]=2.0*term[1]*term[2]-term[1];
333 term[4]=2.0*term[1]*term[3]-term[2];
334 term[5]=2.0*term[1]*term[4]-term[3];
335 term[6]=2.0*term[1]*term[5]-term[4];
336 term[7]=2.0*term[1]*term[6]-term[5];
337 term[8]=2.0*term[1]*term[7]-term[6];
338 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
339 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
340 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
341 quotient=div(exponent-1,5);
342 if (quotient.rem < 0)
347 return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot));
350 MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel)
352 if (pixel <= (0.0404482362771076*QuantumRange))
353 return(pixel/12.92f);
354 return((MagickRealType) (QuantumRange*DecodeGamma((double) (QuantumScale*
355 pixel+0.055)/1.055)));
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363 + D e s t r o y P i x e l C h a n n e l M a p %
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 % DestroyPixelChannelMap() deallocates memory associated with the pixel
372 % The format of the DestroyPixelChannelMap() method is:
374 % PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
376 % A description of each parameter follows:
378 % o channel_map: the pixel component map.
381 MagickExport PixelChannelMap *DestroyPixelChannelMap(
382 PixelChannelMap *channel_map)
384 assert(channel_map != (PixelChannelMap *) NULL);
385 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
386 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
390 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394 + E n c o d e P i x e l G a m m a %
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400 % EncodePixelGamma() cancels any nonlinearity in the pixel.
402 % The format of the EncodePixelGamma method is:
404 % MagickRealType EncodePixelGamma(const double MagickRealType)
406 % A description of each parameter follows:
408 % o pixel: the pixel.
412 static inline double EncodeGamma(const double x)
424 static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */
426 1.1758200232996901923,
427 0.16665763094889061230,
428 -0.0083154894939042125035,
429 0.00075187976780420279038,
430 -0.000083240178519391795367,
431 0.000010229209410070008679,
432 -1.3400466409860246e-06,
433 1.8333422241635376682e-07,
434 -2.5878596761348859722e-08
437 static const double powers_of_two[] = /* (2^N)^(5/12) */
440 1.3348398541700343678,
441 1.7817974362806785482,
442 2.3784142300054420538,
443 3.1748021039363991669,
444 4.2378523774371812394,
445 5.6568542494923805819,
446 7.5509945014535482244,
447 1.0079368399158985525e1,
448 1.3454342644059433809e1,
449 1.7959392772949968275e1,
450 2.3972913230026907883e1
454 Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4).
457 term[1]=4.0*frexp(x,&exponent)-3.0;
458 term[2]=2.0*term[1]*term[1]-term[0];
459 term[3]=2.0*term[1]*term[2]-term[1];
460 term[4]=2.0*term[1]*term[3]-term[2];
461 term[5]=2.0*term[1]*term[4]-term[3];
462 term[6]=2.0*term[1]*term[5]-term[4];
463 term[7]=2.0*term[1]*term[6]-term[5];
464 term[8]=2.0*term[1]*term[7]-term[6];
465 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
466 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
467 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
468 quotient=div(exponent-1,12);
469 if (quotient.rem < 0)
474 return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot));
477 MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel)
479 if (pixel <= (0.0031306684425005883*QuantumRange))
480 return(12.92f*pixel);
481 return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale*
486 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
490 % E x p o r t I m a g e P i x e l s %
494 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
496 % ExportImagePixels() extracts pixel data from an image and returns it to you.
497 % The method returns MagickTrue on success otherwise MagickFalse if an error is
498 % encountered. The data is returned as char, short int, Quantum, unsigned int,
499 % unsigned long long, float, or double in the order specified by map.
501 % Suppose you want to extract the first scanline of a 640x480 image as
502 % character data in red-green-blue order:
504 % ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
506 % The format of the ExportImagePixels method is:
508 % MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
509 % const ssize_t y,const size_t width,const size_t height,
510 % const char *map,const StorageType type,void *pixels,
511 % ExceptionInfo *exception)
513 % A description of each parameter follows:
515 % o image: the image.
517 % o x,y,width,height: These values define the perimeter
518 % of a region of pixels you want to extract.
520 % o map: This string reflects the expected ordering of the pixel array.
521 % It can be any combination or order of R = red, G = green, B = blue,
522 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
523 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
526 % o type: Define the data type of the pixels. Float and double types are
527 % normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
528 % types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
529 % LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
530 % QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
532 % o pixels: This array of values contain the pixel components as defined by
533 % map and type. You must preallocate this array where the expected
534 % length varies depending on the values of width, height, map, and type.
536 % o exception: return any errors or warnings in this structure.
540 static void ExportCharPixel(Image *image,const RectangleInfo *roi,
541 const char *restrict map,const QuantumType *quantum_map,void *pixels,
542 ExceptionInfo *exception)
544 register const Quantum
550 register unsigned char
559 q=(unsigned char *) pixels;
560 if (LocaleCompare(map,"BGR") == 0)
562 for (y=0; y < (ssize_t) roi->height; y++)
564 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
565 if (p == (const Quantum *) NULL)
567 for (x=0; x < (ssize_t) roi->width; x++)
569 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
570 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
571 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
572 p+=GetPixelChannels(image);
577 if (LocaleCompare(map,"BGRA") == 0)
579 for (y=0; y < (ssize_t) roi->height; y++)
581 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
582 if (p == (const Quantum *) NULL)
584 for (x=0; x < (ssize_t) roi->width; x++)
586 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
587 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
588 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
589 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
590 p+=GetPixelChannels(image);
595 if (LocaleCompare(map,"BGRP") == 0)
597 for (y=0; y < (ssize_t) roi->height; y++)
599 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
600 if (p == (const Quantum *) NULL)
602 for (x=0; x < (ssize_t) roi->width; x++)
604 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
605 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
606 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
607 *q++=ScaleQuantumToChar((Quantum) 0);
608 p+=GetPixelChannels(image);
613 if (LocaleCompare(map,"I") == 0)
615 for (y=0; y < (ssize_t) roi->height; y++)
617 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
618 if (p == (const Quantum *) NULL)
620 for (x=0; x < (ssize_t) roi->width; x++)
622 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
623 p+=GetPixelChannels(image);
628 if (LocaleCompare(map,"RGB") == 0)
630 for (y=0; y < (ssize_t) roi->height; y++)
632 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
633 if (p == (const Quantum *) NULL)
635 for (x=0; x < (ssize_t) roi->width; x++)
637 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
638 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
639 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
640 p+=GetPixelChannels(image);
645 if (LocaleCompare(map,"RGBA") == 0)
647 for (y=0; y < (ssize_t) roi->height; y++)
649 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
650 if (p == (const Quantum *) NULL)
652 for (x=0; x < (ssize_t) roi->width; x++)
654 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
655 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
656 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
657 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
658 p+=GetPixelChannels(image);
663 if (LocaleCompare(map,"RGBP") == 0)
665 for (y=0; y < (ssize_t) roi->height; y++)
667 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
668 if (p == (const Quantum *) NULL)
670 for (x=0; x < (ssize_t) roi->width; x++)
672 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
673 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
674 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
675 *q++=ScaleQuantumToChar((Quantum) 0);
676 p+=GetPixelChannels(image);
682 for (y=0; y < (ssize_t) roi->height; y++)
684 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
685 if (p == (const Quantum *) NULL)
687 for (x=0; x < (ssize_t) roi->width; x++)
692 for (i=0; i < (ssize_t) length; i++)
695 switch (quantum_map[i])
700 *q=ScaleQuantumToChar(GetPixelRed(image,p));
706 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
712 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
717 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
722 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
727 if (image->colorspace == CMYKColorspace)
728 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
733 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
741 p+=GetPixelChannels(image);
746 static void ExportDoublePixel(Image *image,const RectangleInfo *roi,
747 const char *restrict map,const QuantumType *quantum_map,void *pixels,
748 ExceptionInfo *exception)
750 register const Quantum
766 if (LocaleCompare(map,"BGR") == 0)
768 for (y=0; y < (ssize_t) roi->height; y++)
770 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
771 if (p == (const Quantum *) NULL)
773 for (x=0; x < (ssize_t) roi->width; x++)
775 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
776 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
777 *q++=(double) (QuantumScale*GetPixelRed(image,p));
778 p+=GetPixelChannels(image);
783 if (LocaleCompare(map,"BGRA") == 0)
785 for (y=0; y < (ssize_t) roi->height; y++)
787 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
788 if (p == (const Quantum *) NULL)
790 for (x=0; x < (ssize_t) roi->width; x++)
792 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
793 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
794 *q++=(double) (QuantumScale*GetPixelRed(image,p));
795 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
796 p+=GetPixelChannels(image);
801 if (LocaleCompare(map,"BGRP") == 0)
803 for (y=0; y < (ssize_t) roi->height; y++)
805 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
806 if (p == (const Quantum *) NULL)
808 for (x=0; x < (ssize_t) roi->width; x++)
810 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
811 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
812 *q++=(double) (QuantumScale*GetPixelRed(image,p));
814 p+=GetPixelChannels(image);
819 if (LocaleCompare(map,"I") == 0)
821 for (y=0; y < (ssize_t) roi->height; y++)
823 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
824 if (p == (const Quantum *) NULL)
826 for (x=0; x < (ssize_t) roi->width; x++)
828 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
829 p+=GetPixelChannels(image);
834 if (LocaleCompare(map,"RGB") == 0)
836 for (y=0; y < (ssize_t) roi->height; y++)
838 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
839 if (p == (const Quantum *) NULL)
841 for (x=0; x < (ssize_t) roi->width; x++)
843 *q++=(double) (QuantumScale*GetPixelRed(image,p));
844 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
845 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
846 p+=GetPixelChannels(image);
851 if (LocaleCompare(map,"RGBA") == 0)
853 for (y=0; y < (ssize_t) roi->height; y++)
855 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
856 if (p == (const Quantum *) NULL)
858 for (x=0; x < (ssize_t) roi->width; x++)
860 *q++=(double) (QuantumScale*GetPixelRed(image,p));
861 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
862 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
863 *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
864 p+=GetPixelChannels(image);
869 if (LocaleCompare(map,"RGBP") == 0)
871 for (y=0; y < (ssize_t) roi->height; y++)
873 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
874 if (p == (const Quantum *) NULL)
876 for (x=0; x < (ssize_t) roi->width; x++)
878 *q++=(double) (QuantumScale*GetPixelRed(image,p));
879 *q++=(double) (QuantumScale*GetPixelGreen(image,p));
880 *q++=(double) (QuantumScale*GetPixelBlue(image,p));
882 p+=GetPixelChannels(image);
888 for (y=0; y < (ssize_t) roi->height; y++)
890 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
891 if (p == (const Quantum *) NULL)
893 for (x=0; x < (ssize_t) roi->width; x++)
898 for (i=0; i < (ssize_t) length; i++)
901 switch (quantum_map[i])
906 *q=(double) (QuantumScale*GetPixelRed(image,p));
912 *q=(double) (QuantumScale*GetPixelGreen(image,p));
918 *q=(double) (QuantumScale*GetPixelBlue(image,p));
923 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
928 *q=(double) (QuantumScale*GetPixelAlpha(image,p));
933 if (image->colorspace == CMYKColorspace)
934 *q=(double) (QuantumScale*
935 GetPixelBlack(image,p));
940 *q=(double) (QuantumScale*GetPixelIntensity(image,p));
948 p+=GetPixelChannels(image);
953 static void ExportFloatPixel(Image *image,const RectangleInfo *roi,
954 const char *restrict map,const QuantumType *quantum_map,void *pixels,
955 ExceptionInfo *exception)
957 register const Quantum
973 if (LocaleCompare(map,"BGR") == 0)
975 for (y=0; y < (ssize_t) roi->height; y++)
977 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
978 if (p == (const Quantum *) NULL)
980 for (x=0; x < (ssize_t) roi->width; x++)
982 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
983 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
984 *q++=(float) (QuantumScale*GetPixelRed(image,p));
985 p+=GetPixelChannels(image);
990 if (LocaleCompare(map,"BGRA") == 0)
992 for (y=0; y < (ssize_t) roi->height; y++)
994 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
995 if (p == (const Quantum *) NULL)
997 for (x=0; x < (ssize_t) roi->width; x++)
999 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1000 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1001 *q++=(float) (QuantumScale*GetPixelRed(image,p));
1002 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
1003 p+=GetPixelChannels(image);
1008 if (LocaleCompare(map,"BGRP") == 0)
1010 for (y=0; y < (ssize_t) roi->height; y++)
1012 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1013 if (p == (const Quantum *) NULL)
1015 for (x=0; x < (ssize_t) roi->width; x++)
1017 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1018 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1019 *q++=(float) (QuantumScale*GetPixelRed(image,p));
1021 p+=GetPixelChannels(image);
1026 if (LocaleCompare(map,"I") == 0)
1028 for (y=0; y < (ssize_t) roi->height; y++)
1030 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1031 if (p == (const Quantum *) NULL)
1033 for (x=0; x < (ssize_t) roi->width; x++)
1035 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
1036 p+=GetPixelChannels(image);
1041 if (LocaleCompare(map,"RGB") == 0)
1043 for (y=0; y < (ssize_t) roi->height; y++)
1045 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1046 if (p == (const Quantum *) NULL)
1048 for (x=0; x < (ssize_t) roi->width; x++)
1050 *q++=(float) (QuantumScale*GetPixelRed(image,p));
1051 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1052 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1053 p+=GetPixelChannels(image);
1058 if (LocaleCompare(map,"RGBA") == 0)
1060 for (y=0; y < (ssize_t) roi->height; y++)
1062 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1063 if (p == (const Quantum *) NULL)
1065 for (x=0; x < (ssize_t) roi->width; x++)
1067 *q++=(float) (QuantumScale*GetPixelRed(image,p));
1068 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1069 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1070 *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
1071 p+=GetPixelChannels(image);
1076 if (LocaleCompare(map,"RGBP") == 0)
1078 for (y=0; y < (ssize_t) roi->height; y++)
1080 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1081 if (p == (const Quantum *) NULL)
1083 for (x=0; x < (ssize_t) roi->width; x++)
1085 *q++=(float) (QuantumScale*GetPixelRed(image,p));
1086 *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1087 *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1089 p+=GetPixelChannels(image);
1095 for (y=0; y < (ssize_t) roi->height; y++)
1097 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1098 if (p == (const Quantum *) NULL)
1100 for (x=0; x < (ssize_t) roi->width; x++)
1105 for (i=0; i < (ssize_t) length; i++)
1108 switch (quantum_map[i])
1113 *q=(float) (QuantumScale*GetPixelRed(image,p));
1117 case MagentaQuantum:
1119 *q=(float) (QuantumScale*GetPixelGreen(image,p));
1125 *q=(float) (QuantumScale*GetPixelBlue(image,p));
1130 *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
1133 case OpacityQuantum:
1135 *q=(float) (QuantumScale*GetPixelAlpha(image,p));
1140 if (image->colorspace == CMYKColorspace)
1141 *q=(float) (QuantumScale* GetPixelBlack(image,p));
1146 *q=(float) (QuantumScale*GetPixelIntensity(image,p));
1154 p+=GetPixelChannels(image);
1159 static void ExportLongPixel(Image *image,const RectangleInfo *roi,
1160 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1161 ExceptionInfo *exception)
1163 register const Quantum
1169 register unsigned int
1178 q=(unsigned int *) pixels;
1179 if (LocaleCompare(map,"BGR") == 0)
1181 for (y=0; y < (ssize_t) roi->height; y++)
1183 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1184 if (p == (const Quantum *) NULL)
1186 for (x=0; x < (ssize_t) roi->width; x++)
1188 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1189 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1190 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1191 p+=GetPixelChannels(image);
1196 if (LocaleCompare(map,"BGRA") == 0)
1198 for (y=0; y < (ssize_t) roi->height; y++)
1200 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1201 if (p == (const Quantum *) NULL)
1203 for (x=0; x < (ssize_t) roi->width; x++)
1205 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1206 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1207 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1208 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1209 p+=GetPixelChannels(image);
1214 if (LocaleCompare(map,"BGRP") == 0)
1216 for (y=0; y < (ssize_t) roi->height; y++)
1218 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1219 if (p == (const Quantum *) NULL)
1221 for (x=0; x < (ssize_t) roi->width; x++)
1223 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1224 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1225 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1227 p+=GetPixelChannels(image);
1232 if (LocaleCompare(map,"I") == 0)
1234 for (y=0; y < (ssize_t) roi->height; y++)
1236 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1237 if (p == (const Quantum *) NULL)
1239 for (x=0; x < (ssize_t) roi->width; x++)
1241 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1242 p+=GetPixelChannels(image);
1247 if (LocaleCompare(map,"RGB") == 0)
1249 for (y=0; y < (ssize_t) roi->height; y++)
1251 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1252 if (p == (const Quantum *) NULL)
1254 for (x=0; x < (ssize_t) roi->width; x++)
1256 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1257 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1258 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1259 p+=GetPixelChannels(image);
1264 if (LocaleCompare(map,"RGBA") == 0)
1266 for (y=0; y < (ssize_t) roi->height; y++)
1268 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1269 if (p == (const Quantum *) NULL)
1271 for (x=0; x < (ssize_t) roi->width; x++)
1273 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1274 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1275 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1276 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1277 p+=GetPixelChannels(image);
1282 if (LocaleCompare(map,"RGBP") == 0)
1284 for (y=0; y < (ssize_t) roi->height; y++)
1286 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1287 if (p == (const Quantum *) NULL)
1289 for (x=0; x < (ssize_t) roi->width; x++)
1291 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1292 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1293 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1295 p+=GetPixelChannels(image);
1301 for (y=0; y < (ssize_t) roi->height; y++)
1303 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1304 if (p == (const Quantum *) NULL)
1306 for (x=0; x < (ssize_t) roi->width; x++)
1311 for (i=0; i < (ssize_t) length; i++)
1314 switch (quantum_map[i])
1319 *q=ScaleQuantumToLong(GetPixelRed(image,p));
1323 case MagentaQuantum:
1325 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
1331 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
1336 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1339 case OpacityQuantum:
1341 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1346 if (image->colorspace == CMYKColorspace)
1347 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
1352 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1360 p+=GetPixelChannels(image);
1365 static void ExportLongLongPixel(Image *image,const RectangleInfo *roi,
1366 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1367 ExceptionInfo *exception)
1369 register const Quantum
1375 register MagickSizeType
1384 q=(MagickSizeType *) pixels;
1385 if (LocaleCompare(map,"BGR") == 0)
1387 for (y=0; y < (ssize_t) roi->height; y++)
1389 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1390 if (p == (const Quantum *) NULL)
1392 for (x=0; x < (ssize_t) roi->width; x++)
1394 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1395 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1396 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1397 p+=GetPixelChannels(image);
1402 if (LocaleCompare(map,"BGRA") == 0)
1404 for (y=0; y < (ssize_t) roi->height; y++)
1406 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1407 if (p == (const Quantum *) NULL)
1409 for (x=0; x < (ssize_t) roi->width; x++)
1411 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1412 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1413 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1414 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1415 p+=GetPixelChannels(image);
1420 if (LocaleCompare(map,"BGRP") == 0)
1422 for (y=0; y < (ssize_t) roi->height; y++)
1424 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1425 if (p == (const Quantum *) NULL)
1427 for (x=0; x < (ssize_t) roi->width; x++)
1429 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1430 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1431 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1433 p+=GetPixelChannels(image);
1438 if (LocaleCompare(map,"I") == 0)
1440 for (y=0; y < (ssize_t) roi->height; y++)
1442 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1443 if (p == (const Quantum *) NULL)
1445 for (x=0; x < (ssize_t) roi->width; x++)
1447 *q++=ScaleQuantumToLongLong(ClampToQuantum(GetPixelIntensity(image,p)));
1448 p+=GetPixelChannels(image);
1453 if (LocaleCompare(map,"RGB") == 0)
1455 for (y=0; y < (ssize_t) roi->height; y++)
1457 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1458 if (p == (const Quantum *) NULL)
1460 for (x=0; x < (ssize_t) roi->width; x++)
1462 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1463 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1464 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1465 p+=GetPixelChannels(image);
1470 if (LocaleCompare(map,"RGBA") == 0)
1472 for (y=0; y < (ssize_t) roi->height; y++)
1474 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1475 if (p == (const Quantum *) NULL)
1477 for (x=0; x < (ssize_t) roi->width; x++)
1479 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1480 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1481 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1482 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1483 p+=GetPixelChannels(image);
1488 if (LocaleCompare(map,"RGBP") == 0)
1490 for (y=0; y < (ssize_t) roi->height; y++)
1492 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1493 if (p == (const Quantum *) NULL)
1495 for (x=0; x < (ssize_t) roi->width; x++)
1497 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1498 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1499 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1501 p+=GetPixelChannels(image);
1507 for (y=0; y < (ssize_t) roi->height; y++)
1509 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1510 if (p == (const Quantum *) NULL)
1512 for (x=0; x < (ssize_t) roi->width; x++)
1517 for (i=0; i < (ssize_t) length; i++)
1520 switch (quantum_map[i])
1525 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
1529 case MagentaQuantum:
1531 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1537 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1542 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1545 case OpacityQuantum:
1547 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1552 if (image->colorspace == CMYKColorspace)
1553 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
1558 *q=ScaleQuantumToLongLong(ClampToQuantum(GetPixelIntensity(image,p)));
1566 p+=GetPixelChannels(image);
1571 static void ExportQuantumPixel(Image *image,const RectangleInfo *roi,
1572 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1573 ExceptionInfo *exception)
1575 register const Quantum
1590 q=(Quantum *) pixels;
1591 if (LocaleCompare(map,"BGR") == 0)
1593 for (y=0; y < (ssize_t) roi->height; y++)
1595 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1596 if (p == (const Quantum *) NULL)
1598 for (x=0; x < (ssize_t) roi->width; x++)
1600 *q++=GetPixelBlue(image,p);
1601 *q++=GetPixelGreen(image,p);
1602 *q++=GetPixelRed(image,p);
1603 p+=GetPixelChannels(image);
1608 if (LocaleCompare(map,"BGRA") == 0)
1610 for (y=0; y < (ssize_t) roi->height; y++)
1612 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1613 if (p == (const Quantum *) NULL)
1615 for (x=0; x < (ssize_t) roi->width; x++)
1617 *q++=GetPixelBlue(image,p);
1618 *q++=GetPixelGreen(image,p);
1619 *q++=GetPixelRed(image,p);
1620 *q++=(Quantum) (GetPixelAlpha(image,p));
1621 p+=GetPixelChannels(image);
1626 if (LocaleCompare(map,"BGRP") == 0)
1628 for (y=0; y < (ssize_t) roi->height; y++)
1630 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1631 if (p == (const Quantum *) NULL)
1633 for (x=0; x < (ssize_t) roi->width; x++)
1635 *q++=GetPixelBlue(image,p);
1636 *q++=GetPixelGreen(image,p);
1637 *q++=GetPixelRed(image,p);
1639 p+=GetPixelChannels(image);
1644 if (LocaleCompare(map,"I") == 0)
1646 for (y=0; y < (ssize_t) roi->height; y++)
1648 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1649 if (p == (const Quantum *) NULL)
1651 for (x=0; x < (ssize_t) roi->width; x++)
1653 *q++=ClampToQuantum(GetPixelIntensity(image,p));
1654 p+=GetPixelChannels(image);
1659 if (LocaleCompare(map,"RGB") == 0)
1661 for (y=0; y < (ssize_t) roi->height; y++)
1663 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1664 if (p == (const Quantum *) NULL)
1666 for (x=0; x < (ssize_t) roi->width; x++)
1668 *q++=GetPixelRed(image,p);
1669 *q++=GetPixelGreen(image,p);
1670 *q++=GetPixelBlue(image,p);
1671 p+=GetPixelChannels(image);
1676 if (LocaleCompare(map,"RGBA") == 0)
1678 for (y=0; y < (ssize_t) roi->height; y++)
1680 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1681 if (p == (const Quantum *) NULL)
1683 for (x=0; x < (ssize_t) roi->width; x++)
1685 *q++=GetPixelRed(image,p);
1686 *q++=GetPixelGreen(image,p);
1687 *q++=GetPixelBlue(image,p);
1688 *q++=(Quantum) (GetPixelAlpha(image,p));
1689 p+=GetPixelChannels(image);
1694 if (LocaleCompare(map,"RGBP") == 0)
1696 for (y=0; y < (ssize_t) roi->height; y++)
1698 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1699 if (p == (const Quantum *) NULL)
1701 for (x=0; x < (ssize_t) roi->width; x++)
1703 *q++=GetPixelRed(image,p);
1704 *q++=GetPixelGreen(image,p);
1705 *q++=GetPixelBlue(image,p);
1707 p+=GetPixelChannels(image);
1713 for (y=0; y < (ssize_t) roi->height; y++)
1715 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1716 if (p == (const Quantum *) NULL)
1718 for (x=0; x < (ssize_t) roi->width; x++)
1723 for (i=0; i < (ssize_t) length; i++)
1726 switch (quantum_map[i])
1731 *q=GetPixelRed(image,p);
1735 case MagentaQuantum:
1737 *q=GetPixelGreen(image,p);
1743 *q=GetPixelBlue(image,p);
1748 *q=GetPixelAlpha(image,p);
1751 case OpacityQuantum:
1753 *q=GetPixelAlpha(image,p);
1758 if (image->colorspace == CMYKColorspace)
1759 *q=GetPixelBlack(image,p);
1764 *q=ClampToQuantum(GetPixelIntensity(image,p));
1775 p+=GetPixelChannels(image);
1780 static void ExportShortPixel(Image *image,const RectangleInfo *roi,
1781 const char *restrict map,const QuantumType *quantum_map,void *pixels,
1782 ExceptionInfo *exception)
1784 register const Quantum
1790 register unsigned short
1799 q=(unsigned short *) pixels;
1800 if (LocaleCompare(map,"BGR") == 0)
1802 for (y=0; y < (ssize_t) roi->height; y++)
1804 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1805 if (p == (const Quantum *) NULL)
1807 for (x=0; x < (ssize_t) roi->width; x++)
1809 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1810 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1811 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1812 p+=GetPixelChannels(image);
1817 if (LocaleCompare(map,"BGRA") == 0)
1819 for (y=0; y < (ssize_t) roi->height; y++)
1821 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1822 if (p == (const Quantum *) NULL)
1824 for (x=0; x < (ssize_t) roi->width; x++)
1826 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1827 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1828 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1829 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1830 p+=GetPixelChannels(image);
1835 if (LocaleCompare(map,"BGRP") == 0)
1837 for (y=0; y < (ssize_t) roi->height; y++)
1839 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1840 if (p == (const Quantum *) NULL)
1842 for (x=0; x < (ssize_t) roi->width; x++)
1844 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1845 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1846 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1848 p+=GetPixelChannels(image);
1853 if (LocaleCompare(map,"I") == 0)
1855 for (y=0; y < (ssize_t) roi->height; y++)
1857 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1858 if (p == (const Quantum *) NULL)
1860 for (x=0; x < (ssize_t) roi->width; x++)
1862 *q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1863 p+=GetPixelChannels(image);
1868 if (LocaleCompare(map,"RGB") == 0)
1870 for (y=0; y < (ssize_t) roi->height; y++)
1872 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1873 if (p == (const Quantum *) NULL)
1875 for (x=0; x < (ssize_t) roi->width; x++)
1877 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1878 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1879 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1880 p+=GetPixelChannels(image);
1885 if (LocaleCompare(map,"RGBA") == 0)
1887 for (y=0; y < (ssize_t) roi->height; y++)
1889 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1890 if (p == (const Quantum *) NULL)
1892 for (x=0; x < (ssize_t) roi->width; x++)
1894 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1895 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1896 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1897 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1898 p+=GetPixelChannels(image);
1903 if (LocaleCompare(map,"RGBP") == 0)
1905 for (y=0; y < (ssize_t) roi->height; y++)
1907 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1908 if (p == (const Quantum *) NULL)
1910 for (x=0; x < (ssize_t) roi->width; x++)
1912 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1913 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1914 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1916 p+=GetPixelChannels(image);
1922 for (y=0; y < (ssize_t) roi->height; y++)
1924 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1925 if (p == (const Quantum *) NULL)
1927 for (x=0; x < (ssize_t) roi->width; x++)
1932 for (i=0; i < (ssize_t) length; i++)
1935 switch (quantum_map[i])
1940 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1944 case MagentaQuantum:
1946 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1952 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1957 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1960 case OpacityQuantum:
1962 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1967 if (image->colorspace == CMYKColorspace)
1968 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1973 *q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1981 p+=GetPixelChannels(image);
1986 MagickExport MagickBooleanType ExportImagePixels(Image *image,
1987 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1988 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
2002 assert(image != (Image *) NULL);
2003 assert(image->signature == MagickSignature);
2004 if (image->debug != MagickFalse)
2005 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2007 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
2008 if (quantum_map == (QuantumType *) NULL)
2010 (void) ThrowMagickException(exception,GetMagickModule(),
2011 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
2012 return(MagickFalse);
2014 for (i=0; i < (ssize_t) length; i++)
2021 quantum_map[i]=AlphaQuantum;
2027 quantum_map[i]=BlueQuantum;
2033 quantum_map[i]=CyanQuantum;
2034 if (image->colorspace == CMYKColorspace)
2036 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2037 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2038 "ColorSeparatedImageRequired","`%s'",map);
2039 return(MagickFalse);
2044 quantum_map[i]=GreenQuantum;
2050 quantum_map[i]=IndexQuantum;
2056 quantum_map[i]=BlackQuantum;
2057 if (image->colorspace == CMYKColorspace)
2059 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2060 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2061 "ColorSeparatedImageRequired","`%s'",map);
2062 return(MagickFalse);
2067 quantum_map[i]=MagentaQuantum;
2068 if (image->colorspace == CMYKColorspace)
2070 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2071 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2072 "ColorSeparatedImageRequired","`%s'",map);
2073 return(MagickFalse);
2078 quantum_map[i]=OpacityQuantum;
2084 quantum_map[i]=UndefinedQuantum;
2090 quantum_map[i]=RedQuantum;
2096 quantum_map[i]=YellowQuantum;
2097 if (image->colorspace == CMYKColorspace)
2099 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2100 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2101 "ColorSeparatedImageRequired","`%s'",map);
2102 return(MagickFalse);
2106 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2107 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2108 "UnrecognizedPixelMap","`%s'",map);
2109 return(MagickFalse);
2121 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
2126 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
2131 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
2136 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
2141 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
2146 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
2151 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
2156 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2157 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2158 "UnrecognizedPixelMap","`%s'",map);
2162 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2171 % G e t P i x e l I n f o %
2175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2177 % GetPixelInfo() initializes the PixelInfo structure.
2179 % The format of the GetPixelInfo method is:
2181 % GetPixelInfo(const Image *image,PixelInfo *pixel)
2183 % A description of each parameter follows:
2185 % o image: the image.
2187 % o pixel: Specifies a pointer to a PixelInfo structure.
2190 MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
2192 pixel->storage_class=DirectClass;
2193 pixel->colorspace=sRGBColorspace;
2194 pixel->alpha_trait=UndefinedPixelTrait;
2196 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2201 pixel->alpha=(double) OpaqueAlpha;
2203 if (image == (const Image *) NULL)
2205 pixel->storage_class=image->storage_class;
2206 pixel->colorspace=image->colorspace;
2207 pixel->alpha_trait=image->alpha_trait;
2208 pixel->depth=image->depth;
2209 pixel->fuzz=image->fuzz;
2213 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2217 % G e t P i x e l I n t e n s i t y %
2221 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2223 % GetPixelIntensity() returns a single sample intensity value from the red,
2224 % green, and blue components of a pixel based on the selected method:
2226 % Rec601Luma 0.298839R' + 0.586811G' + 0.114350B'
2227 % Rec601Luminance 0.298839R + 0.586811G + 0.114350B
2228 % Rec709Luma 0.21260R' + 0.71520G' + 0.07220B'
2229 % Rec709Luminance 0.21260R + 0.71520G + 0.07220B
2230 % Brightness max(R, G, B)
2231 % Lightness (min(R, G, B) + max(R, G, B)) / 2.0
2232 % RMS (R'^2 + G'^2 + B'^2) / 3.0
2233 % Average (R' + G' + B') / 3.0
2235 % The format of the GetPixelIntensity method is:
2237 % MagickRealType GetPixelIntensity(const Image *image,
2238 % const Quantum *pixel)
2240 % A description of each parameter follows:
2242 % o image: the image.
2244 % o pixel: Specifies a pointer to a Quantum structure.
2248 static inline MagickRealType MagickMax(const MagickRealType x,
2249 const MagickRealType y)
2256 static inline MagickRealType MagickMin(const MagickRealType x,
2257 const MagickRealType y)
2264 MagickExport MagickRealType GetPixelIntensity(const Image *restrict image,
2265 const Quantum *restrict pixel)
2273 if (image->colorspace == GRAYColorspace)
2274 return((MagickRealType) GetPixelGray(image,pixel));
2275 red=(MagickRealType) GetPixelRed(image,pixel);
2276 green=(MagickRealType) GetPixelGreen(image,pixel);
2277 blue=(MagickRealType) GetPixelBlue(image,pixel);
2278 switch (image->intensity)
2280 case AveragePixelIntensityMethod:
2282 intensity=(red+green+blue)/3.0;
2285 case BrightnessPixelIntensityMethod:
2287 intensity=MagickMax(MagickMax(red,green),blue);
2290 case LightnessPixelIntensityMethod:
2292 intensity=MagickMin(MagickMin(red,green),blue);
2295 case MSPixelIntensityMethod:
2297 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2298 (3.0*QuantumRange));
2301 case Rec601LumaPixelIntensityMethod:
2303 intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
2306 case Rec601LuminancePixelIntensityMethod:
2309 if (image->colorspace == sRGBColorspace)
2311 red=DecodePixelGamma(red);
2312 green=DecodePixelGamma(green);
2313 blue=DecodePixelGamma(blue);
2315 intensity=0.298839f*red+0.586811f*green+0.114350f*blue;
2318 case Rec709LumaPixelIntensityMethod:
2320 intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
2323 case Rec709LuminancePixelIntensityMethod:
2325 if (image->colorspace == sRGBColorspace)
2327 red=DecodePixelGamma(red);
2328 green=DecodePixelGamma(green);
2329 blue=DecodePixelGamma(blue);
2331 intensity=0.21260f*red+0.71520f*green+0.07220f*blue;
2334 case RMSPixelIntensityMethod:
2336 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2349 % I m p o r t I m a g e P i x e l s %
2353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2355 % ImportImagePixels() accepts pixel data and stores in the image at the
2356 % location you specify. The method returns MagickTrue on success otherwise
2357 % MagickFalse if an error is encountered. The pixel data can be either char,
2358 % Quantum, short int, unsigned int, unsigned long long, float, or double in
2359 % the order specified by map.
2361 % Suppose your want to upload the first scanline of a 640x480 image from
2362 % character data in red-green-blue order:
2364 % ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2366 % The format of the ImportImagePixels method is:
2368 % MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2369 % const ssize_t y,const size_t width,const size_t height,
2370 % const char *map,const StorageType type,const void *pixels,
2371 % ExceptionInfo *exception)
2373 % A description of each parameter follows:
2375 % o image: the image.
2377 % o x,y,width,height: These values define the perimeter
2378 % of a region of pixels you want to define.
2380 % o map: This string reflects the expected ordering of the pixel array.
2381 % It can be any combination or order of R = red, G = green, B = blue,
2382 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2383 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2386 % o type: Define the data type of the pixels. Float and double types are
2387 % normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
2388 % types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
2389 % LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
2390 % QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
2392 % o pixels: This array of values contain the pixel components as defined by
2393 % map and type. You must preallocate this array where the expected
2394 % length varies depending on the values of width, height, map, and type.
2396 % o exception: return any errors or warnings in this structure.
2400 static void ImportCharPixel(Image *image,const RectangleInfo *roi,
2401 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2402 ExceptionInfo *exception)
2404 register const unsigned char
2419 p=(const unsigned char *) pixels;
2420 if (LocaleCompare(map,"BGR") == 0)
2422 for (y=0; y < (ssize_t) roi->height; y++)
2424 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2425 if (q == (Quantum *) NULL)
2427 for (x=0; x < (ssize_t) roi->width; x++)
2429 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2430 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2431 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2432 q+=GetPixelChannels(image);
2434 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2439 if (LocaleCompare(map,"BGRA") == 0)
2441 for (y=0; y < (ssize_t) roi->height; y++)
2443 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2444 if (q == (Quantum *) NULL)
2446 for (x=0; x < (ssize_t) roi->width; x++)
2448 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2449 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2450 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2451 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2452 q+=GetPixelChannels(image);
2454 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2459 if (LocaleCompare(map,"BGRO") == 0)
2461 for (y=0; y < (ssize_t) roi->height; y++)
2463 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2464 if (q == (Quantum *) NULL)
2466 for (x=0; x < (ssize_t) roi->width; x++)
2468 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2469 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2470 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2471 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2472 q+=GetPixelChannels(image);
2474 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2479 if (LocaleCompare(map,"BGRP") == 0)
2481 for (y=0; y < (ssize_t) roi->height; y++)
2483 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2484 if (q == (Quantum *) NULL)
2486 for (x=0; x < (ssize_t) roi->width; x++)
2488 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2489 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2490 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2492 q+=GetPixelChannels(image);
2494 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2499 if (LocaleCompare(map,"I") == 0)
2501 for (y=0; y < (ssize_t) roi->height; y++)
2503 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2504 if (q == (Quantum *) NULL)
2506 for (x=0; x < (ssize_t) roi->width; x++)
2508 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2509 q+=GetPixelChannels(image);
2511 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2516 if (LocaleCompare(map,"RGB") == 0)
2518 for (y=0; y < (ssize_t) roi->height; y++)
2520 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2521 if (q == (Quantum *) NULL)
2523 for (x=0; x < (ssize_t) roi->width; x++)
2525 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2526 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2527 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2528 q+=GetPixelChannels(image);
2530 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2535 if (LocaleCompare(map,"RGBA") == 0)
2537 for (y=0; y < (ssize_t) roi->height; y++)
2539 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2540 if (q == (Quantum *) NULL)
2542 for (x=0; x < (ssize_t) roi->width; x++)
2544 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2545 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2546 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2547 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2548 q+=GetPixelChannels(image);
2550 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2555 if (LocaleCompare(map,"RGBO") == 0)
2557 for (y=0; y < (ssize_t) roi->height; y++)
2559 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2560 if (q == (Quantum *) NULL)
2562 for (x=0; x < (ssize_t) roi->width; x++)
2564 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2565 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2566 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2567 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2568 q+=GetPixelChannels(image);
2570 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2575 if (LocaleCompare(map,"RGBP") == 0)
2577 for (y=0; y < (ssize_t) roi->height; y++)
2579 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2580 if (q == (Quantum *) NULL)
2582 for (x=0; x < (ssize_t) roi->width; x++)
2584 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2585 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2586 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2588 q+=GetPixelChannels(image);
2590 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2596 for (y=0; y < (ssize_t) roi->height; y++)
2598 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2599 if (q == (Quantum *) NULL)
2601 for (x=0; x < (ssize_t) roi->width; x++)
2606 for (i=0; i < (ssize_t) length; i++)
2608 switch (quantum_map[i])
2613 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2617 case MagentaQuantum:
2619 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2625 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2630 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2633 case OpacityQuantum:
2635 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2640 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2645 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2653 q+=GetPixelChannels(image);
2655 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2660 static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
2661 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2662 ExceptionInfo *exception)
2664 register const double
2679 p=(const double *) pixels;
2680 if (LocaleCompare(map,"BGR") == 0)
2682 for (y=0; y < (ssize_t) roi->height; y++)
2684 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2685 if (q == (Quantum *) NULL)
2687 for (x=0; x < (ssize_t) roi->width; x++)
2689 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2691 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2693 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2695 q+=GetPixelChannels(image);
2697 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2702 if (LocaleCompare(map,"BGRA") == 0)
2704 for (y=0; y < (ssize_t) roi->height; y++)
2706 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2707 if (q == (Quantum *) NULL)
2709 for (x=0; x < (ssize_t) roi->width; x++)
2711 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2713 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2715 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2717 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2719 q+=GetPixelChannels(image);
2721 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2726 if (LocaleCompare(map,"BGRP") == 0)
2728 for (y=0; y < (ssize_t) roi->height; y++)
2730 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2731 if (q == (Quantum *) NULL)
2733 for (x=0; x < (ssize_t) roi->width; x++)
2735 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2737 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2739 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2742 q+=GetPixelChannels(image);
2744 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2749 if (LocaleCompare(map,"I") == 0)
2751 for (y=0; y < (ssize_t) roi->height; y++)
2753 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2754 if (q == (Quantum *) NULL)
2756 for (x=0; x < (ssize_t) roi->width; x++)
2758 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
2760 q+=GetPixelChannels(image);
2762 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2767 if (LocaleCompare(map,"RGB") == 0)
2769 for (y=0; y < (ssize_t) roi->height; y++)
2771 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2772 if (q == (Quantum *) NULL)
2774 for (x=0; x < (ssize_t) roi->width; x++)
2776 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2778 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2780 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2782 q+=GetPixelChannels(image);
2784 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2789 if (LocaleCompare(map,"RGBA") == 0)
2791 for (y=0; y < (ssize_t) roi->height; y++)
2793 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2794 if (q == (Quantum *) NULL)
2796 for (x=0; x < (ssize_t) roi->width; x++)
2798 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2800 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2802 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2804 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2806 q+=GetPixelChannels(image);
2808 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2813 if (LocaleCompare(map,"RGBP") == 0)
2815 for (y=0; y < (ssize_t) roi->height; y++)
2817 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2818 if (q == (Quantum *) NULL)
2820 for (x=0; x < (ssize_t) roi->width; x++)
2822 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2824 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2826 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2828 q+=GetPixelChannels(image);
2830 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2836 for (y=0; y < (ssize_t) roi->height; y++)
2838 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2839 if (q == (Quantum *) NULL)
2841 for (x=0; x < (ssize_t) roi->width; x++)
2846 for (i=0; i < (ssize_t) length; i++)
2848 switch (quantum_map[i])
2853 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2857 case MagentaQuantum:
2859 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2865 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2870 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2873 case OpacityQuantum:
2875 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2880 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
2885 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
2893 q+=GetPixelChannels(image);
2895 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2900 static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
2901 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
2902 ExceptionInfo *exception)
2904 register const float
2919 p=(const float *) pixels;
2920 if (LocaleCompare(map,"BGR") == 0)
2922 for (y=0; y < (ssize_t) roi->height; y++)
2924 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2925 if (q == (Quantum *) NULL)
2927 for (x=0; x < (ssize_t) roi->width; x++)
2929 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2931 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2933 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2935 q+=GetPixelChannels(image);
2937 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2942 if (LocaleCompare(map,"BGRA") == 0)
2944 for (y=0; y < (ssize_t) roi->height; y++)
2946 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2947 if (q == (Quantum *) NULL)
2949 for (x=0; x < (ssize_t) roi->width; x++)
2951 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2953 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2955 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2957 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2959 q+=GetPixelChannels(image);
2961 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2966 if (LocaleCompare(map,"BGRP") == 0)
2968 for (y=0; y < (ssize_t) roi->height; y++)
2970 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2971 if (q == (Quantum *) NULL)
2973 for (x=0; x < (ssize_t) roi->width; x++)
2975 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2977 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2979 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2982 q+=GetPixelChannels(image);
2984 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2989 if (LocaleCompare(map,"I") == 0)
2991 for (y=0; y < (ssize_t) roi->height; y++)
2993 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2994 if (q == (Quantum *) NULL)
2996 for (x=0; x < (ssize_t) roi->width; x++)
2998 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
3000 q+=GetPixelChannels(image);
3002 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3007 if (LocaleCompare(map,"RGB") == 0)
3009 for (y=0; y < (ssize_t) roi->height; y++)
3011 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3012 if (q == (Quantum *) NULL)
3014 for (x=0; x < (ssize_t) roi->width; x++)
3016 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3018 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3020 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3022 q+=GetPixelChannels(image);
3024 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3029 if (LocaleCompare(map,"RGBA") == 0)
3031 for (y=0; y < (ssize_t) roi->height; y++)
3033 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3034 if (q == (Quantum *) NULL)
3036 for (x=0; x < (ssize_t) roi->width; x++)
3038 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3040 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3042 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3044 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3046 q+=GetPixelChannels(image);
3048 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3053 if (LocaleCompare(map,"RGBP") == 0)
3055 for (y=0; y < (ssize_t) roi->height; y++)
3057 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3058 if (q == (Quantum *) NULL)
3060 for (x=0; x < (ssize_t) roi->width; x++)
3062 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3064 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3066 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3068 q+=GetPixelChannels(image);
3070 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3076 for (y=0; y < (ssize_t) roi->height; y++)
3078 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3079 if (q == (Quantum *) NULL)
3081 for (x=0; x < (ssize_t) roi->width; x++)
3086 for (i=0; i < (ssize_t) length; i++)
3088 switch (quantum_map[i])
3093 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3097 case MagentaQuantum:
3099 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3105 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3110 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3113 case OpacityQuantum:
3115 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3120 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
3125 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
3133 q+=GetPixelChannels(image);
3135 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3140 static void ImportLongPixel(Image *image,const RectangleInfo *roi,
3141 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3142 ExceptionInfo *exception)
3144 register const unsigned int
3159 p=(const unsigned int *) pixels;
3160 if (LocaleCompare(map,"BGR") == 0)
3162 for (y=0; y < (ssize_t) roi->height; y++)
3164 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3165 if (q == (Quantum *) NULL)
3167 for (x=0; x < (ssize_t) roi->width; x++)
3169 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3170 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3171 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3172 q+=GetPixelChannels(image);
3174 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3179 if (LocaleCompare(map,"BGRA") == 0)
3181 for (y=0; y < (ssize_t) roi->height; y++)
3183 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3184 if (q == (Quantum *) NULL)
3186 for (x=0; x < (ssize_t) roi->width; x++)
3188 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3189 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3190 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3191 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3192 q+=GetPixelChannels(image);
3194 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3199 if (LocaleCompare(map,"BGRP") == 0)
3201 for (y=0; y < (ssize_t) roi->height; y++)
3203 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3204 if (q == (Quantum *) NULL)
3206 for (x=0; x < (ssize_t) roi->width; x++)
3208 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3209 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3210 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3212 q+=GetPixelChannels(image);
3214 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3219 if (LocaleCompare(map,"I") == 0)
3221 for (y=0; y < (ssize_t) roi->height; y++)
3223 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3224 if (q == (Quantum *) NULL)
3226 for (x=0; x < (ssize_t) roi->width; x++)
3228 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
3229 q+=GetPixelChannels(image);
3231 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3236 if (LocaleCompare(map,"RGB") == 0)
3238 for (y=0; y < (ssize_t) roi->height; y++)
3240 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3241 if (q == (Quantum *) NULL)
3243 for (x=0; x < (ssize_t) roi->width; x++)
3245 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3246 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3247 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3248 q+=GetPixelChannels(image);
3250 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3255 if (LocaleCompare(map,"RGBA") == 0)
3257 for (y=0; y < (ssize_t) roi->height; y++)
3259 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3260 if (q == (Quantum *) NULL)
3262 for (x=0; x < (ssize_t) roi->width; x++)
3264 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3265 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3266 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3267 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3268 q+=GetPixelChannels(image);
3270 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3275 if (LocaleCompare(map,"RGBP") == 0)
3277 for (y=0; y < (ssize_t) roi->height; y++)
3279 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3280 if (q == (Quantum *) NULL)
3282 for (x=0; x < (ssize_t) roi->width; x++)
3284 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3285 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3286 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3288 q+=GetPixelChannels(image);
3290 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3296 for (y=0; y < (ssize_t) roi->height; y++)
3298 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3299 if (q == (Quantum *) NULL)
3301 for (x=0; x < (ssize_t) roi->width; x++)
3306 for (i=0; i < (ssize_t) length; i++)
3308 switch (quantum_map[i])
3313 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3317 case MagentaQuantum:
3319 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3325 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3330 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3333 case OpacityQuantum:
3335 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3340 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3345 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3353 q+=GetPixelChannels(image);
3355 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3360 static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
3361 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3362 ExceptionInfo *exception)
3364 register const MagickSizeType
3379 p=(const MagickSizeType *) pixels;
3380 if (LocaleCompare(map,"BGR") == 0)
3382 for (y=0; y < (ssize_t) roi->height; y++)
3384 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3385 if (q == (Quantum *) NULL)
3387 for (x=0; x < (ssize_t) roi->width; x++)
3389 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3390 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3391 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3392 q+=GetPixelChannels(image);
3394 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3399 if (LocaleCompare(map,"BGRA") == 0)
3401 for (y=0; y < (ssize_t) roi->height; y++)
3403 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3404 if (q == (Quantum *) NULL)
3406 for (x=0; x < (ssize_t) roi->width; x++)
3408 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3409 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3410 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3411 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3412 q+=GetPixelChannels(image);
3414 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3419 if (LocaleCompare(map,"BGRP") == 0)
3421 for (y=0; y < (ssize_t) roi->height; y++)
3423 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3424 if (q == (Quantum *) NULL)
3426 for (x=0; x < (ssize_t) roi->width; x++)
3428 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3429 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3430 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3432 q+=GetPixelChannels(image);
3434 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3439 if (LocaleCompare(map,"I") == 0)
3441 for (y=0; y < (ssize_t) roi->height; y++)
3443 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3444 if (q == (Quantum *) NULL)
3446 for (x=0; x < (ssize_t) roi->width; x++)
3448 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
3449 q+=GetPixelChannels(image);
3451 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3456 if (LocaleCompare(map,"RGB") == 0)
3458 for (y=0; y < (ssize_t) roi->height; y++)
3460 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3461 if (q == (Quantum *) NULL)
3463 for (x=0; x < (ssize_t) roi->width; x++)
3465 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3466 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3467 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3468 q+=GetPixelChannels(image);
3470 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3475 if (LocaleCompare(map,"RGBA") == 0)
3477 for (y=0; y < (ssize_t) roi->height; y++)
3479 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3480 if (q == (Quantum *) NULL)
3482 for (x=0; x < (ssize_t) roi->width; x++)
3484 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3485 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3486 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3487 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3488 q+=GetPixelChannels(image);
3490 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3495 if (LocaleCompare(map,"RGBP") == 0)
3497 for (y=0; y < (ssize_t) roi->height; y++)
3499 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3500 if (q == (Quantum *) NULL)
3502 for (x=0; x < (ssize_t) roi->width; x++)
3504 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3505 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3506 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3508 q+=GetPixelChannels(image);
3510 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3516 for (y=0; y < (ssize_t) roi->height; y++)
3518 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3519 if (q == (Quantum *) NULL)
3521 for (x=0; x < (ssize_t) roi->width; x++)
3526 for (i=0; i < (ssize_t) length; i++)
3528 switch (quantum_map[i])
3533 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
3537 case MagentaQuantum:
3539 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
3545 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
3550 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3553 case OpacityQuantum:
3555 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3560 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
3565 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
3573 q+=GetPixelChannels(image);
3575 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3580 static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
3581 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3582 ExceptionInfo *exception)
3584 register const Quantum
3599 p=(const Quantum *) pixels;
3600 if (LocaleCompare(map,"BGR") == 0)
3602 for (y=0; y < (ssize_t) roi->height; y++)
3604 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3605 if (q == (Quantum *) NULL)
3607 for (x=0; x < (ssize_t) roi->width; x++)
3609 SetPixelBlue(image,*p++,q);
3610 SetPixelGreen(image,*p++,q);
3611 SetPixelRed(image,*p++,q);
3612 q+=GetPixelChannels(image);
3614 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3619 if (LocaleCompare(map,"BGRA") == 0)
3621 for (y=0; y < (ssize_t) roi->height; y++)
3623 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3624 if (q == (Quantum *) NULL)
3626 for (x=0; x < (ssize_t) roi->width; x++)
3628 SetPixelBlue(image,*p++,q);
3629 SetPixelGreen(image,*p++,q);
3630 SetPixelRed(image,*p++,q);
3631 SetPixelAlpha(image,*p++,q);
3632 q+=GetPixelChannels(image);
3634 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3639 if (LocaleCompare(map,"BGRP") == 0)
3641 for (y=0; y < (ssize_t) roi->height; y++)
3643 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3644 if (q == (Quantum *) NULL)
3646 for (x=0; x < (ssize_t) roi->width; x++)
3648 SetPixelBlue(image,*p++,q);
3649 SetPixelGreen(image,*p++,q);
3650 SetPixelRed(image,*p++,q);
3652 q+=GetPixelChannels(image);
3654 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3659 if (LocaleCompare(map,"I") == 0)
3661 for (y=0; y < (ssize_t) roi->height; y++)
3663 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3664 if (q == (Quantum *) NULL)
3666 for (x=0; x < (ssize_t) roi->width; x++)
3668 SetPixelGray(image,*p++,q);
3669 q+=GetPixelChannels(image);
3671 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3676 if (LocaleCompare(map,"RGB") == 0)
3678 for (y=0; y < (ssize_t) roi->height; y++)
3680 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3681 if (q == (Quantum *) NULL)
3683 for (x=0; x < (ssize_t) roi->width; x++)
3685 SetPixelRed(image,*p++,q);
3686 SetPixelGreen(image,*p++,q);
3687 SetPixelBlue(image,*p++,q);
3688 q+=GetPixelChannels(image);
3690 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3695 if (LocaleCompare(map,"RGBA") == 0)
3697 for (y=0; y < (ssize_t) roi->height; y++)
3699 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3700 if (q == (Quantum *) NULL)
3702 for (x=0; x < (ssize_t) roi->width; x++)
3704 SetPixelRed(image,*p++,q);
3705 SetPixelGreen(image,*p++,q);
3706 SetPixelBlue(image,*p++,q);
3707 SetPixelAlpha(image,*p++,q);
3708 q+=GetPixelChannels(image);
3710 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3715 if (LocaleCompare(map,"RGBP") == 0)
3717 for (y=0; y < (ssize_t) roi->height; y++)
3719 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3720 if (q == (Quantum *) NULL)
3722 for (x=0; x < (ssize_t) roi->width; x++)
3724 SetPixelRed(image,*p++,q);
3725 SetPixelGreen(image,*p++,q);
3726 SetPixelBlue(image,*p++,q);
3728 q+=GetPixelChannels(image);
3730 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3736 for (y=0; y < (ssize_t) roi->height; y++)
3738 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3739 if (q == (Quantum *) NULL)
3741 for (x=0; x < (ssize_t) roi->width; x++)
3746 for (i=0; i < (ssize_t) length; i++)
3748 switch (quantum_map[i])
3753 SetPixelRed(image,*p,q);
3757 case MagentaQuantum:
3759 SetPixelGreen(image,*p,q);
3765 SetPixelBlue(image,*p,q);
3770 SetPixelAlpha(image,*p,q);
3773 case OpacityQuantum:
3775 SetPixelAlpha(image,*p,q);
3780 SetPixelBlack(image,*p,q);
3785 SetPixelGray(image,*p,q);
3793 q+=GetPixelChannels(image);
3795 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3800 static void ImportShortPixel(Image *image,const RectangleInfo *roi,
3801 const char *restrict map,const QuantumType *quantum_map,const void *pixels,
3802 ExceptionInfo *exception)
3804 register const unsigned short
3819 p=(const unsigned short *) pixels;
3820 if (LocaleCompare(map,"BGR") == 0)
3822 for (y=0; y < (ssize_t) roi->height; y++)
3824 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3825 if (q == (Quantum *) NULL)
3827 for (x=0; x < (ssize_t) roi->width; x++)
3829 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3830 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3831 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3832 q+=GetPixelChannels(image);
3834 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3839 if (LocaleCompare(map,"BGRA") == 0)
3841 for (y=0; y < (ssize_t) roi->height; y++)
3843 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3844 if (q == (Quantum *) NULL)
3846 for (x=0; x < (ssize_t) roi->width; x++)
3848 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3849 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3850 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3851 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3852 q+=GetPixelChannels(image);
3854 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3859 if (LocaleCompare(map,"BGRP") == 0)
3861 for (y=0; y < (ssize_t) roi->height; y++)
3863 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3864 if (q == (Quantum *) NULL)
3866 for (x=0; x < (ssize_t) roi->width; x++)
3868 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3869 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3870 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3872 q+=GetPixelChannels(image);
3874 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3879 if (LocaleCompare(map,"I") == 0)
3881 for (y=0; y < (ssize_t) roi->height; y++)
3883 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3884 if (q == (Quantum *) NULL)
3886 for (x=0; x < (ssize_t) roi->width; x++)
3888 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3889 q+=GetPixelChannels(image);
3891 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3896 if (LocaleCompare(map,"RGB") == 0)
3898 for (y=0; y < (ssize_t) roi->height; y++)
3900 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3901 if (q == (Quantum *) NULL)
3903 for (x=0; x < (ssize_t) roi->width; x++)
3905 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3906 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3907 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3908 q+=GetPixelChannels(image);
3910 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3915 if (LocaleCompare(map,"RGBA") == 0)
3917 for (y=0; y < (ssize_t) roi->height; y++)
3919 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3920 if (q == (Quantum *) NULL)
3922 for (x=0; x < (ssize_t) roi->width; x++)
3924 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3925 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3926 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3927 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3928 q+=GetPixelChannels(image);
3930 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3935 if (LocaleCompare(map,"RGBP") == 0)
3937 for (y=0; y < (ssize_t) roi->height; y++)
3939 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3940 if (q == (Quantum *) NULL)
3942 for (x=0; x < (ssize_t) roi->width; x++)
3944 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3945 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3946 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3948 q+=GetPixelChannels(image);
3950 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3956 for (y=0; y < (ssize_t) roi->height; y++)
3958 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3959 if (q == (Quantum *) NULL)
3961 for (x=0; x < (ssize_t) roi->width; x++)
3966 for (i=0; i < (ssize_t) length; i++)
3968 switch (quantum_map[i])
3973 SetPixelRed(image,ScaleShortToQuantum(*p),q);
3977 case MagentaQuantum:
3979 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
3985 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
3990 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
3993 case OpacityQuantum:
3995 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
4000 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
4005 SetPixelGray(image,ScaleShortToQuantum(*p),q);
4013 q+=GetPixelChannels(image);
4015 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4020 MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
4021 const ssize_t y,const size_t width,const size_t height,const char *map,
4022 const StorageType type,const void *pixels,ExceptionInfo *exception)
4037 Allocate image structure.
4039 assert(image != (Image *) NULL);
4040 assert(image->signature == MagickSignature);
4041 if (image->debug != MagickFalse)
4042 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4044 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
4045 if (quantum_map == (QuantumType *) NULL)
4046 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4048 for (i=0; i < (ssize_t) length; i++)
4055 quantum_map[i]=AlphaQuantum;
4056 image->alpha_trait=BlendPixelTrait;
4062 quantum_map[i]=BlueQuantum;
4068 quantum_map[i]=CyanQuantum;
4069 (void) SetImageColorspace(image,CMYKColorspace,exception);
4075 quantum_map[i]=GreenQuantum;
4081 quantum_map[i]=BlackQuantum;
4082 (void) SetImageColorspace(image,CMYKColorspace,exception);
4088 quantum_map[i]=IndexQuantum;
4089 (void) SetImageColorspace(image,GRAYColorspace,exception);
4095 quantum_map[i]=MagentaQuantum;
4096 (void) SetImageColorspace(image,CMYKColorspace,exception);
4102 quantum_map[i]=OpacityQuantum;
4103 image->alpha_trait=BlendPixelTrait;
4109 quantum_map[i]=UndefinedQuantum;
4115 quantum_map[i]=RedQuantum;
4121 quantum_map[i]=YellowQuantum;
4122 (void) SetImageColorspace(image,CMYKColorspace,exception);
4127 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4128 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
4129 "UnrecognizedPixelMap","`%s'",map);
4130 return(MagickFalse);
4134 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
4135 return(MagickFalse);
4137 Transfer the pixels from the pixel data to the image.
4147 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
4152 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
4157 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
4162 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
4167 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
4172 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
4177 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
4182 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4183 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
4184 "UnrecognizedPixelMap","`%s'",map);
4188 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4197 + I n i t i a l i z e P i x e l C h a n n e l M a p %
4201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4203 % InitializePixelChannelMap() defines the standard pixel component map.
4205 % The format of the InitializePixelChannelMap() method is:
4207 % void InitializePixelChannelMap(Image *image)
4209 % A description of each parameter follows:
4211 % o image: the image.
4214 MagickExport void InitializePixelChannelMap(Image *image)
4225 assert(image != (Image *) NULL);
4226 assert(image->signature == MagickSignature);
4227 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
4228 sizeof(*image->channel_map));
4229 trait=UpdatePixelTrait;
4230 if (image->alpha_trait == BlendPixelTrait)
4231 trait=(PixelTrait) (trait | BlendPixelTrait);
4233 if (image->colorspace == GRAYColorspace)
4235 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
4236 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
4237 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
4241 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
4242 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
4243 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
4245 if (image->colorspace == CMYKColorspace)
4246 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
4247 if (image->alpha_trait != UndefinedPixelTrait)
4248 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
4249 if (image->storage_class == PseudoClass)
4250 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
4251 if (image->read_mask != MagickFalse)
4252 SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++);
4253 if (image->write_mask != MagickFalse)
4254 SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++);
4255 assert((n+image->number_meta_channels) < MaxPixelChannels);
4256 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
4257 SetPixelChannelAttributes(image,(PixelChannel) (MetaPixelChannel+i),
4258 CopyPixelTrait,n++);
4259 image->number_channels=(size_t) n;
4260 if (image->debug != MagickFalse)
4261 LogPixelChannels(image);
4262 (void) SetImageChannelMask(image,image->channel_mask);
4266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4270 % I n t e r p o l a t e P i x e l C h a n n e l %
4274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4276 % InterpolatePixelChannel() applies a pixel interpolation method between a
4277 % floating point coordinate and the pixels surrounding that coordinate. No
4278 % pixel area resampling, or scaling of the result is performed.
4280 % Interpolation is restricted to just the specified channel.
4282 % The format of the InterpolatePixelChannel method is:
4284 % MagickBooleanType InterpolatePixelChannel(const Image *image,
4285 % const CacheView *image_view,const PixelChannel channel,
4286 % const PixelInterpolateMethod method,const double x,const double y,
4287 % double *pixel,ExceptionInfo *exception)
4289 % A description of each parameter follows:
4291 % o image: the image.
4293 % o image_view: the image view.
4295 % o channel: the pixel channel to interpolate.
4297 % o method: the pixel color interpolation method.
4299 % o x,y: A double representing the current (x,y) position of the pixel.
4301 % o pixel: return the interpolated pixel here.
4303 % o exception: return any errors or warnings in this structure.
4307 static inline void CatromWeights(const double x,double (*weights)[4])
4315 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4316 of the standard four 1D Catmull-Rom weights. The sampling location is
4317 assumed between the second and third input pixel locations, and x is the
4318 position relative to the second input pixel location. Formulas originally
4319 derived for the VIPS (Virtual Image Processing System) library.
4321 alpha=(double) 1.0-x;
4322 beta=(double) (-0.5)*x*alpha;
4323 (*weights)[0]=alpha*beta;
4324 (*weights)[3]=x*beta;
4326 The following computation of the inner weights from the outer ones work
4327 for all Keys cubics.
4329 gamma=(*weights)[3]-(*weights)[0];
4330 (*weights)[1]=alpha-(*weights)[0]+gamma;
4331 (*weights)[2]=x-(*weights)[3]-gamma;
4334 static inline void SplineWeights(const double x,double (*weights)[4])
4341 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the
4342 computation of the standard four 1D cubic B-spline smoothing
4343 weights. The sampling location is assumed between the second and
4344 third input pixel locations, and x is the position relative to the
4345 second input pixel location.
4347 alpha=(double) 1.0-x;
4348 (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4349 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
4350 beta=(*weights)[3]-(*weights)[0];
4351 (*weights)[1]=alpha-(*weights)[0]+beta;
4352 (*weights)[2]=x-(*weights)[3]-beta;
4355 static inline double MeshInterpolate(const PointInfo *delta,const double p,
4356 const double x,const double y)
4358 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4362 static inline ssize_t NearestNeighbor(const double x)
4365 return((ssize_t) (x+0.5));
4366 return((ssize_t) (x-0.5));
4370 MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
4371 const CacheView *image_view,const PixelChannel channel,
4372 const PixelInterpolateMethod method,const double x,const double y,
4373 double *pixel,ExceptionInfo *exception)
4386 register const Quantum
4396 PixelInterpolateMethod
4399 assert(image != (Image *) NULL);
4400 assert(image != (Image *) NULL);
4401 assert(image->signature == MagickSignature);
4402 assert(image_view != (CacheView *) NULL);
4405 traits=GetPixelChannelTraits(image,channel);
4406 x_offset=(ssize_t) floor(x);
4407 y_offset=(ssize_t) floor(y);
4408 interpolate = method;
4409 if ( interpolate == UndefinedInterpolatePixel )
4410 interpolate = image->interpolate;
4411 switch (interpolate)
4413 case AverageInterpolatePixel: /* nearest 4 neighbours */
4414 case Average9InterpolatePixel: /* nearest 9 neighbours */
4415 case Average16InterpolatePixel: /* nearest 16 neighbours */
4420 count=2; /* size of the area to average - default nearest 4 */
4421 if (interpolate == Average9InterpolatePixel)
4424 x_offset=(ssize_t) (floor(x+0.5)-1);
4425 y_offset=(ssize_t) (floor(y+0.5)-1);
4428 if (interpolate == Average16InterpolatePixel)
4434 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,(size_t)
4436 if (p == (const Quantum *) NULL)
4441 count*=count; /* Number of pixels to Average */
4442 if ((traits & BlendPixelTrait) == 0)
4443 for (i=0; i < (ssize_t) count; i++)
4446 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4449 for (i=0; i < (ssize_t) count; i++)
4451 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4452 GetPixelChannels(image));
4453 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4455 for (i=0; i < (ssize_t) count; i++)
4457 gamma=PerceptibleReciprocal(alpha[i])/count;
4458 *pixel+=gamma*pixels[i];
4462 case BilinearInterpolatePixel:
4469 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4470 if (p == (const Quantum *) NULL)
4475 if ((traits & BlendPixelTrait) == 0)
4476 for (i=0; i < 4; i++)
4479 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4482 for (i=0; i < 4; i++)
4484 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4485 GetPixelChannels(image));
4486 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4490 epsilon.x=1.0-delta.x;
4491 epsilon.y=1.0-delta.y;
4492 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4493 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4494 gamma=PerceptibleReciprocal(gamma);
4495 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4496 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4499 case BlendInterpolatePixel:
4501 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4502 if (p == (const Quantum *) NULL)
4507 if ((traits & BlendPixelTrait) == 0)
4508 for (i=0; i < 4; i++)
4511 pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4514 for (i=0; i < 4; i++)
4516 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4517 GetPixelChannels(image));
4518 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4520 gamma=1.0; /* number of pixels blended together (its variable) */
4521 for (i=0; i <= 1L; i++) {
4522 if ((y-y_offset) >= 0.75)
4524 alpha[i]=alpha[i+2]; /* take right pixels */
4525 pixels[i]=pixels[i+2];
4528 if ((y-y_offset) > 0.25)
4530 gamma=2.0; /* blend both pixels in row */
4531 alpha[i]+=alpha[i+2]; /* add up alpha weights */
4532 pixels[i]+=pixels[i+2];
4535 if ((x-x_offset) >= 0.75)
4537 alpha[0]=alpha[1]; /* take bottom row blend */
4538 pixels[0]=pixels[1];
4541 if ((x-x_offset) > 0.25)
4543 gamma*=2.0; /* blend both rows */
4544 alpha[0]+=alpha[1]; /* add up alpha weights */
4545 pixels[0]+=pixels[1];
4547 if (channel != AlphaPixelChannel)
4548 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
4550 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
4551 *pixel=gamma*pixels[0];
4554 case CatromInterpolatePixel:
4560 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4562 if (p == (const Quantum *) NULL)
4567 if ((traits & BlendPixelTrait) == 0)
4568 for (i=0; i < 16; i++)
4571 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4574 for (i=0; i < 16; i++)
4576 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4577 GetPixelChannels(image));
4578 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4580 CatromWeights((double) (x-x_offset),&cx);
4581 CatromWeights((double) (y-y_offset),&cy);
4582 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4583 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4584 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4585 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4586 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4587 cx[2]*alpha[14]+cx[3]*alpha[15])));
4588 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4589 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4590 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4591 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4592 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4596 /* deprecated useless and very slow interpolator */
4597 case FilterInterpolatePixel:
4611 geometry.x=x_offset-1;
4612 geometry.y=y_offset-1;
4613 excerpt_image=ExcerptImage(image,&geometry,exception);
4614 if (excerpt_image == (Image *) NULL)
4619 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
4620 excerpt_image=DestroyImage(excerpt_image);
4621 if (filter_image == (Image *) NULL)
4623 filter_view=AcquireVirtualCacheView(filter_image,exception);
4624 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
4625 if (p == (const Quantum *) NULL)
4628 *pixel=(double) GetPixelChannel(image,channel,p);
4629 filter_view=DestroyCacheView(filter_view);
4630 filter_image=DestroyImage(filter_image);
4634 case IntegerInterpolatePixel:
4636 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4637 if (p == (const Quantum *) NULL)
4642 *pixel=(double) GetPixelChannel(image,channel,p);
4645 case NearestInterpolatePixel:
4647 x_offset=(ssize_t) floor(x+0.5);
4648 y_offset=(ssize_t) floor(y+0.5);
4649 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4650 if (p == (const Quantum *) NULL)
4655 *pixel=(double) GetPixelChannel(image,channel,p);
4658 case MeshInterpolatePixel:
4664 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4665 if (p == (const Quantum *) NULL)
4670 if ((traits & BlendPixelTrait) == 0)
4671 for (i=0; i < 4; i++)
4674 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4677 for (i=0; i < 4; i++)
4679 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4680 GetPixelChannels(image));
4681 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4685 luminance.x=GetPixelLuminance(image,p)-(double)
4686 GetPixelLuminance(image,p+3*GetPixelChannels(image));
4687 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
4688 GetPixelLuminance(image,p+2*GetPixelChannels(image));
4689 if (fabs(luminance.x) < fabs(luminance.y))
4694 if (delta.x <= delta.y)
4697 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4699 delta.y=1.0-delta.y;
4700 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4701 gamma=PerceptibleReciprocal(gamma);
4702 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4708 Top-right triangle (pixel: 1, diagonal: 0-3).
4710 delta.x=1.0-delta.x;
4711 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4712 gamma=PerceptibleReciprocal(gamma);
4713 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4722 if (delta.x <= (1.0-delta.y))
4725 Top-left triangle (pixel: 0, diagonal: 1-2).
4727 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4728 gamma=PerceptibleReciprocal(gamma);
4729 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4735 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4737 delta.x=1.0-delta.x;
4738 delta.y=1.0-delta.y;
4739 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4740 gamma=PerceptibleReciprocal(gamma);
4741 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4747 case SplineInterpolatePixel:
4753 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4755 if (p == (const Quantum *) NULL)
4760 if ((traits & BlendPixelTrait) == 0)
4761 for (i=0; i < 16; i++)
4764 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4767 for (i=0; i < 16; i++)
4769 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4770 GetPixelChannels(image));
4771 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4773 SplineWeights((double) (x-x_offset),&cx);
4774 SplineWeights((double) (y-y_offset),&cy);
4775 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4776 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4777 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4778 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4779 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4780 cx[2]*alpha[14]+cx[3]*alpha[15])));
4781 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4782 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4783 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4784 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4785 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4793 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4797 % I n t e r p o l a t e P i x e l C h a n n e l s %
4801 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4803 % InterpolatePixelChannels() applies a pixel interpolation method between a
4804 % floating point coordinate and the pixels surrounding that coordinate. No
4805 % pixel area resampling, or scaling of the result is performed.
4807 % Interpolation is restricted to just the current channel setting of the
4808 % destination image into which the color is to be stored
4810 % The format of the InterpolatePixelChannels method is:
4812 % MagickBooleanType InterpolatePixelChannels(const Image *source,
4813 % const CacheView *source_view,const Image *destination,
4814 % const PixelInterpolateMethod method,const double x,const double y,
4815 % Quantum *pixel,ExceptionInfo *exception)
4817 % A description of each parameter follows:
4819 % o source: the source.
4821 % o source_view: the source view.
4823 % o destination: the destination image, for the interpolated color
4825 % o method: the pixel color interpolation method.
4827 % o x,y: A double representing the current (x,y) position of the pixel.
4829 % o pixel: return the interpolated pixel here.
4831 % o exception: return any errors or warnings in this structure.
4834 MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
4835 const CacheView *source_view,const Image *destination,
4836 const PixelInterpolateMethod method,const double x,const double y,
4837 Quantum *pixel,ExceptionInfo *exception)
4847 register const Quantum
4857 PixelInterpolateMethod
4860 assert(source != (Image *) NULL);
4861 assert(source != (Image *) NULL);
4862 assert(source->signature == MagickSignature);
4863 assert(source_view != (CacheView *) NULL);
4865 x_offset=(ssize_t) floor(x);
4866 y_offset=(ssize_t) floor(y);
4867 interpolate = method;
4868 if ( interpolate == UndefinedInterpolatePixel )
4869 interpolate = source->interpolate;
4870 switch (interpolate)
4872 case AverageInterpolatePixel: /* nearest 4 neighbours */
4873 case Average9InterpolatePixel: /* nearest 9 neighbours */
4874 case Average16InterpolatePixel: /* nearest 16 neighbours */
4879 count=2; /* size of the area to average - default nearest 4 */
4880 if (interpolate == Average9InterpolatePixel)
4883 x_offset=(ssize_t) (floor(x+0.5)-1);
4884 y_offset=(ssize_t) (floor(y+0.5)-1);
4887 if (interpolate == Average16InterpolatePixel)
4893 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count,
4894 (size_t) count,exception);
4895 if (p == (const Quantum *) NULL)
4900 count*=count; /* Number of pixels to Average */
4901 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4909 PixelChannel channel=GetPixelChannelChannel(source,i);
4910 PixelTrait traits=GetPixelChannelTraits(source,channel);
4911 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4913 if ((traits == UndefinedPixelTrait) ||
4914 (destination_traits == UndefinedPixelTrait))
4916 for (j=0; j < (ssize_t) count; j++)
4917 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
4919 if ((traits & BlendPixelTrait) == 0)
4921 for (j=0; j < (ssize_t) count; j++)
4924 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4927 for (j=0; j < (ssize_t) count; j++)
4929 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4930 GetPixelChannels(source));
4931 pixels[j]*=alpha[j];
4932 gamma=PerceptibleReciprocal(alpha[j]);
4933 sum+=gamma*pixels[j];
4936 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4940 case BilinearInterpolatePixel:
4943 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4944 if (p == (const Quantum *) NULL)
4949 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4955 PixelChannel channel=GetPixelChannelChannel(source,i);
4956 PixelTrait traits=GetPixelChannelTraits(source,channel);
4957 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4959 if ((traits == UndefinedPixelTrait) ||
4960 (destination_traits == UndefinedPixelTrait))
4964 epsilon.x=1.0-delta.x;
4965 epsilon.y=1.0-delta.y;
4966 pixels[0]=(double) p[i];
4967 pixels[1]=(double) p[GetPixelChannels(source)+i];
4968 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
4969 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
4970 if ((traits & BlendPixelTrait) == 0)
4972 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
4973 gamma=PerceptibleReciprocal(gamma);
4974 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4975 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
4976 pixels[2]+delta.x*pixels[3]))),pixel);
4979 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
4980 alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
4981 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
4982 GetPixelChannels(source));
4983 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
4984 GetPixelChannels(source));
4985 pixels[0]*=alpha[0];
4986 pixels[1]*=alpha[1];
4987 pixels[2]*=alpha[2];
4988 pixels[3]*=alpha[3];
4989 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4990 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4991 gamma=PerceptibleReciprocal(gamma);
4992 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
4993 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
4994 delta.x*pixels[3]))),pixel);
4998 case BlendInterpolatePixel:
5000 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5001 if (p == (const Quantum *) NULL)
5006 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5011 PixelChannel channel=GetPixelChannelChannel(source,i);
5012 PixelTrait traits=GetPixelChannelTraits(source,channel);
5013 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5015 if ((traits == UndefinedPixelTrait) ||
5016 (destination_traits == UndefinedPixelTrait))
5018 if ((traits & BlendPixelTrait) == 0)
5019 for (j=0; j < 4; j++)
5022 pixels[j]=(MagickRealType) p[j*GetPixelChannels(source)+channel];
5025 for (j=0; j < 4; j++)
5027 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5028 GetPixelChannels(source));
5029 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+channel];
5031 gamma=1.0; /* number of pixels blended together (its variable) */
5032 for (j=0; j <= 1L; j++)
5034 if ((y-y_offset) >= 0.75)
5036 alpha[j]=alpha[j+2]; /* take right pixels */
5037 pixels[j]=pixels[j+2];
5040 if ((y-y_offset) > 0.25)
5042 gamma=2.0; /* blend both pixels in row */
5043 alpha[j]+=alpha[j+2]; /* add up alpha weights */
5044 pixels[j]+=pixels[j+2];
5047 if ((x-x_offset) >= 0.75)
5049 alpha[0]=alpha[1]; /* take bottom row blend */
5050 pixels[0]=pixels[1];
5053 if ((x-x_offset) > 0.25)
5055 gamma*=2.0; /* blend both rows */
5056 alpha[0]+=alpha[1]; /* add up alpha weights */
5057 pixels[0]+=pixels[1];
5059 if ((traits & BlendPixelTrait) == 0)
5060 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
5062 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
5063 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
5068 case CatromInterpolatePixel:
5074 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5076 if (p == (const Quantum *) NULL)
5081 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5086 PixelChannel channel=GetPixelChannelChannel(source,i);
5087 PixelTrait traits=GetPixelChannelTraits(source,channel);
5088 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5090 if ((traits == UndefinedPixelTrait) ||
5091 (destination_traits == UndefinedPixelTrait))
5093 if ((traits & BlendPixelTrait) == 0)
5094 for (j=0; j < 16; j++)
5097 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5100 for (j=0; j < 16; j++)
5102 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5103 GetPixelChannels(source));
5104 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5106 CatromWeights((double) (x-x_offset),&cx);
5107 CatromWeights((double) (y-y_offset),&cy);
5108 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5109 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5110 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5111 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5112 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5113 cx[2]*alpha[14]+cx[3]*alpha[15])));
5114 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5115 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5116 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5117 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5118 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5119 pixels[14]+cx[3]*pixels[15]))),pixel);
5124 /* deprecated useless and very slow interpolator */
5125 case FilterInterpolatePixel:
5127 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5139 PixelChannel channel=GetPixelChannelChannel(source,i);
5140 PixelTrait traits=GetPixelChannelTraits(source,channel);
5141 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5143 if ((traits == UndefinedPixelTrait) ||
5144 (destination_traits == UndefinedPixelTrait))
5148 geometry.x=x_offset-1;
5149 geometry.y=y_offset-1;
5150 excerpt_source=ExcerptImage(source,&geometry,exception);
5151 if (excerpt_source == (Image *) NULL)
5156 filter_source=ResizeImage(excerpt_source,1,1,source->filter,exception);
5157 excerpt_source=DestroyImage(excerpt_source);
5158 if (filter_source == (Image *) NULL)
5160 filter_view=AcquireVirtualCacheView(filter_source,exception);
5161 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5162 if (p == (const Quantum *) NULL)
5166 SetPixelChannel(destination,channel,p[i],pixel);
5168 filter_view=DestroyCacheView(filter_view);
5169 filter_source=DestroyImage(filter_source);
5174 case IntegerInterpolatePixel:
5176 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5177 if (p == (const Quantum *) NULL)
5182 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5184 PixelChannel channel=GetPixelChannelChannel(source,i);
5185 PixelTrait traits=GetPixelChannelTraits(source,channel);
5186 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5188 if ((traits == UndefinedPixelTrait) ||
5189 (destination_traits == UndefinedPixelTrait))
5191 SetPixelChannel(destination,channel,p[i],pixel);
5195 case NearestInterpolatePixel:
5197 x_offset=(ssize_t) floor(x+0.5);
5198 y_offset=(ssize_t) floor(y+0.5);
5199 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5200 if (p == (const Quantum *) NULL)
5205 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5207 PixelChannel channel=GetPixelChannelChannel(source,i);
5208 PixelTrait traits=GetPixelChannelTraits(source,channel);
5209 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5211 if ((traits == UndefinedPixelTrait) ||
5212 (destination_traits == UndefinedPixelTrait))
5214 SetPixelChannel(destination,channel,p[i],pixel);
5218 case MeshInterpolatePixel:
5220 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5221 if (p == (const Quantum *) NULL)
5226 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5232 PixelChannel channel=GetPixelChannelChannel(source,i);
5233 PixelTrait traits=GetPixelChannelTraits(source,channel);
5234 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5236 if ((traits == UndefinedPixelTrait) ||
5237 (destination_traits == UndefinedPixelTrait))
5239 pixels[0]=(double) p[i];
5240 pixels[1]=(double) p[GetPixelChannels(source)+i];
5241 pixels[2]=(double) p[2*GetPixelChannels(source)+i];
5242 pixels[3]=(double) p[3*GetPixelChannels(source)+i];
5243 if ((traits & BlendPixelTrait) == 0)
5252 alpha[0]=QuantumScale*GetPixelAlpha(source,p);
5253 alpha[1]=QuantumScale*GetPixelAlpha(source,p+
5254 GetPixelChannels(source));
5255 alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
5256 GetPixelChannels(source));
5257 alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
5258 GetPixelChannels(source));
5262 luminance.x=fabs((double) (GetPixelLuminance(source,p)-
5263 GetPixelLuminance(source,p+3*GetPixelChannels(source))));
5264 luminance.y=fabs((double) (GetPixelLuminance(source,p+
5265 GetPixelChannels(source))-GetPixelLuminance(source,p+2*
5266 GetPixelChannels(source))));
5267 if (luminance.x < luminance.y)
5272 if (delta.x <= delta.y)
5275 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5277 delta.y=1.0-delta.y;
5278 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5279 gamma=PerceptibleReciprocal(gamma);
5280 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5281 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
5286 Top-right triangle (pixel: 1, diagonal: 0-3).
5288 delta.x=1.0-delta.x;
5289 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5290 gamma=PerceptibleReciprocal(gamma);
5291 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5292 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
5300 if (delta.x <= (1.0-delta.y))
5303 Top-left triangle (pixel: 0, diagonal: 1-2).
5305 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5306 gamma=PerceptibleReciprocal(gamma);
5307 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5308 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
5313 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5315 delta.x=1.0-delta.x;
5316 delta.y=1.0-delta.y;
5317 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5318 gamma=PerceptibleReciprocal(gamma);
5319 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5320 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
5326 case SplineInterpolatePixel:
5332 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5334 if (p == (const Quantum *) NULL)
5339 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5344 PixelChannel channel=GetPixelChannelChannel(source,i);
5345 PixelTrait traits=GetPixelChannelTraits(source,channel);
5346 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5348 if ((traits == UndefinedPixelTrait) ||
5349 (destination_traits == UndefinedPixelTrait))
5351 if ((traits & BlendPixelTrait) == 0)
5352 for (j=0; j < 16; j++)
5355 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5358 for (j=0; j < 16; j++)
5360 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5361 GetPixelChannels(source));
5362 pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5364 SplineWeights((double) (x-x_offset),&cx);
5365 SplineWeights((double) (y-y_offset),&cy);
5366 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5367 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5368 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5369 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5370 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5371 cx[2]*alpha[14]+cx[3]*alpha[15])));
5372 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5373 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5374 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5375 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5376 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5377 pixels[14]+cx[3]*pixels[15]))),pixel);
5386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5390 % I n t e r p o l a t e P i x e l I n f o %
5394 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5396 % InterpolatePixelInfo() applies a pixel interpolation method between a
5397 % floating point coordinate and the pixels surrounding that coordinate. No
5398 % pixel area resampling, or scaling of the result is performed.
5400 % Interpolation is restricted to just RGBKA channels.
5402 % The format of the InterpolatePixelInfo method is:
5404 % MagickBooleanType InterpolatePixelInfo(const Image *image,
5405 % const CacheView *image_view,const PixelInterpolateMethod method,
5406 % const double x,const double y,PixelInfo *pixel,
5407 % ExceptionInfo *exception)
5409 % A description of each parameter follows:
5411 % o image: the image.
5413 % o image_view: the image view.
5415 % o method: the pixel color interpolation method.
5417 % o x,y: A double representing the current (x,y) position of the pixel.
5419 % o pixel: return the interpolated pixel here.
5421 % o exception: return any errors or warnings in this structure.
5425 static inline void AlphaBlendPixelInfo(const Image *image,
5426 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
5428 if (image->alpha_trait != BlendPixelTrait)
5431 pixel_info->red=(double) GetPixelRed(image,pixel);
5432 pixel_info->green=(double) GetPixelGreen(image,pixel);
5433 pixel_info->blue=(double) GetPixelBlue(image,pixel);
5434 pixel_info->black=0.0;
5435 if (image->colorspace == CMYKColorspace)
5436 pixel_info->black=(double) GetPixelBlack(image,pixel);
5437 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5440 *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5441 pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5442 pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5443 pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5444 pixel_info->black=0.0;
5445 if (image->colorspace == CMYKColorspace)
5446 pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
5447 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5450 MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
5451 const CacheView *image_view,const PixelInterpolateMethod method,
5452 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5464 register const Quantum
5474 PixelInterpolateMethod
5477 assert(image != (Image *) NULL);
5478 assert(image->signature == MagickSignature);
5479 assert(image_view != (CacheView *) NULL);
5481 x_offset=(ssize_t) floor(x);
5482 y_offset=(ssize_t) floor(y);
5483 interpolate = method;
5484 if ( interpolate == UndefinedInterpolatePixel )
5485 interpolate = image->interpolate;
5486 switch (interpolate)
5488 case AverageInterpolatePixel: /* nearest 4 neighbours */
5489 case Average9InterpolatePixel: /* nearest 9 neighbours */
5490 case Average16InterpolatePixel: /* nearest 16 neighbours */
5495 count=2; /* size of the area to average - default nearest 4 */
5496 if (interpolate == Average9InterpolatePixel)
5499 x_offset=(ssize_t) (floor(x+0.5)-1);
5500 y_offset=(ssize_t) (floor(y+0.5)-1);
5502 else if (interpolate == Average16InterpolatePixel)
5508 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,(size_t)
5510 if (p == (const Quantum *) NULL)
5520 count*=count; /* number of pixels - square of size */
5521 for (i=0; i < (ssize_t) count; i++)
5523 AlphaBlendPixelInfo(image,p,pixels,alpha);
5524 gamma=PerceptibleReciprocal(alpha[0]);
5525 pixel->red+=gamma*pixels[0].red;
5526 pixel->green+=gamma*pixels[0].green;
5527 pixel->blue+=gamma*pixels[0].blue;
5528 pixel->black+=gamma*pixels[0].black;
5529 pixel->alpha+=pixels[0].alpha;
5530 p += GetPixelChannels(image);
5532 gamma=1.0/count; /* average weighting of each pixel in area */
5534 pixel->green*=gamma;
5536 pixel->black*=gamma;
5537 pixel->alpha*=gamma;
5540 case BackgroundInterpolatePixel:
5542 *pixel=image->background_color; /* Copy PixelInfo Structure */
5545 case BilinearInterpolatePixel:
5552 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5553 if (p == (const Quantum *) NULL)
5558 for (i=0; i < 4L; i++)
5559 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5562 epsilon.x=1.0-delta.x;
5563 epsilon.y=1.0-delta.y;
5564 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5565 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5566 gamma=PerceptibleReciprocal(gamma);
5567 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5568 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5569 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5570 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5572 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5573 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5575 if (image->colorspace == CMYKColorspace)
5576 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5577 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5579 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5580 gamma=PerceptibleReciprocal(gamma);
5581 pixel->alpha=(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5582 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5586 case BlendInterpolatePixel:
5588 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5589 if (p == (const Quantum *) NULL)
5594 for (i=0; i < 4L; i++)
5595 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5596 gamma=1.0; /* number of pixels blended together (its variable) */
5597 for (i=0; i <= 1L; i++)
5599 if ((y-y_offset) >= 0.75)
5601 alpha[i]=alpha[i+2]; /* take right pixels */
5602 pixels[i]=pixels[i+2];
5605 if ((y-y_offset) > 0.25)
5607 gamma=2.0; /* blend both pixels in row */
5608 alpha[i]+=alpha[i+2]; /* add up alpha weights */
5609 pixels[i].red+=pixels[i+2].red;
5610 pixels[i].green+=pixels[i+2].green;
5611 pixels[i].blue+=pixels[i+2].blue;
5612 pixels[i].black+=pixels[i+2].black;
5613 pixels[i].alpha+=pixels[i+2].alpha;
5616 if ((x-x_offset) >= 0.75)
5619 pixels[0]=pixels[1];
5622 if ((x-x_offset) > 0.25)
5624 gamma*=2.0; /* blend both rows */
5625 alpha[0]+= alpha[1]; /* add up alpha weights */
5626 pixels[0].red+=pixels[1].red;
5627 pixels[0].green+=pixels[1].green;
5628 pixels[0].blue+=pixels[1].blue;
5629 pixels[0].black+=pixels[1].black;
5630 pixels[0].alpha+=pixels[1].alpha;
5633 alpha[0]=PerceptibleReciprocal(alpha[0]);
5634 pixel->red=alpha[0]*pixels[0].red;
5635 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5636 pixel->blue=alpha[0]*pixels[0].blue;
5637 pixel->black=alpha[0]*pixels[0].black;
5638 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
5641 case CatromInterpolatePixel:
5647 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5649 if (p == (const Quantum *) NULL)
5654 for (i=0; i < 16L; i++)
5655 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5656 CatromWeights((double) (x-x_offset),&cx);
5657 CatromWeights((double) (y-y_offset),&cy);
5658 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5659 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5660 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5661 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5662 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5663 pixels[14].red+cx[3]*pixels[15].red));
5664 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5665 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5666 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5667 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5668 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5669 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5671 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5672 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5673 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5674 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5675 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5676 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5677 if (image->colorspace == CMYKColorspace)
5678 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5679 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5680 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5681 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5682 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5683 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5685 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5686 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5687 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5688 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5689 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5690 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5694 /* deprecated useless and very slow interpolator */
5695 case FilterInterpolatePixel:
5709 geometry.x=x_offset-1;
5710 geometry.y=y_offset-1;
5711 excerpt_image=ExcerptImage(image,&geometry,exception);
5712 if (excerpt_image == (Image *) NULL)
5717 filter_image=ResizeImage(excerpt_image,1,1,image->filter,exception);
5718 excerpt_image=DestroyImage(excerpt_image);
5719 if (filter_image == (Image *) NULL)
5721 filter_view=AcquireVirtualCacheView(filter_image,exception);
5722 p=GetCacheViewVirtualPixels(filter_view,0,0,1,1,exception);
5723 if (p != (const Quantum *) NULL)
5724 GetPixelInfoPixel(image,p,pixel);
5725 filter_view=DestroyCacheView(filter_view);
5726 filter_image=DestroyImage(filter_image);
5730 case IntegerInterpolatePixel:
5732 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5733 if (p == (const Quantum *) NULL)
5738 GetPixelInfoPixel(image,p,pixel);
5741 case MeshInterpolatePixel:
5747 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5748 if (p == (const Quantum *) NULL)
5755 luminance.x=GetPixelLuminance(image,p)-(double)
5756 GetPixelLuminance(image,p+3*GetPixelChannels(image));
5757 luminance.y=GetPixelLuminance(image,p+GetPixelChannels(image))-(double)
5758 GetPixelLuminance(image,p+2*GetPixelChannels(image));
5759 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5760 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5761 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5762 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5763 if (fabs(luminance.x) < fabs(luminance.y))
5768 if (delta.x <= delta.y)
5771 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5773 delta.y=1.0-delta.y;
5774 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5775 gamma=PerceptibleReciprocal(gamma);
5776 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5777 pixels[3].red,pixels[0].red);
5778 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5779 pixels[3].green,pixels[0].green);
5780 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5781 pixels[3].blue,pixels[0].blue);
5782 if (image->colorspace == CMYKColorspace)
5783 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5784 pixels[3].black,pixels[0].black);
5785 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5786 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5787 pixels[3].alpha,pixels[0].alpha);
5792 Top-right triangle (pixel:1 , diagonal: 0-3).
5794 delta.x=1.0-delta.x;
5795 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5796 gamma=PerceptibleReciprocal(gamma);
5797 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5798 pixels[0].red,pixels[3].red);
5799 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5800 pixels[0].green,pixels[3].green);
5801 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5802 pixels[0].blue,pixels[3].blue);
5803 if (image->colorspace == CMYKColorspace)
5804 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5805 pixels[0].black,pixels[3].black);
5806 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5807 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5808 pixels[0].alpha,pixels[3].alpha);
5816 if (delta.x <= (1.0-delta.y))
5819 Top-left triangle (pixel: 0, diagonal: 1-2).
5821 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5822 gamma=PerceptibleReciprocal(gamma);
5823 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5824 pixels[1].red,pixels[2].red);
5825 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5826 pixels[1].green,pixels[2].green);
5827 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5828 pixels[1].blue,pixels[2].blue);
5829 if (image->colorspace == CMYKColorspace)
5830 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5831 pixels[1].black,pixels[2].black);
5832 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5833 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5834 pixels[1].alpha,pixels[2].alpha);
5839 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5841 delta.x=1.0-delta.x;
5842 delta.y=1.0-delta.y;
5843 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5844 gamma=PerceptibleReciprocal(gamma);
5845 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5846 pixels[2].red,pixels[1].red);
5847 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5848 pixels[2].green,pixels[1].green);
5849 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5850 pixels[2].blue,pixels[1].blue);
5851 if (image->colorspace == CMYKColorspace)
5852 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5853 pixels[2].black,pixels[1].black);
5854 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5855 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5856 pixels[2].alpha,pixels[1].alpha);
5861 case NearestInterpolatePixel:
5863 x_offset=(ssize_t) floor(x+0.5);
5864 y_offset=(ssize_t) floor(y+0.5);
5865 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5866 if (p == (const Quantum *) NULL)
5871 GetPixelInfoPixel(image,p,pixel);
5874 case SplineInterpolatePixel:
5880 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5882 if (p == (const Quantum *) NULL)
5887 for (i=0; i < 16L; i++)
5888 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5889 SplineWeights((double) (x-x_offset),&cx);
5890 SplineWeights((double) (y-y_offset),&cy);
5891 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5892 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5893 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5894 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5895 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5896 pixels[14].red+cx[3]*pixels[15].red));
5897 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5898 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5899 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5900 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5901 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5902 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5903 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5904 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5905 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5906 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5907 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5908 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5909 if (image->colorspace == CMYKColorspace)
5910 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5911 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5912 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5913 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5914 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5915 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5917 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5918 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5919 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5920 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5921 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5922 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5934 + I s F u z z y E q u i v a l e n c e P i x e l %
5938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5940 % IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5941 % pixels is less than the specified distance in a linear three (or four)u
5942 % dimensional color space.
5944 % The format of the IsFuzzyEquivalencePixel method is:
5946 % void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5947 % const Image *destination,const Quantum *q)
5949 % A description of each parameter follows:
5951 % o source: the source image.
5955 % o destination: the destination image.
5960 MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5961 const Quantum *p,const Image *destination,const Quantum *q)
5971 fuzz=MagickMax(source->fuzz,(double) MagickSQ1_2)*MagickMax(
5972 destination->fuzz,(double) MagickSQ1_2);
5975 if (source->alpha_trait == BlendPixelTrait)
5978 Transparencies are involved - set alpha distance
5980 pixel=GetPixelAlpha(source,p)-(double) GetPixelAlpha(destination,q);
5981 distance=pixel*pixel;
5982 if (distance > fuzz)
5983 return(MagickFalse);
5985 Generate a alpha scaling factor to generate a 4D cone on colorspace
5986 Note that if one color is transparent, distance has no color component.
5988 scale=QuantumScale*GetPixelAlpha(source,p);
5989 scale*=QuantumScale*GetPixelAlpha(destination,q);
5990 if (scale <= MagickEpsilon)
5994 RGB or CMY color cube
5996 distance*=3.0; /* rescale appropriately */
5998 pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q);
5999 if ((source->colorspace == HSLColorspace) ||
6000 (source->colorspace == HSBColorspace) ||
6001 (source->colorspace == HWBColorspace))
6004 Compute an arc distance for hue. It should be a vector angle of
6005 'S'/'W' length with 'L'/'B' forming appropriate cones.
6007 if (fabs((double) pixel) > (QuantumRange/2))
6008 pixel-=QuantumRange;
6011 distance+=scale*pixel*pixel;
6012 if (distance > fuzz)
6013 return(MagickFalse);
6014 pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q);
6015 distance+=scale*pixel*pixel;
6016 if (distance > fuzz)
6017 return(MagickFalse);
6018 pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q);
6019 distance+=scale*pixel*pixel;
6020 if (distance > fuzz)
6021 return(MagickFalse);
6026 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6030 + I s F u z z y E q u i v a l e n c e P i x e l I n f o %
6034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6036 % IsFuzzyEquivalencePixelInfo() returns true if the distance between two
6037 % colors is less than the specified distance in a linear three (or four)
6038 % dimensional color space.
6040 % This implements the equivalent of:
6041 % fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
6043 % Which produces a multi-dimensional cone for that colorspace along the
6044 % transparency vector.
6046 % For example for an RGB:
6047 % color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
6049 % See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
6051 % Hue colorspace distances need more work. Hue is not a distance, it is an
6054 % A check that q is in the same color space as p should be made and the
6055 % appropriate mapping made. -- Anthony Thyssen 8 December 2010
6057 % The format of the IsFuzzyEquivalencePixelInfo method is:
6059 % MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6060 % const PixelInfo *q)
6062 % A description of each parameter follows:
6069 MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6080 if ((p->fuzz == 0.0) && (q->fuzz == 0.0))
6081 return(IsPixelInfoEquivalent(p,q));
6083 fuzz=MagickMax(q->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
6084 (double) MagickSQ1_2);
6085 else if (q->fuzz == 0.0)
6086 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(p->fuzz,
6087 (double) MagickSQ1_2);
6089 fuzz=MagickMax(p->fuzz,(double) MagickSQ1_2)*MagickMax(q->fuzz,
6090 (double) MagickSQ1_2);
6093 if ((p->alpha_trait == BlendPixelTrait) || (q->alpha_trait == BlendPixelTrait))
6096 Transparencies are involved - set alpha distance.
6098 pixel=(p->alpha_trait == BlendPixelTrait ? p->alpha : OpaqueAlpha)-
6099 (q->alpha_trait == BlendPixelTrait ? q->alpha : OpaqueAlpha);
6100 distance=pixel*pixel;
6101 if (distance > fuzz)
6102 return(MagickFalse);
6104 Generate a alpha scaling factor to generate a 4D cone on colorspace.
6105 If one color is transparent, distance has no color component.
6107 if (p->alpha_trait == BlendPixelTrait)
6108 scale=(QuantumScale*p->alpha);
6109 if (q->alpha_trait == BlendPixelTrait)
6110 scale*=(QuantumScale*q->alpha);
6111 if (scale <= MagickEpsilon )
6115 CMYK create a CMY cube with a multi-dimensional cone toward black.
6117 if (p->colorspace == CMYKColorspace)
6119 pixel=p->black-q->black;
6120 distance+=pixel*pixel*scale;
6121 if (distance > fuzz)
6122 return(MagickFalse);
6123 scale*=(double) (QuantumScale*(QuantumRange-p->black));
6124 scale*=(double) (QuantumScale*(QuantumRange-q->black));
6127 RGB or CMY color cube.
6129 distance*=3.0; /* rescale appropriately */
6131 pixel=p->red-q->red;
6132 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
6133 (p->colorspace == HWBColorspace))
6136 This calculates a arc distance for hue-- it should be a vector angle
6137 of 'S'/'W' length with 'L'/'B' forming appropriate cones. In other
6138 words this is a hack - Anthony.
6140 if (fabs((double) pixel) > (QuantumRange/2))
6141 pixel-=QuantumRange;
6144 distance+=pixel*pixel*scale;
6145 if (distance > fuzz)
6146 return(MagickFalse);
6147 pixel=p->green-q->green;
6148 distance+=pixel*pixel*scale;
6149 if (distance > fuzz)
6150 return(MagickFalse);
6151 pixel=p->blue-q->blue;
6152 distance+=pixel*pixel*scale;
6153 if (distance > fuzz)
6154 return(MagickFalse);
6159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6163 % S e t P i x e l C h a n n e l M a p M a s k %
6167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6169 % SetPixelChannelMask() sets the pixel channel map from the specified
6172 % The format of the SetPixelChannelMask method is:
6174 % void SetPixelChannelMask(Image *image,const ChannelType channel_mask)
6176 % A description of each parameter follows:
6178 % o image: the image.
6180 % o channel_mask: the channel mask.
6183 MagickExport void SetPixelChannelMask(Image *image,
6184 const ChannelType channel_mask)
6186 #define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
6191 if (image->debug != MagickFalse)
6192 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]", \
6193 image->filename,channel_mask); \
6194 image->channel_mask=channel_mask;
6195 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
6197 PixelChannel channel=GetPixelChannelChannel(image,i);
6198 SetPixelChannelTraits(image,channel,
6199 GetChannelBit(channel_mask,channel) == 0 ? CopyPixelTrait :
6200 image->alpha_trait != BlendPixelTrait || (channel == AlphaPixelChannel) ?
6201 UpdatePixelTrait : (PixelTrait) (UpdatePixelTrait | image->alpha_trait));
6203 if (image->storage_class == PseudoClass)
6204 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
6205 if (image->read_mask != MagickFalse)
6206 SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait);
6207 if (image->write_mask != MagickFalse)
6208 SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait);
6209 if (image->debug != MagickFalse)
6210 LogPixelChannels(image);
6214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6218 % S e t P i x e l M e t a C h a n n e l s %
6222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6224 % SetPixelMetaChannels() sets the image meta channels.
6226 % The format of the SetPixelMetaChannels method is:
6228 % MagickBooleanType SetPixelMetaChannels(Image *image,
6229 % const size_t number_meta_channels,ExceptionInfo *exception)
6231 % A description of each parameter follows:
6233 % o image: the image.
6235 % o number_meta_channels: the number of meta channels.
6237 % o exception: return any errors or warnings in this structure.
6240 MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
6241 const size_t number_meta_channels,ExceptionInfo *exception)
6243 image->number_meta_channels=number_meta_channels;
6244 return(SyncImagePixelCache(image,exception));