MagickCore 7.1.2-33
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
pixel.c
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% PPPP IIIII X X EEEEE L %
7% P P I X X E L %
8% PPPP I X EEE L %
9% P I X X E L %
10% P IIIII X X EEEEE LLLLL %
11% %
12% MagickCore Methods to Import/Export Pixels %
13% %
14% Software Design %
15% Cristy %
16% October 1998 %
17% %
18% %
19% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
20% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% https://imagemagick.org/license/ %
26% %
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. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37␌
38/*
39 Include declarations.
40*/
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/colorspace-private.h"
48#include "MagickCore/draw.h"
49#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/cache.h"
52#include "MagickCore/constitute.h"
53#include "MagickCore/delegate.h"
54#include "MagickCore/geometry.h"
55#include "MagickCore/image-private.h"
56#include "MagickCore/list.h"
57#include "MagickCore/magick.h"
58#include "MagickCore/memory_.h"
59#include "MagickCore/memory-private.h"
60#include "MagickCore/monitor.h"
61#include "MagickCore/option.h"
62#include "MagickCore/pixel.h"
63#include "MagickCore/pixel-accessor.h"
64#include "MagickCore/pixel-private.h"
65#include "MagickCore/quantum.h"
66#include "MagickCore/quantum-private.h"
67#include "MagickCore/resource_.h"
68#include "MagickCore/semaphore.h"
69#include "MagickCore/statistic.h"
70#include "MagickCore/stream.h"
71#include "MagickCore/string_.h"
72#include "MagickCore/transform.h"
73#include "MagickCore/utility.h"
74␌
75/*
76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77% %
78% %
79% %
80+ A c q u i r e P i x e l C h a n n e l M a p %
81% %
82% %
83% %
84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85%
86% AcquirePixelChannelMap() acquires a pixel component map.
87%
88% The format of the AcquirePixelChannelMap() method is:
89%
90% PixelChannelMap *AcquirePixelChannelMap(void)
91%
92*/
93MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
94{
95 PixelChannelMap
96 *channel_map;
97
98 ssize_t
99 i;
100
101 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels+1,
102 sizeof(*channel_map));
103 if (channel_map == (PixelChannelMap *) NULL)
104 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
105 (void) memset(channel_map,0,(MaxPixelChannels+1)*sizeof(*channel_map));
106 for (i=0; i <= MaxPixelChannels; i++)
107 channel_map[i].channel=(PixelChannel) i;
108 return(channel_map);
109}
110␌
111/*
112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113% %
114% %
115% %
116+ C l o n e P i x e l C h a n n e l M a p %
117% %
118% %
119% %
120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121%
122% ClonePixelChannelMap() clones a pixel component map.
123%
124% The format of the ClonePixelChannelMap() method is:
125%
126% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
127%
128% A description of each parameter follows:
129%
130% o channel_map: the pixel component map.
131%
132*/
133MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
134{
135 PixelChannelMap
136 *clone_map;
137
138 assert(channel_map != (PixelChannelMap *) NULL);
139 clone_map=AcquirePixelChannelMap();
140 if (clone_map == (PixelChannelMap *) NULL)
141 return((PixelChannelMap *) NULL);
142 (void) memcpy(clone_map,channel_map,MaxPixelChannels*sizeof(*channel_map));
143 return(clone_map);
144}
145␌
146/*
147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148% %
149% %
150% %
151+ C l o n e P i x e l I n f o %
152% %
153% %
154% %
155%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
156%
157% ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
158% pixel info is NULL, a new one.
159%
160% The format of the ClonePixelInfo method is:
161%
162% PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
163%
164% A description of each parameter follows:
165%
166% o pixel: the pixel info.
167%
168*/
169MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
170{
171 PixelInfo
172 *pixel_info;
173
174 pixel_info=(PixelInfo *) AcquireMagickMemory(sizeof(*pixel_info));
175 if (pixel_info == (PixelInfo *) NULL)
176 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
177 *pixel_info=(*pixel);
178 return(pixel_info);
179}
180␌
181/*
182%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
183% %
184% %
185% %
186+ C o n f o r m P i x e l I n f o %
187% %
188% %
189% %
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191%
192% ConformPixelInfo() ensures the pixel conforms with the colorspace and alpha
193% attribute of the image.
194%
195% The format of the ConformPixelInfo method is:
196%
197% void *ConformPixelInfo((Image *image,const PixelInfo *source,
198% PixelInfo *destination,ExceptionInfo *exception)
199%
200% A description of each parameter follows:
201%
202% o image: the image.
203%
204% o source: the source pixel info.
205%
206% o destination: the destination pixel info.
207%
208% o exception: return any errors or warnings in this structure.
209%
210*/
211MagickExport void ConformPixelInfo(Image *image,const PixelInfo *source,
212 PixelInfo *destination,ExceptionInfo *exception)
213{
214 assert(image != (Image *) NULL);
215 assert(image->signature == MagickCoreSignature);
216 assert(destination != (const PixelInfo *) NULL);
217 *destination=(*source);
218 ConformPixelInfoColorspace(image,destination,exception);
219 if (image->colorspace == CMYKColorspace)
220 {
221 if (IssRGBCompatibleColorspace(destination->colorspace) != MagickFalse)
222 ConvertRGBToCMYK(destination);
223 }
224 else
225 if (destination->colorspace == CMYKColorspace)
226 {
227 if (IssRGBCompatibleColorspace(image->colorspace) != MagickFalse)
228 ConvertCMYKToRGB(destination);
229 }
230 if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
231 (IsGrayColorspace(image->colorspace) != MagickFalse))
232 (void) TransformImageColorspace(image,sRGBColorspace,exception);
233 if ((destination->alpha_trait != UndefinedPixelTrait) &&
234 ((image->alpha_trait & BlendPixelTrait) == 0))
235 (void) SetImageAlpha(image,OpaqueAlpha,exception);
236}
237␌
238/*
239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240% %
241% %
242% %
243% D e c o d e P i x e l G a m m a %
244% %
245% %
246% %
247%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248%
249% DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel.
250%
251% The format of the DecodePixelGamma method is:
252%
253% double DecodePixelGamma(const MagickRealType pixel)
254%
255% A description of each parameter follows:
256%
257% o pixel: the pixel.
258%
259*/
260
261static inline double DecodeGamma(const double x)
262{
263 div_t
264 quotient;
265
266 double
267 p,
268 term[9];
269
270 int
271 exponent;
272
273 static const double coefficient[] = /* terms for x^(7/5), x=1.5 */
274 {
275 1.7917488588043277509,
276 0.82045614371976854984,
277 0.027694100686325412819,
278 -0.00094244335181762134018,
279 0.000064355540911469709545,
280 -5.7224404636060757485e-06,
281 5.8767669437311184313e-07,
282 -6.6139920053589721168e-08,
283 7.9323242696227458163e-09
284 };
285
286 static const double powers_of_two[] = /* (2^x)^(7/5) */
287 {
288 1.0,
289 2.6390158215457883983,
290 6.9644045063689921093,
291 1.8379173679952558018e+01,
292 4.8502930128332728543e+01
293 };
294
295 /*
296 Compute x^2.4 == x*x^(7/5) == pow(x,2.4).
297 */
298 term[0]=1.0;
299 term[1]=4.0*frexp(x,&exponent)-3.0;
300 term[2]=2.0*term[1]*term[1]-term[0];
301 term[3]=2.0*term[1]*term[2]-term[1];
302 term[4]=2.0*term[1]*term[3]-term[2];
303 term[5]=2.0*term[1]*term[4]-term[3];
304 term[6]=2.0*term[1]*term[5]-term[4];
305 term[7]=2.0*term[1]*term[6]-term[5];
306 term[8]=2.0*term[1]*term[7]-term[6];
307 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
308 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
309 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
310 quotient=div(exponent-1,5);
311 if (quotient.rem < 0)
312 {
313 quotient.quot-=1;
314 quotient.rem+=5;
315 }
316 return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot));
317}
318
319MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel)
320{
321 if (pixel <= (0.0404482362771076*(double) QuantumRange))
322 return(pixel/12.92);
323 return((MagickRealType) ((double) QuantumRange*DecodeGamma((double)
324 (QuantumScale*pixel+0.055)/1.055)));
325}
326␌
327/*
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329% %
330% %
331% %
332+ D e s t r o y P i x e l C h a n n e l M a p %
333% %
334% %
335% %
336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337%
338% DestroyPixelChannelMap() deallocates memory associated with the pixel
339% channel map.
340%
341% The format of the DestroyPixelChannelMap() method is:
342%
343% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
344%
345% A description of each parameter follows:
346%
347% o channel_map: the pixel component map.
348%
349*/
350MagickExport PixelChannelMap *DestroyPixelChannelMap(
351 PixelChannelMap *channel_map)
352{
353 assert(channel_map != (PixelChannelMap *) NULL);
354 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
355 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
356}
357␌
358/*
359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360% %
361% %
362% %
363+ E n c o d e P i x e l G a m m a %
364% %
365% %
366% %
367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368%
369% EncodePixelGamma() cancels any nonlinearity in the pixel.
370%
371% The format of the EncodePixelGamma method is:
372%
373% MagickRealType EncodePixelGamma(const double MagickRealType)
374%
375% A description of each parameter follows:
376%
377% o pixel: the pixel.
378%
379*/
380
381static inline double EncodeGamma(const double x)
382{
383 div_t
384 quotient;
385
386 double
387 p,
388 term[9];
389
390 int
391 exponent;
392
393 static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */
394 {
395 1.1758200232996901923,
396 0.16665763094889061230,
397 -0.0083154894939042125035,
398 0.00075187976780420279038,
399 -0.000083240178519391795367,
400 0.000010229209410070008679,
401 -1.3400466409860246e-06,
402 1.8333422241635376682e-07,
403 -2.5878596761348859722e-08
404 };
405
406 static const double powers_of_two[] = /* (2^N)^(5/12) */
407 {
408 1.0,
409 1.3348398541700343678,
410 1.7817974362806785482,
411 2.3784142300054420538,
412 3.1748021039363991669,
413 4.2378523774371812394,
414 5.6568542494923805819,
415 7.5509945014535482244,
416 1.0079368399158985525e1,
417 1.3454342644059433809e1,
418 1.7959392772949968275e1,
419 2.3972913230026907883e1
420 };
421
422 /*
423 Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4).
424 */
425 term[0]=1.0;
426 term[1]=4.0*frexp(x,&exponent)-3.0;
427 term[2]=2.0*term[1]*term[1]-term[0];
428 term[3]=2.0*term[1]*term[2]-term[1];
429 term[4]=2.0*term[1]*term[3]-term[2];
430 term[5]=2.0*term[1]*term[4]-term[3];
431 term[6]=2.0*term[1]*term[5]-term[4];
432 term[7]=2.0*term[1]*term[6]-term[5];
433 term[8]=2.0*term[1]*term[7]-term[6];
434 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
435 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
436 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
437 quotient=div(exponent-1,12);
438 if (quotient.rem < 0)
439 {
440 quotient.quot-=1;
441 quotient.rem+=12;
442 }
443 return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot));
444}
445
446MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel)
447{
448 if (pixel <= (0.0031306684425005883*(double) QuantumRange))
449 return(12.92*pixel);
450 return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale*
451 pixel)-0.055));
452}
453␌
454/*
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456% %
457% %
458% %
459% E x p o r t I m a g e P i x e l s %
460% %
461% %
462% %
463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464%
465% ExportImagePixels() extracts pixel data from an image and returns it to you.
466% The method returns MagickTrue on success otherwise MagickFalse if an error is
467% encountered. The data is returned as char, short int, Quantum, unsigned int,
468% unsigned long long, float, or double in the order specified by map.
469%
470% Suppose you want to extract the first scanline of a 640x480 image as
471% character data in red-green-blue order:
472%
473% ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
474%
475% The format of the ExportImagePixels method is:
476%
477% MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
478% const ssize_t y,const size_t width,const size_t height,
479% const char *map,const StorageType type,void *pixels,
480% ExceptionInfo *exception)
481%
482% A description of each parameter follows:
483%
484% o image: the image.
485%
486% o x,y,width,height: These values define the perimeter
487% of a region of pixels you want to extract.
488%
489% o map: This string reflects the expected ordering of the pixel array.
490% It can be any combination or order of R = red, G = green, B = blue,
491% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
492% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
493% P = pad.
494%
495% o type: Define the data type of the pixels. Float and double types are
496% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
497% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
498% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
499% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
500%
501% o pixels: This array of values contain the pixel components as defined by
502% map and type. You must preallocate this array where the expected
503% length varies depending on the values of width, height, map, and type.
504%
505% o exception: return any errors or warnings in this structure.
506%
507*/
508
509static MagickBooleanType ExportCharPixel(const Image *image,
510 const RectangleInfo *roi,const char *magick_restrict map,
511 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
512{
513 const Quantum
514 *magick_restrict p;
515
516 ssize_t
517 x;
518
519 unsigned char
520 *magick_restrict q;
521
522 size_t
523 length;
524
525 ssize_t
526 y;
527
528 q=(unsigned char *) pixels;
529 if (LocaleCompare(map,"BGR") == 0)
530 {
531 for (y=0; y < (ssize_t) roi->height; y++)
532 {
533 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
534 if (p == (const Quantum *) NULL)
535 break;
536 for (x=0; x < (ssize_t) roi->width; x++)
537 {
538 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
539 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
540 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
541 p+=(ptrdiff_t) GetPixelChannels(image);
542 }
543 }
544 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
545 }
546 if (LocaleCompare(map,"BGRA") == 0)
547 {
548 for (y=0; y < (ssize_t) roi->height; y++)
549 {
550 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
551 if (p == (const Quantum *) NULL)
552 break;
553 for (x=0; x < (ssize_t) roi->width; x++)
554 {
555 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
556 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
557 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
558 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
559 p+=(ptrdiff_t) GetPixelChannels(image);
560 }
561 }
562 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
563 }
564 if (LocaleCompare(map,"BGRP") == 0)
565 {
566 for (y=0; y < (ssize_t) roi->height; y++)
567 {
568 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
569 if (p == (const Quantum *) NULL)
570 break;
571 for (x=0; x < (ssize_t) roi->width; x++)
572 {
573 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
574 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
575 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
576 *q++=ScaleQuantumToChar((Quantum) 0);
577 p+=(ptrdiff_t) GetPixelChannels(image);
578 }
579 }
580 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
581 }
582 if (LocaleCompare(map,"I") == 0)
583 {
584 for (y=0; y < (ssize_t) roi->height; y++)
585 {
586 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
587 if (p == (const Quantum *) NULL)
588 break;
589 for (x=0; x < (ssize_t) roi->width; x++)
590 {
591 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
592 p+=(ptrdiff_t) GetPixelChannels(image);
593 }
594 }
595 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
596 }
597 if (LocaleCompare(map,"RGB") == 0)
598 {
599 for (y=0; y < (ssize_t) roi->height; y++)
600 {
601 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
602 if (p == (const Quantum *) NULL)
603 break;
604 for (x=0; x < (ssize_t) roi->width; x++)
605 {
606 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
607 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
608 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
609 p+=(ptrdiff_t) GetPixelChannels(image);
610 }
611 }
612 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
613 }
614 if (LocaleCompare(map,"RGBA") == 0)
615 {
616 for (y=0; y < (ssize_t) roi->height; y++)
617 {
618 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
619 if (p == (const Quantum *) NULL)
620 break;
621 for (x=0; x < (ssize_t) roi->width; x++)
622 {
623 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
624 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
625 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
626 *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
627 p+=(ptrdiff_t) GetPixelChannels(image);
628 }
629 }
630 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
631 }
632 if (LocaleCompare(map,"RGBP") == 0)
633 {
634 for (y=0; y < (ssize_t) roi->height; y++)
635 {
636 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
637 if (p == (const Quantum *) NULL)
638 break;
639 for (x=0; x < (ssize_t) roi->width; x++)
640 {
641 *q++=ScaleQuantumToChar(GetPixelRed(image,p));
642 *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
643 *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
644 *q++=ScaleQuantumToChar((Quantum) 0);
645 p+=(ptrdiff_t) GetPixelChannels(image);
646 }
647 }
648 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
649 }
650 length=strlen(map);
651 for (y=0; y < (ssize_t) roi->height; y++)
652 {
653 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
654 if (p == (const Quantum *) NULL)
655 break;
656 for (x=0; x < (ssize_t) roi->width; x++)
657 {
658 ssize_t
659 i;
660
661 for (i=0; i < (ssize_t) length; i++)
662 {
663 *q=0;
664 switch (quantum_map[i])
665 {
666 case RedQuantum:
667 case CyanQuantum:
668 {
669 *q=ScaleQuantumToChar(GetPixelRed(image,p));
670 break;
671 }
672 case GreenQuantum:
673 case MagentaQuantum:
674 {
675 *q=ScaleQuantumToChar(GetPixelGreen(image,p));
676 break;
677 }
678 case BlueQuantum:
679 case YellowQuantum:
680 {
681 *q=ScaleQuantumToChar(GetPixelBlue(image,p));
682 break;
683 }
684 case AlphaQuantum:
685 {
686 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
687 break;
688 }
689 case OpacityQuantum:
690 {
691 *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
692 break;
693 }
694 case BlackQuantum:
695 {
696 if (image->colorspace == CMYKColorspace)
697 *q=ScaleQuantumToChar(GetPixelBlack(image,p));
698 break;
699 }
700 case IndexQuantum:
701 {
702 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
703 break;
704 }
705 default:
706 break;
707 }
708 q++;
709 }
710 p+=(ptrdiff_t) GetPixelChannels(image);
711 }
712 }
713 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
714}
715
716static MagickBooleanType ExportDoublePixel(const Image *image,
717 const RectangleInfo *roi,const char *magick_restrict map,
718 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
719{
720 const Quantum
721 *magick_restrict p;
722
723 double
724 *magick_restrict q;
725
726 ssize_t
727 x;
728
729 size_t
730 length;
731
732 ssize_t
733 y;
734
735 q=(double *) pixels;
736 if (LocaleCompare(map,"BGR") == 0)
737 {
738 for (y=0; y < (ssize_t) roi->height; y++)
739 {
740 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
741 if (p == (const Quantum *) NULL)
742 break;
743 for (x=0; x < (ssize_t) roi->width; x++)
744 {
745 *q++=QuantumScale*(double) GetPixelBlue(image,p);
746 *q++=QuantumScale*(double) GetPixelGreen(image,p);
747 *q++=QuantumScale*(double) GetPixelRed(image,p);
748 p+=(ptrdiff_t) GetPixelChannels(image);
749 }
750 }
751 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
752 }
753 if (LocaleCompare(map,"BGRA") == 0)
754 {
755 for (y=0; y < (ssize_t) roi->height; y++)
756 {
757 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
758 if (p == (const Quantum *) NULL)
759 break;
760 for (x=0; x < (ssize_t) roi->width; x++)
761 {
762 *q++=QuantumScale*(double) GetPixelBlue(image,p);
763 *q++=QuantumScale*(double) GetPixelGreen(image,p);
764 *q++=QuantumScale*(double) GetPixelRed(image,p);
765 *q++=QuantumScale*(double) GetPixelAlpha(image,p);
766 p+=(ptrdiff_t) GetPixelChannels(image);
767 }
768 }
769 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
770 }
771 if (LocaleCompare(map,"BGRP") == 0)
772 {
773 for (y=0; y < (ssize_t) roi->height; y++)
774 {
775 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
776 if (p == (const Quantum *) NULL)
777 break;
778 for (x=0; x < (ssize_t) roi->width; x++)
779 {
780 *q++=QuantumScale*(double) GetPixelBlue(image,p);
781 *q++=QuantumScale*(double) GetPixelGreen(image,p);
782 *q++=QuantumScale*(double) GetPixelRed(image,p);
783 *q++=0.0;
784 p+=(ptrdiff_t) GetPixelChannels(image);
785 }
786 }
787 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
788 }
789 if (LocaleCompare(map,"I") == 0)
790 {
791 for (y=0; y < (ssize_t) roi->height; y++)
792 {
793 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
794 if (p == (const Quantum *) NULL)
795 break;
796 for (x=0; x < (ssize_t) roi->width; x++)
797 {
798 *q++=(double) (QuantumScale*(double) GetPixelIntensity(image,p));
799 p+=(ptrdiff_t) GetPixelChannels(image);
800 }
801 }
802 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
803 }
804 if (LocaleCompare(map,"RGB") == 0)
805 {
806 for (y=0; y < (ssize_t) roi->height; y++)
807 {
808 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
809 if (p == (const Quantum *) NULL)
810 break;
811 for (x=0; x < (ssize_t) roi->width; x++)
812 {
813 *q++=QuantumScale*(double) GetPixelRed(image,p);
814 *q++=QuantumScale*(double) GetPixelGreen(image,p);
815 *q++=QuantumScale*(double) GetPixelBlue(image,p);
816 p+=(ptrdiff_t) GetPixelChannels(image);
817 }
818 }
819 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
820 }
821 if (LocaleCompare(map,"RGBA") == 0)
822 {
823 for (y=0; y < (ssize_t) roi->height; y++)
824 {
825 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
826 if (p == (const Quantum *) NULL)
827 break;
828 for (x=0; x < (ssize_t) roi->width; x++)
829 {
830 *q++=QuantumScale*(double) GetPixelRed(image,p);
831 *q++=QuantumScale*(double) GetPixelGreen(image,p);
832 *q++=QuantumScale*(double) GetPixelBlue(image,p);
833 *q++=QuantumScale*(double) GetPixelAlpha(image,p);
834 p+=(ptrdiff_t) GetPixelChannels(image);
835 }
836 }
837 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
838 }
839 if (LocaleCompare(map,"RGBP") == 0)
840 {
841 for (y=0; y < (ssize_t) roi->height; y++)
842 {
843 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
844 if (p == (const Quantum *) NULL)
845 break;
846 for (x=0; x < (ssize_t) roi->width; x++)
847 {
848 *q++=QuantumScale*(double) GetPixelRed(image,p);
849 *q++=QuantumScale*(double) GetPixelGreen(image,p);
850 *q++=QuantumScale*(double) GetPixelBlue(image,p);
851 *q++=0.0;
852 p+=(ptrdiff_t) GetPixelChannels(image);
853 }
854 }
855 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
856 }
857 length=strlen(map);
858 for (y=0; y < (ssize_t) roi->height; y++)
859 {
860 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
861 if (p == (const Quantum *) NULL)
862 break;
863 for (x=0; x < (ssize_t) roi->width; x++)
864 {
865 ssize_t
866 i;
867
868 for (i=0; i < (ssize_t) length; i++)
869 {
870 *q=0;
871 switch (quantum_map[i])
872 {
873 case RedQuantum:
874 case CyanQuantum:
875 {
876 *q=QuantumScale*(double) GetPixelRed(image,p);
877 break;
878 }
879 case GreenQuantum:
880 case MagentaQuantum:
881 {
882 *q=QuantumScale*(double) GetPixelGreen(image,p);
883 break;
884 }
885 case BlueQuantum:
886 case YellowQuantum:
887 {
888 *q=QuantumScale*(double) GetPixelBlue(image,p);
889 break;
890 }
891 case AlphaQuantum:
892 {
893 *q=QuantumScale*(double) GetPixelAlpha(image,p);
894 break;
895 }
896 case OpacityQuantum:
897 {
898 *q=QuantumScale*(double) GetPixelAlpha(image,p);
899 break;
900 }
901 case BlackQuantum:
902 {
903 if (image->colorspace == CMYKColorspace)
904 *q=QuantumScale*(double) GetPixelBlack(image,p);
905 break;
906 }
907 case IndexQuantum:
908 {
909 *q=QuantumScale*(double) GetPixelIntensity(image,p);
910 break;
911 }
912 default:
913 *q=0;
914 }
915 q++;
916 }
917 p+=(ptrdiff_t) GetPixelChannels(image);
918 }
919 }
920 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
921}
922
923static MagickBooleanType ExportFloatPixel(const Image *image,
924 const RectangleInfo *roi,const char *magick_restrict map,
925 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
926{
927 const Quantum
928 *magick_restrict p;
929
930 float
931 *magick_restrict q;
932
933 ssize_t
934 x;
935
936 size_t
937 length;
938
939 ssize_t
940 y;
941
942 q=(float *) pixels;
943 if (LocaleCompare(map,"BGR") == 0)
944 {
945 for (y=0; y < (ssize_t) roi->height; y++)
946 {
947 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
948 if (p == (const Quantum *) NULL)
949 break;
950 for (x=0; x < (ssize_t) roi->width; x++)
951 {
952 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
953 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
954 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
955 p+=(ptrdiff_t) GetPixelChannels(image);
956 }
957 }
958 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
959 }
960 if (LocaleCompare(map,"BGRA") == 0)
961 {
962 for (y=0; y < (ssize_t) roi->height; y++)
963 {
964 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
965 if (p == (const Quantum *) NULL)
966 break;
967 for (x=0; x < (ssize_t) roi->width; x++)
968 {
969 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
970 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
971 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
972 *q++=(float) (QuantumScale*(double) GetPixelAlpha(image,p));
973 p+=(ptrdiff_t) GetPixelChannels(image);
974 }
975 }
976 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
977 }
978 if (LocaleCompare(map,"BGRP") == 0)
979 {
980 for (y=0; y < (ssize_t) roi->height; y++)
981 {
982 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
983 if (p == (const Quantum *) NULL)
984 break;
985 for (x=0; x < (ssize_t) roi->width; x++)
986 {
987 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
988 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
989 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
990 *q++=0.0;
991 p+=(ptrdiff_t) GetPixelChannels(image);
992 }
993 }
994 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
995 }
996 if (LocaleCompare(map,"I") == 0)
997 {
998 for (y=0; y < (ssize_t) roi->height; y++)
999 {
1000 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1001 if (p == (const Quantum *) NULL)
1002 break;
1003 for (x=0; x < (ssize_t) roi->width; x++)
1004 {
1005 *q++=(float) (QuantumScale*(double) GetPixelIntensity(image,p));
1006 p+=(ptrdiff_t) GetPixelChannels(image);
1007 }
1008 }
1009 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1010 }
1011 if (LocaleCompare(map,"RGB") == 0)
1012 {
1013 for (y=0; y < (ssize_t) roi->height; y++)
1014 {
1015 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1016 if (p == (const Quantum *) NULL)
1017 break;
1018 for (x=0; x < (ssize_t) roi->width; x++)
1019 {
1020 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
1021 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
1022 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
1023 p+=(ptrdiff_t) GetPixelChannels(image);
1024 }
1025 }
1026 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1027 }
1028 if (LocaleCompare(map,"RGBA") == 0)
1029 {
1030 for (y=0; y < (ssize_t) roi->height; y++)
1031 {
1032 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1033 if (p == (const Quantum *) NULL)
1034 break;
1035 for (x=0; x < (ssize_t) roi->width; x++)
1036 {
1037 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
1038 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
1039 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
1040 *q++=(float) (QuantumScale*(double) GetPixelAlpha(image,p));
1041 p+=(ptrdiff_t) GetPixelChannels(image);
1042 }
1043 }
1044 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1045 }
1046 if (LocaleCompare(map,"RGBP") == 0)
1047 {
1048 for (y=0; y < (ssize_t) roi->height; y++)
1049 {
1050 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1051 if (p == (const Quantum *) NULL)
1052 break;
1053 for (x=0; x < (ssize_t) roi->width; x++)
1054 {
1055 *q++=(float) (QuantumScale*(double) GetPixelRed(image,p));
1056 *q++=(float) (QuantumScale*(double) GetPixelGreen(image,p));
1057 *q++=(float) (QuantumScale*(double) GetPixelBlue(image,p));
1058 *q++=0.0;
1059 p+=(ptrdiff_t) GetPixelChannels(image);
1060 }
1061 }
1062 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1063 }
1064 length=strlen(map);
1065 for (y=0; y < (ssize_t) roi->height; y++)
1066 {
1067 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1068 if (p == (const Quantum *) NULL)
1069 break;
1070 for (x=0; x < (ssize_t) roi->width; x++)
1071 {
1072 ssize_t
1073 i;
1074
1075 for (i=0; i < (ssize_t) length; i++)
1076 {
1077 *q=0;
1078 switch (quantum_map[i])
1079 {
1080 case RedQuantum:
1081 case CyanQuantum:
1082 {
1083 *q=(float) (QuantumScale*(double) GetPixelRed(image,p));
1084 break;
1085 }
1086 case GreenQuantum:
1087 case MagentaQuantum:
1088 {
1089 *q=(float) (QuantumScale*(double) GetPixelGreen(image,p));
1090 break;
1091 }
1092 case BlueQuantum:
1093 case YellowQuantum:
1094 {
1095 *q=(float) (QuantumScale*(double) GetPixelBlue(image,p));
1096 break;
1097 }
1098 case AlphaQuantum:
1099 {
1100 *q=(float) (QuantumScale*((double) (GetPixelAlpha(image,p))));
1101 break;
1102 }
1103 case OpacityQuantum:
1104 {
1105 *q=(float) (QuantumScale*(double) GetPixelAlpha(image,p));
1106 break;
1107 }
1108 case BlackQuantum:
1109 {
1110 if (image->colorspace == CMYKColorspace)
1111 *q=(float) (QuantumScale*(double) GetPixelBlack(image,p));
1112 break;
1113 }
1114 case IndexQuantum:
1115 {
1116 *q=(float) (QuantumScale*(double) GetPixelIntensity(image,p));
1117 break;
1118 }
1119 default:
1120 *q=0;
1121 }
1122 q++;
1123 }
1124 p+=(ptrdiff_t) GetPixelChannels(image);
1125 }
1126 }
1127 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1128}
1129
1130static MagickBooleanType ExportLongPixel(const Image *image,
1131 const RectangleInfo *roi,const char *magick_restrict map,
1132 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
1133{
1134 const Quantum
1135 *magick_restrict p;
1136
1137 ssize_t
1138 x;
1139
1140 unsigned int
1141 *magick_restrict q;
1142
1143 size_t
1144 length;
1145
1146 ssize_t
1147 y;
1148
1149 q=(unsigned int *) pixels;
1150 if (LocaleCompare(map,"BGR") == 0)
1151 {
1152 for (y=0; y < (ssize_t) roi->height; y++)
1153 {
1154 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1155 if (p == (const Quantum *) NULL)
1156 break;
1157 for (x=0; x < (ssize_t) roi->width; x++)
1158 {
1159 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1160 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1161 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1162 p+=(ptrdiff_t) GetPixelChannels(image);
1163 }
1164 }
1165 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1166 }
1167 if (LocaleCompare(map,"BGRA") == 0)
1168 {
1169 for (y=0; y < (ssize_t) roi->height; y++)
1170 {
1171 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1172 if (p == (const Quantum *) NULL)
1173 break;
1174 for (x=0; x < (ssize_t) roi->width; x++)
1175 {
1176 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1177 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1178 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1179 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1180 p+=(ptrdiff_t) GetPixelChannels(image);
1181 }
1182 }
1183 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1184 }
1185 if (LocaleCompare(map,"BGRP") == 0)
1186 {
1187 for (y=0; y < (ssize_t) roi->height; y++)
1188 {
1189 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1190 if (p == (const Quantum *) NULL)
1191 break;
1192 for (x=0; x < (ssize_t) roi->width; x++)
1193 {
1194 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1195 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1196 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1197 *q++=0;
1198 p+=(ptrdiff_t) GetPixelChannels(image);
1199 }
1200 }
1201 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1202 }
1203 if (LocaleCompare(map,"I") == 0)
1204 {
1205 for (y=0; y < (ssize_t) roi->height; y++)
1206 {
1207 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1208 if (p == (const Quantum *) NULL)
1209 break;
1210 for (x=0; x < (ssize_t) roi->width; x++)
1211 {
1212 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1213 p+=(ptrdiff_t) GetPixelChannels(image);
1214 }
1215 }
1216 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1217 }
1218 if (LocaleCompare(map,"RGB") == 0)
1219 {
1220 for (y=0; y < (ssize_t) roi->height; y++)
1221 {
1222 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1223 if (p == (const Quantum *) NULL)
1224 break;
1225 for (x=0; x < (ssize_t) roi->width; x++)
1226 {
1227 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1228 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1229 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1230 p+=(ptrdiff_t) GetPixelChannels(image);
1231 }
1232 }
1233 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1234 }
1235 if (LocaleCompare(map,"RGBA") == 0)
1236 {
1237 for (y=0; y < (ssize_t) roi->height; y++)
1238 {
1239 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1240 if (p == (const Quantum *) NULL)
1241 break;
1242 for (x=0; x < (ssize_t) roi->width; x++)
1243 {
1244 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1245 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1246 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1247 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1248 p+=(ptrdiff_t) GetPixelChannels(image);
1249 }
1250 }
1251 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1252 }
1253 if (LocaleCompare(map,"RGBP") == 0)
1254 {
1255 for (y=0; y < (ssize_t) roi->height; y++)
1256 {
1257 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1258 if (p == (const Quantum *) NULL)
1259 break;
1260 for (x=0; x < (ssize_t) roi->width; x++)
1261 {
1262 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1263 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1264 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1265 *q++=0;
1266 p+=(ptrdiff_t) GetPixelChannels(image);
1267 }
1268 }
1269 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1270 }
1271 length=strlen(map);
1272 for (y=0; y < (ssize_t) roi->height; y++)
1273 {
1274 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1275 if (p == (const Quantum *) NULL)
1276 break;
1277 for (x=0; x < (ssize_t) roi->width; x++)
1278 {
1279 ssize_t
1280 i;
1281
1282 for (i=0; i < (ssize_t) length; i++)
1283 {
1284 *q=0;
1285 switch (quantum_map[i])
1286 {
1287 case RedQuantum:
1288 case CyanQuantum:
1289 {
1290 *q=ScaleQuantumToLong(GetPixelRed(image,p));
1291 break;
1292 }
1293 case GreenQuantum:
1294 case MagentaQuantum:
1295 {
1296 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
1297 break;
1298 }
1299 case BlueQuantum:
1300 case YellowQuantum:
1301 {
1302 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
1303 break;
1304 }
1305 case AlphaQuantum:
1306 {
1307 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1308 break;
1309 }
1310 case OpacityQuantum:
1311 {
1312 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1313 break;
1314 }
1315 case BlackQuantum:
1316 {
1317 if (image->colorspace == CMYKColorspace)
1318 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
1319 break;
1320 }
1321 case IndexQuantum:
1322 {
1323 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1324 break;
1325 }
1326 default:
1327 break;
1328 }
1329 q++;
1330 }
1331 p+=(ptrdiff_t) GetPixelChannels(image);
1332 }
1333 }
1334 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1335}
1336
1337static MagickBooleanType ExportLongLongPixel(const Image *image,
1338 const RectangleInfo *roi,const char *magick_restrict map,
1339 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
1340{
1341 const Quantum
1342 *magick_restrict p;
1343
1344 ssize_t
1345 x;
1346
1347 MagickSizeType
1348 *magick_restrict q;
1349
1350 size_t
1351 length;
1352
1353 ssize_t
1354 y;
1355
1356 q=(MagickSizeType *) pixels;
1357 if (LocaleCompare(map,"BGR") == 0)
1358 {
1359 for (y=0; y < (ssize_t) roi->height; y++)
1360 {
1361 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1362 if (p == (const Quantum *) NULL)
1363 break;
1364 for (x=0; x < (ssize_t) roi->width; x++)
1365 {
1366 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1367 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1368 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1369 p+=(ptrdiff_t) GetPixelChannels(image);
1370 }
1371 }
1372 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1373 }
1374 if (LocaleCompare(map,"BGRA") == 0)
1375 {
1376 for (y=0; y < (ssize_t) roi->height; y++)
1377 {
1378 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1379 if (p == (const Quantum *) NULL)
1380 break;
1381 for (x=0; x < (ssize_t) roi->width; x++)
1382 {
1383 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1384 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1385 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1386 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1387 p+=(ptrdiff_t) GetPixelChannels(image);
1388 }
1389 }
1390 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1391 }
1392 if (LocaleCompare(map,"BGRP") == 0)
1393 {
1394 for (y=0; y < (ssize_t) roi->height; y++)
1395 {
1396 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1397 if (p == (const Quantum *) NULL)
1398 break;
1399 for (x=0; x < (ssize_t) roi->width; x++)
1400 {
1401 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1402 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1403 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1404 *q++=0;
1405 p+=(ptrdiff_t) GetPixelChannels(image);
1406 }
1407 }
1408 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1409 }
1410 if (LocaleCompare(map,"I") == 0)
1411 {
1412 for (y=0; y < (ssize_t) roi->height; y++)
1413 {
1414 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1415 if (p == (const Quantum *) NULL)
1416 break;
1417 for (x=0; x < (ssize_t) roi->width; x++)
1418 {
1419 *q++=ScaleQuantumToLongLong(ClampToQuantum(
1420 GetPixelIntensity(image,p)));
1421 p+=(ptrdiff_t) GetPixelChannels(image);
1422 }
1423 }
1424 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1425 }
1426 if (LocaleCompare(map,"RGB") == 0)
1427 {
1428 for (y=0; y < (ssize_t) roi->height; y++)
1429 {
1430 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1431 if (p == (const Quantum *) NULL)
1432 break;
1433 for (x=0; x < (ssize_t) roi->width; x++)
1434 {
1435 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1436 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1437 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1438 p+=(ptrdiff_t) GetPixelChannels(image);
1439 }
1440 }
1441 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1442 }
1443 if (LocaleCompare(map,"RGBA") == 0)
1444 {
1445 for (y=0; y < (ssize_t) roi->height; y++)
1446 {
1447 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1448 if (p == (const Quantum *) NULL)
1449 break;
1450 for (x=0; x < (ssize_t) roi->width; x++)
1451 {
1452 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1453 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1454 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1455 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1456 p+=(ptrdiff_t) GetPixelChannels(image);
1457 }
1458 }
1459 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1460 }
1461 if (LocaleCompare(map,"RGBP") == 0)
1462 {
1463 for (y=0; y < (ssize_t) roi->height; y++)
1464 {
1465 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1466 if (p == (const Quantum *) NULL)
1467 break;
1468 for (x=0; x < (ssize_t) roi->width; x++)
1469 {
1470 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1471 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1472 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1473 *q++=0;
1474 p+=(ptrdiff_t) GetPixelChannels(image);
1475 }
1476 }
1477 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1478 }
1479 length=strlen(map);
1480 for (y=0; y < (ssize_t) roi->height; y++)
1481 {
1482 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1483 if (p == (const Quantum *) NULL)
1484 break;
1485 for (x=0; x < (ssize_t) roi->width; x++)
1486 {
1487 ssize_t
1488 i;
1489
1490 for (i=0; i < (ssize_t) length; i++)
1491 {
1492 *q=0;
1493 switch (quantum_map[i])
1494 {
1495 case RedQuantum:
1496 case CyanQuantum:
1497 {
1498 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
1499 break;
1500 }
1501 case GreenQuantum:
1502 case MagentaQuantum:
1503 {
1504 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1505 break;
1506 }
1507 case BlueQuantum:
1508 case YellowQuantum:
1509 {
1510 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1511 break;
1512 }
1513 case AlphaQuantum:
1514 {
1515 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1516 break;
1517 }
1518 case OpacityQuantum:
1519 {
1520 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1521 break;
1522 }
1523 case BlackQuantum:
1524 {
1525 if (image->colorspace == CMYKColorspace)
1526 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
1527 break;
1528 }
1529 case IndexQuantum:
1530 {
1531 *q=ScaleQuantumToLongLong(ClampToQuantum(
1532 GetPixelIntensity(image,p)));
1533 break;
1534 }
1535 default:
1536 break;
1537 }
1538 q++;
1539 }
1540 p+=(ptrdiff_t) GetPixelChannels(image);
1541 }
1542 }
1543 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1544}
1545
1546static MagickBooleanType ExportQuantumPixel(const Image *image,
1547 const RectangleInfo *roi,const char *magick_restrict map,
1548 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
1549{
1550 const Quantum
1551 *magick_restrict p;
1552
1553 Quantum
1554 *magick_restrict q;
1555
1556 ssize_t
1557 x;
1558
1559 size_t
1560 length;
1561
1562 ssize_t
1563 y;
1564
1565 q=(Quantum *) pixels;
1566 if (LocaleCompare(map,"BGR") == 0)
1567 {
1568 for (y=0; y < (ssize_t) roi->height; y++)
1569 {
1570 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1571 if (p == (const Quantum *) NULL)
1572 break;
1573 for (x=0; x < (ssize_t) roi->width; x++)
1574 {
1575 *q++=GetPixelBlue(image,p);
1576 *q++=GetPixelGreen(image,p);
1577 *q++=GetPixelRed(image,p);
1578 p+=(ptrdiff_t) GetPixelChannels(image);
1579 }
1580 }
1581 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1582 }
1583 if (LocaleCompare(map,"BGRA") == 0)
1584 {
1585 for (y=0; y < (ssize_t) roi->height; y++)
1586 {
1587 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1588 if (p == (const Quantum *) NULL)
1589 break;
1590 for (x=0; x < (ssize_t) roi->width; x++)
1591 {
1592 *q++=GetPixelBlue(image,p);
1593 *q++=GetPixelGreen(image,p);
1594 *q++=GetPixelRed(image,p);
1595 *q++=(Quantum) (GetPixelAlpha(image,p));
1596 p+=(ptrdiff_t) GetPixelChannels(image);
1597 }
1598 }
1599 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1600 }
1601 if (LocaleCompare(map,"BGRP") == 0)
1602 {
1603 for (y=0; y < (ssize_t) roi->height; y++)
1604 {
1605 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1606 if (p == (const Quantum *) NULL)
1607 break;
1608 for (x=0; x < (ssize_t) roi->width; x++)
1609 {
1610 *q++=GetPixelBlue(image,p);
1611 *q++=GetPixelGreen(image,p);
1612 *q++=GetPixelRed(image,p);
1613 *q++=(Quantum) 0;
1614 p+=(ptrdiff_t) GetPixelChannels(image);
1615 }
1616 }
1617 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1618 }
1619 if (LocaleCompare(map,"I") == 0)
1620 {
1621 for (y=0; y < (ssize_t) roi->height; y++)
1622 {
1623 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1624 if (p == (const Quantum *) NULL)
1625 break;
1626 for (x=0; x < (ssize_t) roi->width; x++)
1627 {
1628 *q++=ClampToQuantum(GetPixelIntensity(image,p));
1629 p+=(ptrdiff_t) GetPixelChannels(image);
1630 }
1631 }
1632 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1633 }
1634 if (LocaleCompare(map,"RGB") == 0)
1635 {
1636 for (y=0; y < (ssize_t) roi->height; y++)
1637 {
1638 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1639 if (p == (const Quantum *) NULL)
1640 break;
1641 for (x=0; x < (ssize_t) roi->width; x++)
1642 {
1643 *q++=GetPixelRed(image,p);
1644 *q++=GetPixelGreen(image,p);
1645 *q++=GetPixelBlue(image,p);
1646 p+=(ptrdiff_t) GetPixelChannels(image);
1647 }
1648 }
1649 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1650 }
1651 if (LocaleCompare(map,"RGBA") == 0)
1652 {
1653 for (y=0; y < (ssize_t) roi->height; y++)
1654 {
1655 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1656 if (p == (const Quantum *) NULL)
1657 break;
1658 for (x=0; x < (ssize_t) roi->width; x++)
1659 {
1660 *q++=GetPixelRed(image,p);
1661 *q++=GetPixelGreen(image,p);
1662 *q++=GetPixelBlue(image,p);
1663 *q++=(Quantum) (GetPixelAlpha(image,p));
1664 p+=(ptrdiff_t) GetPixelChannels(image);
1665 }
1666 }
1667 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1668 }
1669 if (LocaleCompare(map,"RGBP") == 0)
1670 {
1671 for (y=0; y < (ssize_t) roi->height; y++)
1672 {
1673 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1674 if (p == (const Quantum *) NULL)
1675 break;
1676 for (x=0; x < (ssize_t) roi->width; x++)
1677 {
1678 *q++=GetPixelRed(image,p);
1679 *q++=GetPixelGreen(image,p);
1680 *q++=GetPixelBlue(image,p);
1681 *q++=(Quantum) 0;
1682 p+=(ptrdiff_t) GetPixelChannels(image);
1683 }
1684 }
1685 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1686 }
1687 length=strlen(map);
1688 for (y=0; y < (ssize_t) roi->height; y++)
1689 {
1690 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1691 if (p == (const Quantum *) NULL)
1692 break;
1693 for (x=0; x < (ssize_t) roi->width; x++)
1694 {
1695 ssize_t
1696 i;
1697
1698 for (i=0; i < (ssize_t) length; i++)
1699 {
1700 *q=(Quantum) 0;
1701 switch (quantum_map[i])
1702 {
1703 case RedQuantum:
1704 case CyanQuantum:
1705 {
1706 *q=GetPixelRed(image,p);
1707 break;
1708 }
1709 case GreenQuantum:
1710 case MagentaQuantum:
1711 {
1712 *q=GetPixelGreen(image,p);
1713 break;
1714 }
1715 case BlueQuantum:
1716 case YellowQuantum:
1717 {
1718 *q=GetPixelBlue(image,p);
1719 break;
1720 }
1721 case AlphaQuantum:
1722 {
1723 *q=GetPixelAlpha(image,p);
1724 break;
1725 }
1726 case OpacityQuantum:
1727 {
1728 *q=GetPixelAlpha(image,p);
1729 break;
1730 }
1731 case BlackQuantum:
1732 {
1733 if (image->colorspace == CMYKColorspace)
1734 *q=GetPixelBlack(image,p);
1735 break;
1736 }
1737 case IndexQuantum:
1738 {
1739 *q=ClampToQuantum(GetPixelIntensity(image,p));
1740 break;
1741 }
1742 default:
1743 {
1744 *q=(Quantum) 0;
1745 break;
1746 }
1747 }
1748 q++;
1749 }
1750 p+=(ptrdiff_t) GetPixelChannels(image);
1751 }
1752 }
1753 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1754}
1755
1756static MagickBooleanType ExportShortPixel(const Image *image,
1757 const RectangleInfo *roi,const char *magick_restrict map,
1758 const QuantumType *quantum_map,void *pixels,ExceptionInfo *exception)
1759{
1760 const Quantum
1761 *magick_restrict p;
1762
1763 ssize_t
1764 x;
1765
1766 unsigned short
1767 *magick_restrict q;
1768
1769 size_t
1770 length;
1771
1772 ssize_t
1773 y;
1774
1775 q=(unsigned short *) pixels;
1776 if (LocaleCompare(map,"BGR") == 0)
1777 {
1778 for (y=0; y < (ssize_t) roi->height; y++)
1779 {
1780 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1781 if (p == (const Quantum *) NULL)
1782 break;
1783 for (x=0; x < (ssize_t) roi->width; x++)
1784 {
1785 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1786 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1787 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1788 p+=(ptrdiff_t) GetPixelChannels(image);
1789 }
1790 }
1791 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1792 }
1793 if (LocaleCompare(map,"BGRA") == 0)
1794 {
1795 for (y=0; y < (ssize_t) roi->height; y++)
1796 {
1797 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1798 if (p == (const Quantum *) NULL)
1799 break;
1800 for (x=0; x < (ssize_t) roi->width; x++)
1801 {
1802 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1803 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1804 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1805 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1806 p+=(ptrdiff_t) GetPixelChannels(image);
1807 }
1808 }
1809 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1810 }
1811 if (LocaleCompare(map,"BGRP") == 0)
1812 {
1813 for (y=0; y < (ssize_t) roi->height; y++)
1814 {
1815 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1816 if (p == (const Quantum *) NULL)
1817 break;
1818 for (x=0; x < (ssize_t) roi->width; x++)
1819 {
1820 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1821 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1822 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1823 *q++=0;
1824 p+=(ptrdiff_t) GetPixelChannels(image);
1825 }
1826 }
1827 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1828 }
1829 if (LocaleCompare(map,"I") == 0)
1830 {
1831 for (y=0; y < (ssize_t) roi->height; y++)
1832 {
1833 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1834 if (p == (const Quantum *) NULL)
1835 break;
1836 for (x=0; x < (ssize_t) roi->width; x++)
1837 {
1838 *q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1839 p+=(ptrdiff_t) GetPixelChannels(image);
1840 }
1841 }
1842 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1843 }
1844 if (LocaleCompare(map,"RGB") == 0)
1845 {
1846 for (y=0; y < (ssize_t) roi->height; y++)
1847 {
1848 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1849 if (p == (const Quantum *) NULL)
1850 break;
1851 for (x=0; x < (ssize_t) roi->width; x++)
1852 {
1853 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1854 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1855 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1856 p+=(ptrdiff_t) GetPixelChannels(image);
1857 }
1858 }
1859 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1860 }
1861 if (LocaleCompare(map,"RGBA") == 0)
1862 {
1863 for (y=0; y < (ssize_t) roi->height; y++)
1864 {
1865 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1866 if (p == (const Quantum *) NULL)
1867 break;
1868 for (x=0; x < (ssize_t) roi->width; x++)
1869 {
1870 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1871 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1872 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1873 *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1874 p+=(ptrdiff_t) GetPixelChannels(image);
1875 }
1876 }
1877 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1878 }
1879 if (LocaleCompare(map,"RGBP") == 0)
1880 {
1881 for (y=0; y < (ssize_t) roi->height; y++)
1882 {
1883 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1884 if (p == (const Quantum *) NULL)
1885 break;
1886 for (x=0; x < (ssize_t) roi->width; x++)
1887 {
1888 *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1889 *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1890 *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1891 *q++=0;
1892 p+=(ptrdiff_t) GetPixelChannels(image);
1893 }
1894 }
1895 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1896 }
1897 length=strlen(map);
1898 for (y=0; y < (ssize_t) roi->height; y++)
1899 {
1900 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1901 if (p == (const Quantum *) NULL)
1902 break;
1903 for (x=0; x < (ssize_t) roi->width; x++)
1904 {
1905 ssize_t
1906 i;
1907
1908 for (i=0; i < (ssize_t) length; i++)
1909 {
1910 *q=0;
1911 switch (quantum_map[i])
1912 {
1913 case RedQuantum:
1914 case CyanQuantum:
1915 {
1916 *q=ScaleQuantumToShort(GetPixelRed(image,p));
1917 break;
1918 }
1919 case GreenQuantum:
1920 case MagentaQuantum:
1921 {
1922 *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1923 break;
1924 }
1925 case BlueQuantum:
1926 case YellowQuantum:
1927 {
1928 *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1929 break;
1930 }
1931 case AlphaQuantum:
1932 {
1933 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1934 break;
1935 }
1936 case OpacityQuantum:
1937 {
1938 *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1939 break;
1940 }
1941 case BlackQuantum:
1942 {
1943 if (image->colorspace == CMYKColorspace)
1944 *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1945 break;
1946 }
1947 case IndexQuantum:
1948 {
1949 *q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1950 break;
1951 }
1952 default:
1953 break;
1954 }
1955 q++;
1956 }
1957 p+=(ptrdiff_t) GetPixelChannels(image);
1958 }
1959 }
1960 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
1961}
1962
1963MagickExport MagickBooleanType ExportImagePixels(const Image *image,
1964 const ssize_t x,const ssize_t y,const size_t width,const size_t height,
1965 const char *map,const StorageType type,void *pixels,ExceptionInfo *exception)
1966{
1967 MagickBooleanType
1968 status;
1969
1970 QuantumType
1971 *quantum_map;
1972
1973 RectangleInfo
1974 roi;
1975
1976 ssize_t
1977 i;
1978
1979 size_t
1980 length;
1981
1982 assert(image != (Image *) NULL);
1983 assert(image->signature == MagickCoreSignature);
1984 if (IsEventLogging() != MagickFalse)
1985 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1986 length=strlen(map);
1987 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1988 if (quantum_map == (QuantumType *) NULL)
1989 {
1990 (void) ThrowMagickException(exception,GetMagickModule(),
1991 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1992 return(MagickFalse);
1993 }
1994 for (i=0; i < (ssize_t) length; i++)
1995 {
1996 switch (map[i])
1997 {
1998 case 'A':
1999 case 'a':
2000 {
2001 quantum_map[i]=AlphaQuantum;
2002 break;
2003 }
2004 case 'B':
2005 case 'b':
2006 {
2007 quantum_map[i]=BlueQuantum;
2008 break;
2009 }
2010 case 'C':
2011 case 'c':
2012 {
2013 quantum_map[i]=CyanQuantum;
2014 if (image->colorspace == CMYKColorspace)
2015 break;
2016 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2017 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2018 "ColorSeparatedImageRequired","`%s'",map);
2019 return(MagickFalse);
2020 }
2021 case 'g':
2022 case 'G':
2023 {
2024 quantum_map[i]=GreenQuantum;
2025 break;
2026 }
2027 case 'I':
2028 case 'i':
2029 {
2030 quantum_map[i]=IndexQuantum;
2031 break;
2032 }
2033 case 'K':
2034 case 'k':
2035 {
2036 quantum_map[i]=BlackQuantum;
2037 if (image->colorspace == CMYKColorspace)
2038 break;
2039 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2040 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2041 "ColorSeparatedImageRequired","`%s'",map);
2042 return(MagickFalse);
2043 }
2044 case 'M':
2045 case 'm':
2046 {
2047 quantum_map[i]=MagentaQuantum;
2048 if (image->colorspace == CMYKColorspace)
2049 break;
2050 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2051 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2052 "ColorSeparatedImageRequired","`%s'",map);
2053 return(MagickFalse);
2054 }
2055 case 'o':
2056 case 'O':
2057 {
2058 quantum_map[i]=OpacityQuantum;
2059 break;
2060 }
2061 case 'P':
2062 case 'p':
2063 {
2064 quantum_map[i]=UndefinedQuantum;
2065 break;
2066 }
2067 case 'R':
2068 case 'r':
2069 {
2070 quantum_map[i]=RedQuantum;
2071 break;
2072 }
2073 case 'Y':
2074 case 'y':
2075 {
2076 quantum_map[i]=YellowQuantum;
2077 if (image->colorspace == CMYKColorspace)
2078 break;
2079 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2080 (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2081 "ColorSeparatedImageRequired","`%s'",map);
2082 return(MagickFalse);
2083 }
2084 default:
2085 {
2086 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2087 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2088 "UnrecognizedPixelMap","`%s'",map);
2089 return(MagickFalse);
2090 }
2091 }
2092 }
2093 roi.width=width;
2094 roi.height=height;
2095 roi.x=x;
2096 roi.y=y;
2097 switch (type)
2098 {
2099 case CharPixel:
2100 {
2101 status=ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
2102 break;
2103 }
2104 case DoublePixel:
2105 {
2106 status=ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
2107 break;
2108 }
2109 case FloatPixel:
2110 {
2111 status=ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
2112 break;
2113 }
2114 case LongPixel:
2115 {
2116 status=ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
2117 break;
2118 }
2119 case LongLongPixel:
2120 {
2121 status=ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
2122 break;
2123 }
2124 case QuantumPixel:
2125 {
2126 status=ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
2127 break;
2128 }
2129 case ShortPixel:
2130 {
2131 status=ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
2132 break;
2133 }
2134 default:
2135 {
2136 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
2137 "UnrecognizedPixelMap","`%s'",map);
2138 status=MagickFalse;
2139 }
2140 }
2141 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2142 return(status);
2143}
2144␌
2145/*
2146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2147% %
2148% %
2149% %
2150% G e t P i x e l I n f o %
2151% %
2152% %
2153% %
2154%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2155%
2156% GetPixelInfo() initializes the PixelInfo structure.
2157%
2158% The format of the GetPixelInfo method is:
2159%
2160% GetPixelInfo(const Image *image,PixelInfo *pixel)
2161%
2162% A description of each parameter follows:
2163%
2164% o image: the image. (optional - may be NULL)
2165%
2166% o pixel: Specifies a pointer to a PixelInfo structure.
2167%
2168*/
2169MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
2170{
2171 (void) memset(pixel,0,sizeof(*pixel));
2172 pixel->storage_class=DirectClass;
2173 pixel->colorspace=sRGBColorspace;
2174 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2175 pixel->alpha_trait=UndefinedPixelTrait;
2176 pixel->alpha=(double) OpaqueAlpha;
2177 if (image == (const Image *) NULL)
2178 return;
2179 pixel->storage_class=image->storage_class;
2180 pixel->colorspace=image->colorspace;
2181 pixel->alpha_trait=image->alpha_trait;
2182 pixel->depth=image->depth;
2183 pixel->fuzz=image->fuzz;
2184}
2185␌
2186/*
2187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2188% %
2189% %
2190% %
2191% G e t P i x e l I n d o I n t e n s i t y %
2192% %
2193% %
2194% %
2195%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2196%
2197% GetPixelInfoIntensity() returns a single sample intensity value from the red,
2198% green, and blue components of a pixel based on the selected method:
2199%
2200% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B'
2201% Rec601Luminance 0.298839R + 0.586811G + 0.114350B
2202% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B'
2203% Rec709Luminance 0.212656R + 0.715158G + 0.072186B
2204% Brightness max(R', G', B')
2205% Lightness (min(R', G', B') + max(R', G', B')) / 2.0
2206%
2207% MS (R^2 + G^2 + B^2) / 3.0
2208% RMS sqrt((R^2 + G^2 + B^2) / 3.0
2209% Average (R + G + B') / 3.0
2210%
2211% The format of the GetPixelInfoIntensity method is:
2212%
2213% MagickRealType GetPixelInfoIntensity(const Image *image,
2214% const Quantum *pixel)
2215%
2216% A description of each parameter follows:
2217%
2218% o image: the image.
2219%
2220% o pixel: Specifies a pointer to a Quantum structure.
2221%
2222*/
2223MagickExport MagickRealType GetPixelInfoIntensity(
2224 const Image *magick_restrict image,const PixelInfo *magick_restrict pixel)
2225{
2226 MagickRealType
2227 blue,
2228 green,
2229 red,
2230 intensity;
2231
2232 PixelIntensityMethod
2233 method;
2234
2235 method=Rec709LumaPixelIntensityMethod;
2236 if (image != (const Image *) NULL)
2237 method=image->intensity;
2238 red=pixel->red;
2239 green=pixel->green;
2240 blue=pixel->blue;
2241 switch (method)
2242 {
2243 case AveragePixelIntensityMethod:
2244 {
2245 intensity=(red+green+blue)/3.0;
2246 break;
2247 }
2248 case BrightnessPixelIntensityMethod:
2249 {
2250 intensity=MagickMax(MagickMax(red,green),blue);
2251 break;
2252 }
2253 case LightnessPixelIntensityMethod:
2254 {
2255 intensity=(MagickMin(MagickMin(red,green),blue)+
2256 MagickMax(MagickMax(red,green),blue))/2.0;
2257 break;
2258 }
2259 case MSPixelIntensityMethod:
2260 {
2261 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2262 (3.0*(double) QuantumRange));
2263 break;
2264 }
2265 case Rec601LumaPixelIntensityMethod:
2266 {
2267 if (pixel->colorspace == RGBColorspace)
2268 {
2269 red=EncodePixelGamma(red);
2270 green=EncodePixelGamma(green);
2271 blue=EncodePixelGamma(blue);
2272 }
2273 intensity=0.298839*red+0.586811*green+0.114350*blue;
2274 break;
2275 }
2276 case Rec601LuminancePixelIntensityMethod:
2277 {
2278 if (pixel->colorspace == sRGBColorspace)
2279 {
2280 red=DecodePixelGamma(red);
2281 green=DecodePixelGamma(green);
2282 blue=DecodePixelGamma(blue);
2283 }
2284 intensity=0.298839*red+0.586811*green+0.114350*blue;
2285 break;
2286 }
2287 case Rec709LumaPixelIntensityMethod:
2288 default:
2289 {
2290 if (pixel->colorspace == RGBColorspace)
2291 {
2292 red=EncodePixelGamma(red);
2293 green=EncodePixelGamma(green);
2294 blue=EncodePixelGamma(blue);
2295 }
2296 intensity=0.212656*red+0.715158*green+0.072186*blue;
2297 break;
2298 }
2299 case Rec709LuminancePixelIntensityMethod:
2300 {
2301 if (pixel->colorspace == sRGBColorspace)
2302 {
2303 red=DecodePixelGamma(red);
2304 green=DecodePixelGamma(green);
2305 blue=DecodePixelGamma(blue);
2306 }
2307 intensity=0.212656*red+0.715158*green+0.072186*blue;
2308 break;
2309 }
2310 case RMSPixelIntensityMethod:
2311 {
2312 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2313 sqrt(3.0));
2314 break;
2315 }
2316 }
2317 return(intensity);
2318}
2319␌
2320/*
2321%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2322% %
2323% %
2324% %
2325% G e t P i x e l I n t e n s i t y %
2326% %
2327% %
2328% %
2329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2330%
2331% GetPixelIntensity() returns a single sample intensity value from the red,
2332% green, and blue components of a pixel based on the selected method:
2333%
2334% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B'
2335% Rec601Luminance 0.298839R + 0.586811G + 0.114350B
2336% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B'
2337% Rec709Luminance 0.212656R + 0.715158G + 0.072186B
2338% Brightness max(R', G', B')
2339% Lightness (min(R', G', B') + max(R', G', B')) / 2.0
2340%
2341% MS (R^2 + G^2 + B^2) / 3.0
2342% RMS sqrt((R^2 + G^2 + B^2) / 3.0
2343% Average (R + G + B') / 3.0
2344%
2345% The format of the GetPixelIntensity method is:
2346%
2347% MagickRealType GetPixelIntensity(const Image *image,
2348% const Quantum *pixel)
2349%
2350% A description of each parameter follows:
2351%
2352% o image: the image.
2353%
2354% o pixel: Specifies a pointer to a Quantum structure.
2355%
2356*/
2357MagickExport MagickRealType GetPixelIntensity(
2358 const Image *magick_restrict image,const Quantum *magick_restrict pixel)
2359{
2360 MagickRealType
2361 blue,
2362 green,
2363 red,
2364 intensity;
2365
2366 red=(MagickRealType) GetPixelRed(image,pixel);
2367 if (image->number_channels == 1)
2368 return(red);
2369 green=(MagickRealType) GetPixelGreen(image,pixel);
2370 blue=(MagickRealType) GetPixelBlue(image,pixel);
2371 switch (image->intensity)
2372 {
2373 case AveragePixelIntensityMethod:
2374 {
2375 intensity=(red+green+blue)/3.0;
2376 break;
2377 }
2378 case BrightnessPixelIntensityMethod:
2379 {
2380 intensity=MagickMax(MagickMax(red,green),blue);
2381 break;
2382 }
2383 case LightnessPixelIntensityMethod:
2384 {
2385 intensity=(MagickMin(MagickMin(red,green),blue)+
2386 MagickMax(MagickMax(red,green),blue))/2.0;
2387 break;
2388 }
2389 case MSPixelIntensityMethod:
2390 {
2391 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2392 (3.0*(double) QuantumRange));
2393 break;
2394 }
2395 case Rec601LumaPixelIntensityMethod:
2396 {
2397 if ((image->colorspace == RGBColorspace) ||
2398 (image->colorspace == LinearGRAYColorspace))
2399 {
2400 red=EncodePixelGamma(red);
2401 green=EncodePixelGamma(green);
2402 blue=EncodePixelGamma(blue);
2403 }
2404 intensity=0.298839*red+0.586811*green+0.114350*blue;
2405 break;
2406 }
2407 case Rec601LuminancePixelIntensityMethod:
2408 {
2409 if ((image->colorspace == sRGBColorspace) ||
2410 (image->colorspace == GRAYColorspace))
2411 {
2412 red=DecodePixelGamma(red);
2413 green=DecodePixelGamma(green);
2414 blue=DecodePixelGamma(blue);
2415 }
2416 intensity=0.298839*red+0.586811*green+0.114350*blue;
2417 break;
2418 }
2419 case Rec709LumaPixelIntensityMethod:
2420 default:
2421 {
2422 if ((image->colorspace == RGBColorspace) ||
2423 (image->colorspace == LinearGRAYColorspace))
2424 {
2425 red=EncodePixelGamma(red);
2426 green=EncodePixelGamma(green);
2427 blue=EncodePixelGamma(blue);
2428 }
2429 intensity=0.212656*red+0.715158*green+0.072186*blue;
2430 break;
2431 }
2432 case Rec709LuminancePixelIntensityMethod:
2433 {
2434 if ((image->colorspace == sRGBColorspace) ||
2435 (image->colorspace == GRAYColorspace))
2436 {
2437 red=DecodePixelGamma(red);
2438 green=DecodePixelGamma(green);
2439 blue=DecodePixelGamma(blue);
2440 }
2441 intensity=0.212656*red+0.715158*green+0.072186*blue;
2442 break;
2443 }
2444 case RMSPixelIntensityMethod:
2445 {
2446 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2447 sqrt(3.0));
2448 break;
2449 }
2450 }
2451 return(intensity);
2452}
2453␌
2454/*
2455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2456% %
2457% %
2458% %
2459% I m p o r t I m a g e P i x e l s %
2460% %
2461% %
2462% %
2463%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2464%
2465% ImportImagePixels() accepts pixel data and stores in the image at the
2466% location you specify. The method returns MagickTrue on success otherwise
2467% MagickFalse if an error is encountered. The pixel data can be either char,
2468% Quantum, short int, unsigned int, unsigned long long, float, or double in
2469% the order specified by map.
2470%
2471% Suppose your want to upload the first scanline of a 640x480 image from
2472% character data in red-green-blue order:
2473%
2474% ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2475%
2476% The format of the ImportImagePixels method is:
2477%
2478% MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2479% const ssize_t y,const size_t width,const size_t height,
2480% const char *map,const StorageType type,const void *pixels,
2481% ExceptionInfo *exception)
2482%
2483% A description of each parameter follows:
2484%
2485% o image: the image.
2486%
2487% o x,y,width,height: These values define the perimeter
2488% of a region of pixels you want to define.
2489%
2490% o map: This string reflects the expected ordering of the pixel array.
2491% It can be any combination or order of R = red, G = green, B = blue,
2492% A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2493% Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2494% P = pad.
2495%
2496% o type: Define the data type of the pixels. Float and double types are
2497% normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
2498% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
2499% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
2500% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
2501%
2502% o pixels: This array of values contain the pixel components as defined by
2503% map and type. You must preallocate this array where the expected
2504% length varies depending on the values of width, height, map, and type.
2505%
2506% o exception: return any errors or warnings in this structure.
2507%
2508*/
2509
2510static MagickBooleanType ImportCharPixel(Image *image,const RectangleInfo *roi,
2511 const char *magick_restrict map,const QuantumType *quantum_map,
2512 const void *pixels,ExceptionInfo *exception)
2513{
2514 const unsigned char
2515 *magick_restrict p;
2516
2517 Quantum
2518 *magick_restrict q;
2519
2520 ssize_t
2521 x;
2522
2523 size_t
2524 length;
2525
2526 ssize_t
2527 y;
2528
2529 p=(const unsigned char *) pixels;
2530 if (LocaleCompare(map,"BGR") == 0)
2531 {
2532 for (y=0; y < (ssize_t) roi->height; y++)
2533 {
2534 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2535 if (q == (Quantum *) NULL)
2536 break;
2537 for (x=0; x < (ssize_t) roi->width; x++)
2538 {
2539 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2540 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2541 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2542 q+=(ptrdiff_t) GetPixelChannels(image);
2543 }
2544 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2545 break;
2546 }
2547 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2548 }
2549 if (LocaleCompare(map,"BGRA") == 0)
2550 {
2551 for (y=0; y < (ssize_t) roi->height; y++)
2552 {
2553 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2554 if (q == (Quantum *) NULL)
2555 break;
2556 for (x=0; x < (ssize_t) roi->width; x++)
2557 {
2558 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2559 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2560 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2561 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2562 q+=(ptrdiff_t) GetPixelChannels(image);
2563 }
2564 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2565 break;
2566 }
2567 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2568 }
2569 if (LocaleCompare(map,"BGRO") == 0)
2570 {
2571 for (y=0; y < (ssize_t) roi->height; y++)
2572 {
2573 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2574 if (q == (Quantum *) NULL)
2575 break;
2576 for (x=0; x < (ssize_t) roi->width; x++)
2577 {
2578 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2579 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2580 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2581 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2582 q+=(ptrdiff_t) GetPixelChannels(image);
2583 }
2584 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2585 break;
2586 }
2587 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2588 }
2589 if (LocaleCompare(map,"BGRP") == 0)
2590 {
2591 for (y=0; y < (ssize_t) roi->height; y++)
2592 {
2593 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2594 if (q == (Quantum *) NULL)
2595 break;
2596 for (x=0; x < (ssize_t) roi->width; x++)
2597 {
2598 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2599 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2600 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2601 p++;
2602 q+=(ptrdiff_t) GetPixelChannels(image);
2603 }
2604 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2605 break;
2606 }
2607 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2608 }
2609 if (LocaleCompare(map,"I") == 0)
2610 {
2611 for (y=0; y < (ssize_t) roi->height; y++)
2612 {
2613 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2614 if (q == (Quantum *) NULL)
2615 break;
2616 for (x=0; x < (ssize_t) roi->width; x++)
2617 {
2618 SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2619 q+=(ptrdiff_t) GetPixelChannels(image);
2620 }
2621 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2622 break;
2623 }
2624 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2625 }
2626 if (LocaleCompare(map,"RGB") == 0)
2627 {
2628 for (y=0; y < (ssize_t) roi->height; y++)
2629 {
2630 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2631 if (q == (Quantum *) NULL)
2632 break;
2633 for (x=0; x < (ssize_t) roi->width; x++)
2634 {
2635 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2636 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2637 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2638 q+=(ptrdiff_t) GetPixelChannels(image);
2639 }
2640 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2641 break;
2642 }
2643 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2644 }
2645 if (LocaleCompare(map,"RGBA") == 0)
2646 {
2647 for (y=0; y < (ssize_t) roi->height; y++)
2648 {
2649 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2650 if (q == (Quantum *) NULL)
2651 break;
2652 for (x=0; x < (ssize_t) roi->width; x++)
2653 {
2654 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2655 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2656 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2657 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2658 q+=(ptrdiff_t) GetPixelChannels(image);
2659 }
2660 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2661 break;
2662 }
2663 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2664 }
2665 if (LocaleCompare(map,"RGBO") == 0)
2666 {
2667 for (y=0; y < (ssize_t) roi->height; y++)
2668 {
2669 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2670 if (q == (Quantum *) NULL)
2671 break;
2672 for (x=0; x < (ssize_t) roi->width; x++)
2673 {
2674 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2675 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2676 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2677 SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2678 q+=(ptrdiff_t) GetPixelChannels(image);
2679 }
2680 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2681 break;
2682 }
2683 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2684 }
2685 if (LocaleCompare(map,"RGBP") == 0)
2686 {
2687 for (y=0; y < (ssize_t) roi->height; y++)
2688 {
2689 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2690 if (q == (Quantum *) NULL)
2691 break;
2692 for (x=0; x < (ssize_t) roi->width; x++)
2693 {
2694 SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2695 SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2696 SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2697 p++;
2698 q+=(ptrdiff_t) GetPixelChannels(image);
2699 }
2700 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2701 break;
2702 }
2703 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2704 }
2705 length=strlen(map);
2706 for (y=0; y < (ssize_t) roi->height; y++)
2707 {
2708 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2709 if (q == (Quantum *) NULL)
2710 break;
2711 for (x=0; x < (ssize_t) roi->width; x++)
2712 {
2713 ssize_t
2714 i;
2715
2716 for (i=0; i < (ssize_t) length; i++)
2717 {
2718 switch (quantum_map[i])
2719 {
2720 case RedQuantum:
2721 case CyanQuantum:
2722 {
2723 SetPixelRed(image,ScaleCharToQuantum(*p),q);
2724 break;
2725 }
2726 case GreenQuantum:
2727 case MagentaQuantum:
2728 {
2729 SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2730 break;
2731 }
2732 case BlueQuantum:
2733 case YellowQuantum:
2734 {
2735 SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2736 break;
2737 }
2738 case AlphaQuantum:
2739 {
2740 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2741 break;
2742 }
2743 case OpacityQuantum:
2744 {
2745 SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2746 break;
2747 }
2748 case BlackQuantum:
2749 {
2750 SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2751 break;
2752 }
2753 case IndexQuantum:
2754 {
2755 SetPixelGray(image,ScaleCharToQuantum(*p),q);
2756 break;
2757 }
2758 default:
2759 break;
2760 }
2761 p++;
2762 }
2763 q+=(ptrdiff_t) GetPixelChannels(image);
2764 }
2765 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2766 break;
2767 }
2768 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2769}
2770
2771static MagickBooleanType ImportDoublePixel(Image *image,
2772 const RectangleInfo *roi,const char *magick_restrict map,
2773 const QuantumType *quantum_map,const void *pixels,ExceptionInfo *exception)
2774{
2775 const double
2776 *magick_restrict p;
2777
2778 Quantum
2779 *magick_restrict q;
2780
2781 ssize_t
2782 x;
2783
2784 size_t
2785 length;
2786
2787 ssize_t
2788 y;
2789
2790 p=(const double *) pixels;
2791 if (LocaleCompare(map,"BGR") == 0)
2792 {
2793 for (y=0; y < (ssize_t) roi->height; y++)
2794 {
2795 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2796 if (q == (Quantum *) NULL)
2797 break;
2798 for (x=0; x < (ssize_t) roi->width; x++)
2799 {
2800 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2801 p++;
2802 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2803 p++;
2804 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2805 p++;
2806 q+=(ptrdiff_t) GetPixelChannels(image);
2807 }
2808 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2809 break;
2810 }
2811 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2812 }
2813 if (LocaleCompare(map,"BGRA") == 0)
2814 {
2815 for (y=0; y < (ssize_t) roi->height; y++)
2816 {
2817 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2818 if (q == (Quantum *) NULL)
2819 break;
2820 for (x=0; x < (ssize_t) roi->width; x++)
2821 {
2822 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2823 p++;
2824 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2825 p++;
2826 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2827 p++;
2828 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2829 p++;
2830 q+=(ptrdiff_t) GetPixelChannels(image);
2831 }
2832 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2833 break;
2834 }
2835 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2836 }
2837 if (LocaleCompare(map,"BGRP") == 0)
2838 {
2839 for (y=0; y < (ssize_t) roi->height; y++)
2840 {
2841 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2842 if (q == (Quantum *) NULL)
2843 break;
2844 for (x=0; x < (ssize_t) roi->width; x++)
2845 {
2846 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2847 p++;
2848 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2849 p++;
2850 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2851 p++;
2852 p++;
2853 q+=(ptrdiff_t) GetPixelChannels(image);
2854 }
2855 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2856 break;
2857 }
2858 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2859 }
2860 if (LocaleCompare(map,"I") == 0)
2861 {
2862 for (y=0; y < (ssize_t) roi->height; y++)
2863 {
2864 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2865 if (q == (Quantum *) NULL)
2866 break;
2867 for (x=0; x < (ssize_t) roi->width; x++)
2868 {
2869 SetPixelGray(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2870 p++;
2871 q+=(ptrdiff_t) GetPixelChannels(image);
2872 }
2873 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2874 break;
2875 }
2876 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2877 }
2878 if (LocaleCompare(map,"RGB") == 0)
2879 {
2880 for (y=0; y < (ssize_t) roi->height; y++)
2881 {
2882 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2883 if (q == (Quantum *) NULL)
2884 break;
2885 for (x=0; x < (ssize_t) roi->width; x++)
2886 {
2887 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2888 p++;
2889 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2890 p++;
2891 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2892 p++;
2893 q+=(ptrdiff_t) GetPixelChannels(image);
2894 }
2895 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2896 break;
2897 }
2898 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2899 }
2900 if (LocaleCompare(map,"RGBA") == 0)
2901 {
2902 for (y=0; y < (ssize_t) roi->height; y++)
2903 {
2904 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2905 if (q == (Quantum *) NULL)
2906 break;
2907 for (x=0; x < (ssize_t) roi->width; x++)
2908 {
2909 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2910 p++;
2911 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2912 p++;
2913 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2914 p++;
2915 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2916 p++;
2917 q+=(ptrdiff_t) GetPixelChannels(image);
2918 }
2919 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2920 break;
2921 }
2922 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2923 }
2924 if (LocaleCompare(map,"RGBP") == 0)
2925 {
2926 for (y=0; y < (ssize_t) roi->height; y++)
2927 {
2928 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2929 if (q == (Quantum *) NULL)
2930 break;
2931 for (x=0; x < (ssize_t) roi->width; x++)
2932 {
2933 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2934 p++;
2935 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2936 p++;
2937 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2938 p++;
2939 q+=(ptrdiff_t) GetPixelChannels(image);
2940 }
2941 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2942 break;
2943 }
2944 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
2945 }
2946 length=strlen(map);
2947 for (y=0; y < (ssize_t) roi->height; y++)
2948 {
2949 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2950 if (q == (Quantum *) NULL)
2951 break;
2952 for (x=0; x < (ssize_t) roi->width; x++)
2953 {
2954 ssize_t
2955 i;
2956
2957 for (i=0; i < (ssize_t) length; i++)
2958 {
2959 switch (quantum_map[i])
2960 {
2961 case RedQuantum:
2962 case CyanQuantum:
2963 {
2964 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2965 break;
2966 }
2967 case GreenQuantum:
2968 case MagentaQuantum:
2969 {
2970 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2971 break;
2972 }
2973 case BlueQuantum:
2974 case YellowQuantum:
2975 {
2976 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2977 break;
2978 }
2979 case AlphaQuantum:
2980 {
2981 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2982 break;
2983 }
2984 case OpacityQuantum:
2985 {
2986 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2987 break;
2988 }
2989 case BlackQuantum:
2990 {
2991 SetPixelBlack(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2992 break;
2993 }
2994 case IndexQuantum:
2995 {
2996 SetPixelGray(image,ClampToQuantum((double) QuantumRange*(*p)),q);
2997 break;
2998 }
2999 default:
3000 break;
3001 }
3002 p++;
3003 }
3004 q+=(ptrdiff_t) GetPixelChannels(image);
3005 }
3006 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3007 break;
3008 }
3009 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3010}
3011
3012static MagickBooleanType ImportFloatPixel(Image *image,const RectangleInfo *roi,
3013 const char *magick_restrict map,const QuantumType *quantum_map,
3014 const void *pixels,ExceptionInfo *exception)
3015{
3016 const float
3017 *magick_restrict p;
3018
3019 Quantum
3020 *magick_restrict q;
3021
3022 ssize_t
3023 x;
3024
3025 size_t
3026 length;
3027
3028 ssize_t
3029 y;
3030
3031 p=(const float *) pixels;
3032 if (LocaleCompare(map,"BGR") == 0)
3033 {
3034 for (y=0; y < (ssize_t) roi->height; y++)
3035 {
3036 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3037 if (q == (Quantum *) NULL)
3038 break;
3039 for (x=0; x < (ssize_t) roi->width; x++)
3040 {
3041 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3042 (*p)),q);
3043 p++;
3044 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3045 (*p)),q);
3046 p++;
3047 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3048 (*p)),q);
3049 p++;
3050 q+=(ptrdiff_t) GetPixelChannels(image);
3051 }
3052 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3053 break;
3054 }
3055 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3056 }
3057 if (LocaleCompare(map,"BGRA") == 0)
3058 {
3059 for (y=0; y < (ssize_t) roi->height; y++)
3060 {
3061 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3062 if (q == (Quantum *) NULL)
3063 break;
3064 for (x=0; x < (ssize_t) roi->width; x++)
3065 {
3066 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3067 (*p)),q);
3068 p++;
3069 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3070 (*p)),q);
3071 p++;
3072 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3073 (*p)),q);
3074 p++;
3075 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(double)
3076 (*p)),q);
3077 p++;
3078 q+=(ptrdiff_t) GetPixelChannels(image);
3079 }
3080 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3081 break;
3082 }
3083 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3084 }
3085 if (LocaleCompare(map,"BGRP") == 0)
3086 {
3087 for (y=0; y < (ssize_t) roi->height; y++)
3088 {
3089 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3090 if (q == (Quantum *) NULL)
3091 break;
3092 for (x=0; x < (ssize_t) roi->width; x++)
3093 {
3094 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3095 (*p)),q);
3096 p++;
3097 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3098 (*p)),q);
3099 p++;
3100 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3101 (*p)),q);
3102 p++;
3103 p++;
3104 q+=(ptrdiff_t) GetPixelChannels(image);
3105 }
3106 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3107 break;
3108 }
3109 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3110 }
3111 if (LocaleCompare(map,"I") == 0)
3112 {
3113 for (y=0; y < (ssize_t) roi->height; y++)
3114 {
3115 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3116 if (q == (Quantum *) NULL)
3117 break;
3118 for (x=0; x < (ssize_t) roi->width; x++)
3119 {
3120 SetPixelGray(image,ClampToQuantum((double) QuantumRange*(double)
3121 (*p)),q);
3122 p++;
3123 q+=(ptrdiff_t) GetPixelChannels(image);
3124 }
3125 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3126 break;
3127 }
3128 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3129 }
3130 if (LocaleCompare(map,"RGB") == 0)
3131 {
3132 for (y=0; y < (ssize_t) roi->height; y++)
3133 {
3134 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3135 if (q == (Quantum *) NULL)
3136 break;
3137 for (x=0; x < (ssize_t) roi->width; x++)
3138 {
3139 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3140 (*p)),q);
3141 p++;
3142 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3143 (*p)),q);
3144 p++;
3145 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3146 (*p)),q);
3147 p++;
3148 q+=(ptrdiff_t) GetPixelChannels(image);
3149 }
3150 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3151 break;
3152 }
3153 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3154 }
3155 if (LocaleCompare(map,"RGBA") == 0)
3156 {
3157 for (y=0; y < (ssize_t) roi->height; y++)
3158 {
3159 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3160 if (q == (Quantum *) NULL)
3161 break;
3162 for (x=0; x < (ssize_t) roi->width; x++)
3163 {
3164 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3165 (*p)),q);
3166 p++;
3167 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3168 (*p)),q);
3169 p++;
3170 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3171 (*p)),q);
3172 p++;
3173 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(double)
3174 (*p)),q);
3175 p++;
3176 q+=(ptrdiff_t) GetPixelChannels(image);
3177 }
3178 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3179 break;
3180 }
3181 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3182 }
3183 if (LocaleCompare(map,"RGBP") == 0)
3184 {
3185 for (y=0; y < (ssize_t) roi->height; y++)
3186 {
3187 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3188 if (q == (Quantum *) NULL)
3189 break;
3190 for (x=0; x < (ssize_t) roi->width; x++)
3191 {
3192 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3193 (*p)),q);
3194 p++;
3195 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3196 (*p)),q);
3197 p++;
3198 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3199 (*p)),q);
3200 p++;
3201 q+=(ptrdiff_t) GetPixelChannels(image);
3202 }
3203 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3204 break;
3205 }
3206 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3207 }
3208 length=strlen(map);
3209 for (y=0; y < (ssize_t) roi->height; y++)
3210 {
3211 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3212 if (q == (Quantum *) NULL)
3213 break;
3214 for (x=0; x < (ssize_t) roi->width; x++)
3215 {
3216 ssize_t
3217 i;
3218
3219 for (i=0; i < (ssize_t) length; i++)
3220 {
3221 switch (quantum_map[i])
3222 {
3223 case RedQuantum:
3224 case CyanQuantum:
3225 {
3226 SetPixelRed(image,ClampToQuantum((double) QuantumRange*(double)
3227 (*p)),q);
3228 break;
3229 }
3230 case GreenQuantum:
3231 case MagentaQuantum:
3232 {
3233 SetPixelGreen(image,ClampToQuantum((double) QuantumRange*(double)
3234 (*p)),q);
3235 break;
3236 }
3237 case BlueQuantum:
3238 case YellowQuantum:
3239 {
3240 SetPixelBlue(image,ClampToQuantum((double) QuantumRange*(double)
3241 (*p)),q);
3242 break;
3243 }
3244 case AlphaQuantum:
3245 {
3246 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(double)
3247 (*p)),q);
3248 break;
3249 }
3250 case OpacityQuantum:
3251 {
3252 SetPixelAlpha(image,ClampToQuantum((double) QuantumRange*(double)
3253 (*p)),q);
3254 break;
3255 }
3256 case BlackQuantum:
3257 {
3258 SetPixelBlack(image,ClampToQuantum((double) QuantumRange*(double)
3259 (*p)),q);
3260 break;
3261 }
3262 case IndexQuantum:
3263 {
3264 SetPixelGray(image,ClampToQuantum((double) QuantumRange*(double)
3265 (*p)),q);
3266 break;
3267 }
3268 default:
3269 break;
3270 }
3271 p++;
3272 }
3273 q+=(ptrdiff_t) GetPixelChannels(image);
3274 }
3275 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3276 break;
3277 }
3278 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3279}
3280
3281static MagickBooleanType ImportLongPixel(Image *image,const RectangleInfo *roi,
3282 const char *magick_restrict map,const QuantumType *quantum_map,
3283 const void *pixels,ExceptionInfo *exception)
3284{
3285 const unsigned int
3286 *magick_restrict p;
3287
3288 Quantum
3289 *magick_restrict q;
3290
3291 ssize_t
3292 x;
3293
3294 size_t
3295 length;
3296
3297 ssize_t
3298 y;
3299
3300 p=(const unsigned int *) pixels;
3301 if (LocaleCompare(map,"BGR") == 0)
3302 {
3303 for (y=0; y < (ssize_t) roi->height; y++)
3304 {
3305 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3306 if (q == (Quantum *) NULL)
3307 break;
3308 for (x=0; x < (ssize_t) roi->width; x++)
3309 {
3310 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3311 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3312 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3313 q+=(ptrdiff_t) GetPixelChannels(image);
3314 }
3315 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3316 break;
3317 }
3318 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3319 }
3320 if (LocaleCompare(map,"BGRA") == 0)
3321 {
3322 for (y=0; y < (ssize_t) roi->height; y++)
3323 {
3324 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3325 if (q == (Quantum *) NULL)
3326 break;
3327 for (x=0; x < (ssize_t) roi->width; x++)
3328 {
3329 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3330 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3331 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3332 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3333 q+=(ptrdiff_t) GetPixelChannels(image);
3334 }
3335 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3336 break;
3337 }
3338 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3339 }
3340 if (LocaleCompare(map,"BGRP") == 0)
3341 {
3342 for (y=0; y < (ssize_t) roi->height; y++)
3343 {
3344 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3345 if (q == (Quantum *) NULL)
3346 break;
3347 for (x=0; x < (ssize_t) roi->width; x++)
3348 {
3349 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3350 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3351 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3352 p++;
3353 q+=(ptrdiff_t) GetPixelChannels(image);
3354 }
3355 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3356 break;
3357 }
3358 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3359 }
3360 if (LocaleCompare(map,"I") == 0)
3361 {
3362 for (y=0; y < (ssize_t) roi->height; y++)
3363 {
3364 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3365 if (q == (Quantum *) NULL)
3366 break;
3367 for (x=0; x < (ssize_t) roi->width; x++)
3368 {
3369 SetPixelGray(image,ScaleLongToQuantum(*p++),q);
3370 q+=(ptrdiff_t) GetPixelChannels(image);
3371 }
3372 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3373 break;
3374 }
3375 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3376 }
3377 if (LocaleCompare(map,"RGB") == 0)
3378 {
3379 for (y=0; y < (ssize_t) roi->height; y++)
3380 {
3381 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3382 if (q == (Quantum *) NULL)
3383 break;
3384 for (x=0; x < (ssize_t) roi->width; x++)
3385 {
3386 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3387 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3388 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3389 q+=(ptrdiff_t) GetPixelChannels(image);
3390 }
3391 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3392 break;
3393 }
3394 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3395 }
3396 if (LocaleCompare(map,"RGBA") == 0)
3397 {
3398 for (y=0; y < (ssize_t) roi->height; y++)
3399 {
3400 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3401 if (q == (Quantum *) NULL)
3402 break;
3403 for (x=0; x < (ssize_t) roi->width; x++)
3404 {
3405 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3406 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3407 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3408 SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3409 q+=(ptrdiff_t) GetPixelChannels(image);
3410 }
3411 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3412 break;
3413 }
3414 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3415 }
3416 if (LocaleCompare(map,"RGBP") == 0)
3417 {
3418 for (y=0; y < (ssize_t) roi->height; y++)
3419 {
3420 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3421 if (q == (Quantum *) NULL)
3422 break;
3423 for (x=0; x < (ssize_t) roi->width; x++)
3424 {
3425 SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3426 SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3427 SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3428 p++;
3429 q+=(ptrdiff_t) GetPixelChannels(image);
3430 }
3431 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3432 break;
3433 }
3434 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3435 }
3436 length=strlen(map);
3437 for (y=0; y < (ssize_t) roi->height; y++)
3438 {
3439 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3440 if (q == (Quantum *) NULL)
3441 break;
3442 for (x=0; x < (ssize_t) roi->width; x++)
3443 {
3444 ssize_t
3445 i;
3446
3447 for (i=0; i < (ssize_t) length; i++)
3448 {
3449 switch (quantum_map[i])
3450 {
3451 case RedQuantum:
3452 case CyanQuantum:
3453 {
3454 SetPixelRed(image,ScaleLongToQuantum(*p),q);
3455 break;
3456 }
3457 case GreenQuantum:
3458 case MagentaQuantum:
3459 {
3460 SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3461 break;
3462 }
3463 case BlueQuantum:
3464 case YellowQuantum:
3465 {
3466 SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3467 break;
3468 }
3469 case AlphaQuantum:
3470 {
3471 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3472 break;
3473 }
3474 case OpacityQuantum:
3475 {
3476 SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3477 break;
3478 }
3479 case BlackQuantum:
3480 {
3481 SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3482 break;
3483 }
3484 case IndexQuantum:
3485 {
3486 SetPixelGray(image,ScaleLongToQuantum(*p),q);
3487 break;
3488 }
3489 default:
3490 break;
3491 }
3492 p++;
3493 }
3494 q+=(ptrdiff_t) GetPixelChannels(image);
3495 }
3496 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3497 break;
3498 }
3499 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3500}
3501
3502static MagickBooleanType ImportLongLongPixel(Image *image,
3503 const RectangleInfo *roi,const char *magick_restrict map,
3504 const QuantumType *quantum_map,const void *pixels,ExceptionInfo *exception)
3505{
3506 const MagickSizeType
3507 *magick_restrict p;
3508
3509 Quantum
3510 *magick_restrict q;
3511
3512 ssize_t
3513 x;
3514
3515 size_t
3516 length;
3517
3518 ssize_t
3519 y;
3520
3521 p=(const MagickSizeType *) pixels;
3522 if (LocaleCompare(map,"BGR") == 0)
3523 {
3524 for (y=0; y < (ssize_t) roi->height; y++)
3525 {
3526 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3527 if (q == (Quantum *) NULL)
3528 break;
3529 for (x=0; x < (ssize_t) roi->width; x++)
3530 {
3531 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3532 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3533 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3534 q+=(ptrdiff_t) GetPixelChannels(image);
3535 }
3536 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3537 break;
3538 }
3539 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3540 }
3541 if (LocaleCompare(map,"BGRA") == 0)
3542 {
3543 for (y=0; y < (ssize_t) roi->height; y++)
3544 {
3545 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3546 if (q == (Quantum *) NULL)
3547 break;
3548 for (x=0; x < (ssize_t) roi->width; x++)
3549 {
3550 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3551 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3552 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3553 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3554 q+=(ptrdiff_t) GetPixelChannels(image);
3555 }
3556 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3557 break;
3558 }
3559 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3560 }
3561 if (LocaleCompare(map,"BGRP") == 0)
3562 {
3563 for (y=0; y < (ssize_t) roi->height; y++)
3564 {
3565 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3566 if (q == (Quantum *) NULL)
3567 break;
3568 for (x=0; x < (ssize_t) roi->width; x++)
3569 {
3570 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3571 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3572 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3573 p++;
3574 q+=(ptrdiff_t) GetPixelChannels(image);
3575 }
3576 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3577 break;
3578 }
3579 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3580 }
3581 if (LocaleCompare(map,"I") == 0)
3582 {
3583 for (y=0; y < (ssize_t) roi->height; y++)
3584 {
3585 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3586 if (q == (Quantum *) NULL)
3587 break;
3588 for (x=0; x < (ssize_t) roi->width; x++)
3589 {
3590 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
3591 q+=(ptrdiff_t) GetPixelChannels(image);
3592 }
3593 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3594 break;
3595 }
3596 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3597 }
3598 if (LocaleCompare(map,"RGB") == 0)
3599 {
3600 for (y=0; y < (ssize_t) roi->height; y++)
3601 {
3602 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3603 if (q == (Quantum *) NULL)
3604 break;
3605 for (x=0; x < (ssize_t) roi->width; x++)
3606 {
3607 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3608 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3609 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3610 q+=(ptrdiff_t) GetPixelChannels(image);
3611 }
3612 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3613 break;
3614 }
3615 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3616 }
3617 if (LocaleCompare(map,"RGBA") == 0)
3618 {
3619 for (y=0; y < (ssize_t) roi->height; y++)
3620 {
3621 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3622 if (q == (Quantum *) NULL)
3623 break;
3624 for (x=0; x < (ssize_t) roi->width; x++)
3625 {
3626 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3627 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3628 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3629 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3630 q+=(ptrdiff_t) GetPixelChannels(image);
3631 }
3632 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3633 break;
3634 }
3635 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3636 }
3637 if (LocaleCompare(map,"RGBP") == 0)
3638 {
3639 for (y=0; y < (ssize_t) roi->height; y++)
3640 {
3641 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3642 if (q == (Quantum *) NULL)
3643 break;
3644 for (x=0; x < (ssize_t) roi->width; x++)
3645 {
3646 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3647 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3648 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3649 p++;
3650 q+=(ptrdiff_t) GetPixelChannels(image);
3651 }
3652 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3653 break;
3654 }
3655 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3656 }
3657 length=strlen(map);
3658 for (y=0; y < (ssize_t) roi->height; y++)
3659 {
3660 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3661 if (q == (Quantum *) NULL)
3662 break;
3663 for (x=0; x < (ssize_t) roi->width; x++)
3664 {
3665 ssize_t
3666 i;
3667
3668 for (i=0; i < (ssize_t) length; i++)
3669 {
3670 switch (quantum_map[i])
3671 {
3672 case RedQuantum:
3673 case CyanQuantum:
3674 {
3675 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
3676 break;
3677 }
3678 case GreenQuantum:
3679 case MagentaQuantum:
3680 {
3681 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
3682 break;
3683 }
3684 case BlueQuantum:
3685 case YellowQuantum:
3686 {
3687 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
3688 break;
3689 }
3690 case AlphaQuantum:
3691 {
3692 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3693 break;
3694 }
3695 case OpacityQuantum:
3696 {
3697 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3698 break;
3699 }
3700 case BlackQuantum:
3701 {
3702 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
3703 break;
3704 }
3705 case IndexQuantum:
3706 {
3707 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
3708 break;
3709 }
3710 default:
3711 break;
3712 }
3713 p++;
3714 }
3715 q+=(ptrdiff_t) GetPixelChannels(image);
3716 }
3717 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3718 break;
3719 }
3720 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3721}
3722
3723static MagickBooleanType ImportQuantumPixel(Image *image,
3724 const RectangleInfo *roi,const char *magick_restrict map,
3725 const QuantumType *quantum_map,const void *pixels,ExceptionInfo *exception)
3726{
3727 const Quantum
3728 *magick_restrict p;
3729
3730 Quantum
3731 *magick_restrict q;
3732
3733 ssize_t
3734 x;
3735
3736 size_t
3737 length;
3738
3739 ssize_t
3740 y;
3741
3742 p=(const Quantum *) pixels;
3743 if (LocaleCompare(map,"BGR") == 0)
3744 {
3745 for (y=0; y < (ssize_t) roi->height; y++)
3746 {
3747 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3748 if (q == (Quantum *) NULL)
3749 break;
3750 for (x=0; x < (ssize_t) roi->width; x++)
3751 {
3752 SetPixelBlue(image,*p++,q);
3753 SetPixelGreen(image,*p++,q);
3754 SetPixelRed(image,*p++,q);
3755 q+=(ptrdiff_t) GetPixelChannels(image);
3756 }
3757 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3758 break;
3759 }
3760 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3761 }
3762 if (LocaleCompare(map,"BGRA") == 0)
3763 {
3764 for (y=0; y < (ssize_t) roi->height; y++)
3765 {
3766 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3767 if (q == (Quantum *) NULL)
3768 break;
3769 for (x=0; x < (ssize_t) roi->width; x++)
3770 {
3771 SetPixelBlue(image,*p++,q);
3772 SetPixelGreen(image,*p++,q);
3773 SetPixelRed(image,*p++,q);
3774 SetPixelAlpha(image,*p++,q);
3775 q+=(ptrdiff_t) GetPixelChannels(image);
3776 }
3777 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3778 break;
3779 }
3780 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3781 }
3782 if (LocaleCompare(map,"BGRP") == 0)
3783 {
3784 for (y=0; y < (ssize_t) roi->height; y++)
3785 {
3786 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3787 if (q == (Quantum *) NULL)
3788 break;
3789 for (x=0; x < (ssize_t) roi->width; x++)
3790 {
3791 SetPixelBlue(image,*p++,q);
3792 SetPixelGreen(image,*p++,q);
3793 SetPixelRed(image,*p++,q);
3794 p++;
3795 q+=(ptrdiff_t) GetPixelChannels(image);
3796 }
3797 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3798 break;
3799 }
3800 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3801 }
3802 if (LocaleCompare(map,"I") == 0)
3803 {
3804 for (y=0; y < (ssize_t) roi->height; y++)
3805 {
3806 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3807 if (q == (Quantum *) NULL)
3808 break;
3809 for (x=0; x < (ssize_t) roi->width; x++)
3810 {
3811 SetPixelGray(image,*p++,q);
3812 q+=(ptrdiff_t) GetPixelChannels(image);
3813 }
3814 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3815 break;
3816 }
3817 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3818 }
3819 if (LocaleCompare(map,"RGB") == 0)
3820 {
3821 for (y=0; y < (ssize_t) roi->height; y++)
3822 {
3823 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3824 if (q == (Quantum *) NULL)
3825 break;
3826 for (x=0; x < (ssize_t) roi->width; x++)
3827 {
3828 SetPixelRed(image,*p++,q);
3829 SetPixelGreen(image,*p++,q);
3830 SetPixelBlue(image,*p++,q);
3831 q+=(ptrdiff_t) GetPixelChannels(image);
3832 }
3833 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3834 break;
3835 }
3836 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3837 }
3838 if (LocaleCompare(map,"RGBA") == 0)
3839 {
3840 for (y=0; y < (ssize_t) roi->height; y++)
3841 {
3842 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3843 if (q == (Quantum *) NULL)
3844 break;
3845 for (x=0; x < (ssize_t) roi->width; x++)
3846 {
3847 SetPixelRed(image,*p++,q);
3848 SetPixelGreen(image,*p++,q);
3849 SetPixelBlue(image,*p++,q);
3850 SetPixelAlpha(image,*p++,q);
3851 q+=(ptrdiff_t) GetPixelChannels(image);
3852 }
3853 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3854 break;
3855 }
3856 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3857 }
3858 if (LocaleCompare(map,"RGBP") == 0)
3859 {
3860 for (y=0; y < (ssize_t) roi->height; y++)
3861 {
3862 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3863 if (q == (Quantum *) NULL)
3864 break;
3865 for (x=0; x < (ssize_t) roi->width; x++)
3866 {
3867 SetPixelRed(image,*p++,q);
3868 SetPixelGreen(image,*p++,q);
3869 SetPixelBlue(image,*p++,q);
3870 p++;
3871 q+=(ptrdiff_t) GetPixelChannels(image);
3872 }
3873 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3874 break;
3875 }
3876 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3877 }
3878 length=strlen(map);
3879 for (y=0; y < (ssize_t) roi->height; y++)
3880 {
3881 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3882 if (q == (Quantum *) NULL)
3883 break;
3884 for (x=0; x < (ssize_t) roi->width; x++)
3885 {
3886 ssize_t
3887 i;
3888
3889 for (i=0; i < (ssize_t) length; i++)
3890 {
3891 switch (quantum_map[i])
3892 {
3893 case RedQuantum:
3894 case CyanQuantum:
3895 {
3896 SetPixelRed(image,*p,q);
3897 break;
3898 }
3899 case GreenQuantum:
3900 case MagentaQuantum:
3901 {
3902 SetPixelGreen(image,*p,q);
3903 break;
3904 }
3905 case BlueQuantum:
3906 case YellowQuantum:
3907 {
3908 SetPixelBlue(image,*p,q);
3909 break;
3910 }
3911 case AlphaQuantum:
3912 {
3913 SetPixelAlpha(image,*p,q);
3914 break;
3915 }
3916 case OpacityQuantum:
3917 {
3918 SetPixelAlpha(image,*p,q);
3919 break;
3920 }
3921 case BlackQuantum:
3922 {
3923 SetPixelBlack(image,*p,q);
3924 break;
3925 }
3926 case IndexQuantum:
3927 {
3928 SetPixelGray(image,*p,q);
3929 break;
3930 }
3931 default:
3932 break;
3933 }
3934 p++;
3935 }
3936 q+=(ptrdiff_t) GetPixelChannels(image);
3937 }
3938 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3939 break;
3940 }
3941 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3942}
3943
3944static MagickBooleanType ImportShortPixel(Image *image,const RectangleInfo *roi,
3945 const char *magick_restrict map,const QuantumType *quantum_map,
3946 const void *pixels,ExceptionInfo *exception)
3947{
3948 const unsigned short
3949 *magick_restrict p;
3950
3951 Quantum
3952 *magick_restrict q;
3953
3954 ssize_t
3955 x;
3956
3957 size_t
3958 length;
3959
3960 ssize_t
3961 y;
3962
3963 p=(const unsigned short *) pixels;
3964 if (LocaleCompare(map,"BGR") == 0)
3965 {
3966 for (y=0; y < (ssize_t) roi->height; y++)
3967 {
3968 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3969 if (q == (Quantum *) NULL)
3970 break;
3971 for (x=0; x < (ssize_t) roi->width; x++)
3972 {
3973 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3974 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3975 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3976 q+=(ptrdiff_t) GetPixelChannels(image);
3977 }
3978 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3979 break;
3980 }
3981 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
3982 }
3983 if (LocaleCompare(map,"BGRA") == 0)
3984 {
3985 for (y=0; y < (ssize_t) roi->height; y++)
3986 {
3987 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3988 if (q == (Quantum *) NULL)
3989 break;
3990 for (x=0; x < (ssize_t) roi->width; x++)
3991 {
3992 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3993 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3994 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3995 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3996 q+=(ptrdiff_t) GetPixelChannels(image);
3997 }
3998 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3999 break;
4000 }
4001 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4002 }
4003 if (LocaleCompare(map,"BGRP") == 0)
4004 {
4005 for (y=0; y < (ssize_t) roi->height; y++)
4006 {
4007 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4008 if (q == (Quantum *) NULL)
4009 break;
4010 for (x=0; x < (ssize_t) roi->width; x++)
4011 {
4012 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4013 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4014 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4015 p++;
4016 q+=(ptrdiff_t) GetPixelChannels(image);
4017 }
4018 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4019 break;
4020 }
4021 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4022 }
4023 if (LocaleCompare(map,"I") == 0)
4024 {
4025 for (y=0; y < (ssize_t) roi->height; y++)
4026 {
4027 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4028 if (q == (Quantum *) NULL)
4029 break;
4030 for (x=0; x < (ssize_t) roi->width; x++)
4031 {
4032 SetPixelGray(image,ScaleShortToQuantum(*p++),q);
4033 q+=(ptrdiff_t) GetPixelChannels(image);
4034 }
4035 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4036 break;
4037 }
4038 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4039 }
4040 if (LocaleCompare(map,"RGB") == 0)
4041 {
4042 for (y=0; y < (ssize_t) roi->height; y++)
4043 {
4044 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4045 if (q == (Quantum *) NULL)
4046 break;
4047 for (x=0; x < (ssize_t) roi->width; x++)
4048 {
4049 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4050 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4051 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4052 q+=(ptrdiff_t) GetPixelChannels(image);
4053 }
4054 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4055 break;
4056 }
4057 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4058 }
4059 if (LocaleCompare(map,"RGBA") == 0)
4060 {
4061 for (y=0; y < (ssize_t) roi->height; y++)
4062 {
4063 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4064 if (q == (Quantum *) NULL)
4065 break;
4066 for (x=0; x < (ssize_t) roi->width; x++)
4067 {
4068 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4069 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4070 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4071 SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
4072 q+=(ptrdiff_t) GetPixelChannels(image);
4073 }
4074 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4075 break;
4076 }
4077 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4078 }
4079 if (LocaleCompare(map,"RGBP") == 0)
4080 {
4081 for (y=0; y < (ssize_t) roi->height; y++)
4082 {
4083 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4084 if (q == (Quantum *) NULL)
4085 break;
4086 for (x=0; x < (ssize_t) roi->width; x++)
4087 {
4088 SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4089 SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4090 SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4091 p++;
4092 q+=(ptrdiff_t) GetPixelChannels(image);
4093 }
4094 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4095 break;
4096 }
4097 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4098 }
4099 length=strlen(map);
4100 for (y=0; y < (ssize_t) roi->height; y++)
4101 {
4102 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4103 if (q == (Quantum *) NULL)
4104 break;
4105 for (x=0; x < (ssize_t) roi->width; x++)
4106 {
4107 ssize_t
4108 i;
4109
4110 for (i=0; i < (ssize_t) length; i++)
4111 {
4112 switch (quantum_map[i])
4113 {
4114 case RedQuantum:
4115 case CyanQuantum:
4116 {
4117 SetPixelRed(image,ScaleShortToQuantum(*p),q);
4118 break;
4119 }
4120 case GreenQuantum:
4121 case MagentaQuantum:
4122 {
4123 SetPixelGreen(image,ScaleShortToQuantum(*p),q);
4124 break;
4125 }
4126 case BlueQuantum:
4127 case YellowQuantum:
4128 {
4129 SetPixelBlue(image,ScaleShortToQuantum(*p),q);
4130 break;
4131 }
4132 case AlphaQuantum:
4133 {
4134 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
4135 break;
4136 }
4137 case OpacityQuantum:
4138 {
4139 SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
4140 break;
4141 }
4142 case BlackQuantum:
4143 {
4144 SetPixelBlack(image,ScaleShortToQuantum(*p),q);
4145 break;
4146 }
4147 case IndexQuantum:
4148 {
4149 SetPixelGray(image,ScaleShortToQuantum(*p),q);
4150 break;
4151 }
4152 default:
4153 break;
4154 }
4155 p++;
4156 }
4157 q+=(ptrdiff_t) GetPixelChannels(image);
4158 }
4159 if (SyncAuthenticPixels(image,exception) == MagickFalse)
4160 break;
4161 }
4162 return(y < (ssize_t) roi->height ? MagickFalse : MagickTrue);
4163}
4164
4165MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
4166 const ssize_t y,const size_t width,const size_t height,const char *map,
4167 const StorageType type,const void *pixels,ExceptionInfo *exception)
4168{
4169 MagickBooleanType
4170 status;
4171
4172 QuantumType
4173 *quantum_map;
4174
4175 RectangleInfo
4176 roi;
4177
4178 ssize_t
4179 i;
4180
4181 size_t
4182 length;
4183
4184 /*
4185 Allocate image structure.
4186 */
4187 assert(image != (Image *) NULL);
4188 assert(image->signature == MagickCoreSignature);
4189 if (IsEventLogging() != MagickFalse)
4190 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4191 length=strlen(map);
4192 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
4193 if (quantum_map == (QuantumType *) NULL)
4194 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4195 image->filename);
4196 for (i=0; i < (ssize_t) length; i++)
4197 {
4198 switch (map[i])
4199 {
4200 case 'a':
4201 case 'A':
4202 {
4203 quantum_map[i]=AlphaQuantum;
4204 image->alpha_trait=BlendPixelTrait;
4205 break;
4206 }
4207 case 'B':
4208 case 'b':
4209 {
4210 quantum_map[i]=BlueQuantum;
4211 break;
4212 }
4213 case 'C':
4214 case 'c':
4215 {
4216 quantum_map[i]=CyanQuantum;
4217 (void) SetImageColorspace(image,CMYKColorspace,exception);
4218 break;
4219 }
4220 case 'g':
4221 case 'G':
4222 {
4223 quantum_map[i]=GreenQuantum;
4224 break;
4225 }
4226 case 'K':
4227 case 'k':
4228 {
4229 quantum_map[i]=BlackQuantum;
4230 (void) SetImageColorspace(image,CMYKColorspace,exception);
4231 break;
4232 }
4233 case 'I':
4234 case 'i':
4235 {
4236 quantum_map[i]=IndexQuantum;
4237 (void) SetImageColorspace(image,GRAYColorspace,exception);
4238 break;
4239 }
4240 case 'm':
4241 case 'M':
4242 {
4243 quantum_map[i]=MagentaQuantum;
4244 (void) SetImageColorspace(image,CMYKColorspace,exception);
4245 break;
4246 }
4247 case 'O':
4248 case 'o':
4249 {
4250 quantum_map[i]=OpacityQuantum;
4251 image->alpha_trait=BlendPixelTrait;
4252 break;
4253 }
4254 case 'P':
4255 case 'p':
4256 {
4257 quantum_map[i]=UndefinedQuantum;
4258 break;
4259 }
4260 case 'R':
4261 case 'r':
4262 {
4263 quantum_map[i]=RedQuantum;
4264 break;
4265 }
4266 case 'Y':
4267 case 'y':
4268 {
4269 quantum_map[i]=YellowQuantum;
4270 (void) SetImageColorspace(image,CMYKColorspace,exception);
4271 break;
4272 }
4273 default:
4274 {
4275 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4276 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
4277 "UnrecognizedPixelMap","`%s'",map);
4278 return(MagickFalse);
4279 }
4280 }
4281 }
4282 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
4283 return(MagickFalse);
4284 /*
4285 Transfer the pixels from the pixel data to the image.
4286 */
4287 roi.width=width;
4288 roi.height=height;
4289 roi.x=x;
4290 roi.y=y;
4291 switch (type)
4292 {
4293 case CharPixel:
4294 {
4295 status=ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
4296 break;
4297 }
4298 case DoublePixel:
4299 {
4300 status=ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
4301 break;
4302 }
4303 case FloatPixel:
4304 {
4305 status=ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
4306 break;
4307 }
4308 case LongPixel:
4309 {
4310 status=ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
4311 break;
4312 }
4313 case LongLongPixel:
4314 {
4315 status=ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
4316 break;
4317 }
4318 case QuantumPixel:
4319 {
4320 status=ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
4321 break;
4322 }
4323 case ShortPixel:
4324 {
4325 status=ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
4326 break;
4327 }
4328 default:
4329 {
4330 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
4331 "UnrecognizedStorageType","`%d'",type);
4332 status=MagickFalse;
4333 }
4334 }
4335 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4336 return(status);
4337}
4338␌
4339/*
4340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4341% %
4342% %
4343% %
4344% I n t e r p o l a t e P i x e l C h a n n e l %
4345% %
4346% %
4347% %
4348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4349%
4350% InterpolatePixelChannel() applies a pixel interpolation method between a
4351% floating point coordinate and the pixels surrounding that coordinate. No
4352% pixel area resampling, or scaling of the result is performed.
4353%
4354% Interpolation is restricted to just the specified channel.
4355%
4356% The format of the InterpolatePixelChannel method is:
4357%
4358% MagickBooleanType InterpolatePixelChannel(
4359% const Image *magick_restrict image,const CacheView *image_view,
4360% const PixelChannel channel,const PixelInterpolateMethod method,
4361% const double x,const double y,double *pixel,ExceptionInfo *exception)
4362%
4363% A description of each parameter follows:
4364%
4365% o image: the image.
4366%
4367% o image_view: the image view.
4368%
4369% o channel: the pixel channel to interpolate.
4370%
4371% o method: the pixel color interpolation method.
4372%
4373% o x,y: A double representing the current (x,y) position of the pixel.
4374%
4375% o pixel: return the interpolated pixel here.
4376%
4377% o exception: return any errors or warnings in this structure.
4378%
4379*/
4380
4381static inline void CatromWeights(const double x,double (*weights)[4])
4382{
4383 double
4384 alpha,
4385 beta,
4386 gamma;
4387
4388 /*
4389 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4390 of the standard four 1D Catmull-Rom weights. The sampling location is
4391 assumed between the second and third input pixel locations, and x is the
4392 position relative to the second input pixel location. Formulas originally
4393 derived for the VIPS (Virtual Image Processing System) library.
4394 */
4395 alpha=(double) 1.0-x;
4396 beta=(double) (-0.5)*x*alpha;
4397 (*weights)[0]=alpha*beta;
4398 (*weights)[3]=x*beta;
4399 /*
4400 The following computation of the inner weights from the outer ones work
4401 for all Keys cubics.
4402 */
4403 gamma=(*weights)[3]-(*weights)[0];
4404 (*weights)[1]=alpha-(*weights)[0]+gamma;
4405 (*weights)[2]=x-(*weights)[3]-gamma;
4406}
4407
4408static inline void SplineWeights(const double x,double (*weights)[4])
4409{
4410 double
4411 alpha,
4412 beta;
4413
4414 /*
4415 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation
4416 of the standard four 1D cubic B-spline smoothing weights. The sampling
4417 location is assumed between the second and third input pixel locations,
4418 and x is the position relative to the second input pixel location.
4419 */
4420 alpha=(double) 1.0-x;
4421 (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4422 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
4423 beta=(*weights)[3]-(*weights)[0];
4424 (*weights)[1]=alpha-(*weights)[0]+beta;
4425 (*weights)[2]=x-(*weights)[3]-beta;
4426}
4427
4428static inline double MeshInterpolate(const PointInfo *delta,const double p,
4429 const double x,const double y)
4430{
4431 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4432}
4433
4434MagickExport MagickBooleanType InterpolatePixelChannel(
4435 const Image *magick_restrict image,const CacheView_ *image_view,
4436 const PixelChannel channel,const PixelInterpolateMethod method,const double x,
4437 const double y,double *pixel,ExceptionInfo *exception)
4438{
4439 const Quantum
4440 *magick_restrict p;
4441
4442 double
4443 alpha[16],
4444 gamma,
4445 pixels[16];
4446
4447 MagickBooleanType
4448 status;
4449
4450 PixelInterpolateMethod
4451 interpolate;
4452
4453 PixelTrait
4454 traits;
4455
4456 ssize_t
4457 i,
4458 x_offset,
4459 y_offset;
4460
4461 assert(image != (Image *) NULL);
4462 assert(image->signature == MagickCoreSignature);
4463 assert(image_view != (CacheView *) NULL);
4464 *pixel=0.0;
4465 if ((channel < 0) || (channel >= MaxPixelChannels))
4466 ThrowBinaryException(OptionError,"NoSuchImageChannel",image->filename);
4467 traits=GetPixelChannelTraits(image,channel);
4468 x_offset=CastDoubleToSsizeT(floor(x));
4469 y_offset=CastDoubleToSsizeT(floor(y));
4470 interpolate=method;
4471 if (interpolate == UndefinedInterpolatePixel)
4472 interpolate=image->interpolate;
4473 status=MagickTrue;
4474 switch (interpolate)
4475 {
4476 case AverageInterpolatePixel: /* nearest 4 neighbours */
4477 case Average9InterpolatePixel: /* nearest 9 neighbours */
4478 case Average16InterpolatePixel: /* nearest 16 neighbours */
4479 {
4480 ssize_t
4481 count;
4482
4483 count=2; /* size of the area to average - default nearest 4 */
4484 if (interpolate == Average9InterpolatePixel)
4485 {
4486 count=3;
4487 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
4488 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
4489 }
4490 else
4491 if (interpolate == Average16InterpolatePixel)
4492 {
4493 count=4;
4494 x_offset--;
4495 y_offset--;
4496 }
4497 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
4498 (size_t) count,exception);
4499 if (p == (const Quantum *) NULL)
4500 {
4501 status=MagickFalse;
4502 break;
4503 }
4504 count*=count; /* Number of pixels to average */
4505 if ((traits & BlendPixelTrait) == 0)
4506 for (i=0; i < (ssize_t) count; i++)
4507 {
4508 alpha[i]=1.0;
4509 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4510 GetPixelChannelOffset(image,channel)];
4511 }
4512 else
4513 for (i=0; i < (ssize_t) count; i++)
4514 {
4515 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4516 (ssize_t) GetPixelChannels(image));
4517 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4518 GetPixelChannelOffset(image,channel)];
4519 }
4520 for (i=0; i < (ssize_t) count; i++)
4521 {
4522 gamma=MagickSafeReciprocal(alpha[i])/count;
4523 *pixel+=gamma*pixels[i];
4524 }
4525 break;
4526 }
4527 case BilinearInterpolatePixel:
4528 default:
4529 {
4530 PointInfo
4531 delta,
4532 epsilon;
4533
4534 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4535 if (p == (const Quantum *) NULL)
4536 {
4537 status=MagickFalse;
4538 break;
4539 }
4540 if ((traits & BlendPixelTrait) == 0)
4541 for (i=0; i < 4; i++)
4542 {
4543 alpha[i]=1.0;
4544 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4545 GetPixelChannelOffset(image,channel)];
4546 }
4547 else
4548 for (i=0; i < 4; i++)
4549 {
4550 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4551 (ssize_t) GetPixelChannels(image));
4552 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4553 GetPixelChannelOffset(image,channel)];
4554 }
4555 delta.x=x-x_offset;
4556 delta.y=y-y_offset;
4557 epsilon.x=1.0-delta.x;
4558 epsilon.y=1.0-delta.y;
4559 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4560 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4561 gamma=MagickSafeReciprocal(gamma);
4562 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4563 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4564 break;
4565 }
4566 case BlendInterpolatePixel:
4567 {
4568 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4569 if (p == (const Quantum *) NULL)
4570 {
4571 status=MagickFalse;
4572 break;
4573 }
4574 if ((traits & BlendPixelTrait) == 0)
4575 for (i=0; i < 4; i++)
4576 {
4577 alpha[i]=1.0;
4578 pixels[i]=(MagickRealType) p[i*(ssize_t) GetPixelChannels(image)+
4579 GetPixelChannelOffset(image,channel)];
4580 }
4581 else
4582 for (i=0; i < 4; i++)
4583 {
4584 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4585 (ssize_t) GetPixelChannels(image));
4586 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4587 GetPixelChannelOffset(image,channel)];
4588 }
4589 gamma=1.0; /* number of pixels blended together (its variable) */
4590 for (i=0; i <= 1L; i++) {
4591 if ((y-y_offset) >= 0.75)
4592 {
4593 alpha[i]=alpha[i+2]; /* take right pixels */
4594 pixels[i]=pixels[i+2];
4595 }
4596 else
4597 if ((y-y_offset) > 0.25)
4598 {
4599 gamma=2.0; /* blend both pixels in row */
4600 alpha[i]+=alpha[i+2]; /* add up alpha weights */
4601 pixels[i]+=pixels[i+2];
4602 }
4603 }
4604 if ((x-x_offset) >= 0.75)
4605 {
4606 alpha[0]=alpha[1]; /* take bottom row blend */
4607 pixels[0]=pixels[1];
4608 }
4609 else
4610 if ((x-x_offset) > 0.25)
4611 {
4612 gamma*=2.0; /* blend both rows */
4613 alpha[0]+=alpha[1]; /* add up alpha weights */
4614 pixels[0]+=pixels[1];
4615 }
4616 if (channel != AlphaPixelChannel)
4617 gamma=MagickSafeReciprocal(alpha[0]); /* (color) 1/alpha_weights */
4618 else
4619 gamma=MagickSafeReciprocal(gamma); /* (alpha) 1/number_of_pixels */
4620 *pixel=gamma*pixels[0];
4621 break;
4622 }
4623 case CatromInterpolatePixel:
4624 {
4625 double
4626 cx[4],
4627 cy[4];
4628
4629 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4630 exception);
4631 if (p == (const Quantum *) NULL)
4632 {
4633 status=MagickFalse;
4634 break;
4635 }
4636 if ((traits & BlendPixelTrait) == 0)
4637 for (i=0; i < 16; i++)
4638 {
4639 alpha[i]=1.0;
4640 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4641 GetPixelChannelOffset(image,channel)];
4642 }
4643 else
4644 for (i=0; i < 16; i++)
4645 {
4646 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4647 (ssize_t) GetPixelChannels(image));
4648 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4649 GetPixelChannelOffset(image,channel)];
4650 }
4651 CatromWeights((double) (x-x_offset),&cx);
4652 CatromWeights((double) (y-y_offset),&cy);
4653 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4654 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4655 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4656 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4657 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4658 cx[2]*alpha[14]+cx[3]*alpha[15])));
4659 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4660 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4661 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4662 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4663 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4664 break;
4665 }
4666 case IntegerInterpolatePixel:
4667 {
4668 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4669 if (p == (const Quantum *) NULL)
4670 {
4671 status=MagickFalse;
4672 break;
4673 }
4674 *pixel=(double) GetPixelChannel(image,channel,p);
4675 break;
4676 }
4677 case NearestInterpolatePixel:
4678 {
4679 x_offset=CastDoubleToSsizeT(floor(x+0.5));
4680 y_offset=CastDoubleToSsizeT(floor(y+0.5));
4681 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4682 if (p == (const Quantum *) NULL)
4683 {
4684 status=MagickFalse;
4685 break;
4686 }
4687 *pixel=(double) GetPixelChannel(image,channel,p);
4688 break;
4689 }
4690 case MeshInterpolatePixel:
4691 {
4692 PointInfo
4693 delta,
4694 luminance;
4695
4696 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4697 if (p == (const Quantum *) NULL)
4698 {
4699 status=MagickFalse;
4700 break;
4701 }
4702 if ((traits & BlendPixelTrait) == 0)
4703 for (i=0; i < 4; i++)
4704 {
4705 alpha[i]=1.0;
4706 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4707 GetPixelChannelOffset(image,channel)];
4708 }
4709 else
4710 for (i=0; i < 4; i++)
4711 {
4712 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4713 (ssize_t) GetPixelChannels(image));
4714 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4715 GetPixelChannelOffset(image,channel)];
4716 }
4717 delta.x=x-x_offset;
4718 delta.y=y-y_offset;
4719 luminance.x=GetPixelLuma(image,p)-(double)
4720 GetPixelLuma(image,p+3*GetPixelChannels(image));
4721 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
4722 GetPixelLuma(image,p+2*GetPixelChannels(image));
4723 if (fabs((double) luminance.x) < fabs((double) luminance.y))
4724 {
4725 /*
4726 Diagonal 0-3 NW-SE.
4727 */
4728 if (delta.x <= delta.y)
4729 {
4730 /*
4731 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4732 */
4733 delta.y=1.0-delta.y;
4734 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4735 gamma=MagickSafeReciprocal(gamma);
4736 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4737 pixels[0]);
4738 }
4739 else
4740 {
4741 /*
4742 Top-right triangle (pixel: 1, diagonal: 0-3).
4743 */
4744 delta.x=1.0-delta.x;
4745 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4746 gamma=MagickSafeReciprocal(gamma);
4747 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4748 pixels[3]);
4749 }
4750 }
4751 else
4752 {
4753 /*
4754 Diagonal 1-2 NE-SW.
4755 */
4756 if (delta.x <= (1.0-delta.y))
4757 {
4758 /*
4759 Top-left triangle (pixel: 0, diagonal: 1-2).
4760 */
4761 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4762 gamma=MagickSafeReciprocal(gamma);
4763 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4764 pixels[2]);
4765 }
4766 else
4767 {
4768 /*
4769 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4770 */
4771 delta.x=1.0-delta.x;
4772 delta.y=1.0-delta.y;
4773 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4774 gamma=MagickSafeReciprocal(gamma);
4775 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4776 pixels[1]);
4777 }
4778 }
4779 break;
4780 }
4781 case SplineInterpolatePixel:
4782 {
4783 double
4784 cx[4],
4785 cy[4];
4786
4787 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4788 exception);
4789 if (p == (const Quantum *) NULL)
4790 {
4791 status=MagickFalse;
4792 break;
4793 }
4794 if ((traits & BlendPixelTrait) == 0)
4795 for (i=0; i < 16; i++)
4796 {
4797 alpha[i]=1.0;
4798 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4799 GetPixelChannelOffset(image,channel)];
4800 }
4801 else
4802 for (i=0; i < 16; i++)
4803 {
4804 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4805 (ssize_t) GetPixelChannels(image));
4806 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4807 GetPixelChannelOffset(image,channel)];
4808 }
4809 SplineWeights((double) (x-x_offset),&cx);
4810 SplineWeights((double) (y-y_offset),&cy);
4811 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4812 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4813 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4814 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4815 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4816 cx[2]*alpha[14]+cx[3]*alpha[15])));
4817 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4818 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4819 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4820 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4821 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4822 break;
4823 }
4824 }
4825 return(status);
4826}
4827␌
4828/*
4829%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4830% %
4831% %
4832% %
4833% I n t e r p o l a t e P i x e l C h a n n e l s %
4834% %
4835% %
4836% %
4837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4838%
4839% InterpolatePixelChannels() applies a pixel interpolation method between a
4840% floating point coordinate and the pixels surrounding that coordinate. No
4841% pixel area resampling, or scaling of the result is performed.
4842%
4843% Interpolation is restricted to just the current channel setting of the
4844% destination image into which the color is to be stored
4845%
4846% The format of the InterpolatePixelChannels method is:
4847%
4848% MagickBooleanType InterpolatePixelChannels(
4849% const Image *magick_restrict source,const CacheView *source_view,
4850% const Image *magick_restrict destination,
4851% const PixelInterpolateMethod method,const double x,const double y,
4852% Quantum *pixel,ExceptionInfo *exception)
4853%
4854% A description of each parameter follows:
4855%
4856% o source: the source.
4857%
4858% o source_view: the source view.
4859%
4860% o destination: the destination image, for the interpolated color
4861%
4862% o method: the pixel color interpolation method.
4863%
4864% o x,y: A double representing the current (x,y) position of the pixel.
4865%
4866% o pixel: return the interpolated pixel here.
4867%
4868% o exception: return any errors or warnings in this structure.
4869%
4870*/
4871MagickExport MagickBooleanType InterpolatePixelChannels(
4872 const Image *magick_restrict source,const CacheView_ *source_view,
4873 const Image *magick_restrict destination,const PixelInterpolateMethod method,
4874 const double x,const double y,Quantum *pixel,ExceptionInfo *exception)
4875{
4876 MagickBooleanType
4877 status;
4878
4879 double
4880 alpha[16],
4881 gamma,
4882 pixels[16];
4883
4884 const Quantum
4885 *magick_restrict p;
4886
4887 ssize_t
4888 i;
4889
4890 ssize_t
4891 x_offset,
4892 y_offset;
4893
4894 PixelInterpolateMethod
4895 interpolate;
4896
4897 assert(source != (Image *) NULL);
4898 assert(source->signature == MagickCoreSignature);
4899 assert(source_view != (CacheView *) NULL);
4900 status=MagickTrue;
4901 x_offset=CastDoubleToSsizeT(floor(x));
4902 y_offset=CastDoubleToSsizeT(floor(y));
4903 interpolate=method;
4904 if (interpolate == UndefinedInterpolatePixel)
4905 interpolate=source->interpolate;
4906 switch (interpolate)
4907 {
4908 case AverageInterpolatePixel: /* nearest 4 neighbours */
4909 case Average9InterpolatePixel: /* nearest 9 neighbours */
4910 case Average16InterpolatePixel: /* nearest 16 neighbours */
4911 {
4912 ssize_t
4913 count;
4914
4915 count=2; /* size of the area to average - default nearest 4 */
4916 if (interpolate == Average9InterpolatePixel)
4917 {
4918 count=3;
4919 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
4920 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
4921 }
4922 else
4923 if (interpolate == Average16InterpolatePixel)
4924 {
4925 count=4;
4926 x_offset--;
4927 y_offset--;
4928 }
4929 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count,
4930 (size_t) count,exception);
4931 if (p == (const Quantum *) NULL)
4932 {
4933 status=MagickFalse;
4934 break;
4935 }
4936 count*=count; /* Number of pixels to average */
4937 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4938 {
4939 double
4940 sum;
4941
4942 ssize_t
4943 j;
4944
4945 PixelChannel channel = GetPixelChannelChannel(source,i);
4946 PixelTrait traits = GetPixelChannelTraits(source,channel);
4947 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4948 channel);
4949 if ((traits == UndefinedPixelTrait) ||
4950 (destination_traits == UndefinedPixelTrait))
4951 continue;
4952 for (j=0; j < (ssize_t) count; j++)
4953 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
4954 sum=0.0;
4955 if ((traits & BlendPixelTrait) == 0)
4956 {
4957 for (j=0; j < (ssize_t) count; j++)
4958 sum+=pixels[j];
4959 sum/=count;
4960 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4961 continue;
4962 }
4963 for (j=0; j < (ssize_t) count; j++)
4964 {
4965 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
4966 (ssize_t) GetPixelChannels(source));
4967 pixels[j]*=alpha[j];
4968 gamma=MagickSafeReciprocal(alpha[j]);
4969 sum+=gamma*pixels[j];
4970 }
4971 sum/=count;
4972 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4973 }
4974 break;
4975 }
4976 case BilinearInterpolatePixel:
4977 default:
4978 {
4979 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4980 if (p == (const Quantum *) NULL)
4981 {
4982 status=MagickFalse;
4983 break;
4984 }
4985 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4986 {
4987 PointInfo
4988 delta,
4989 epsilon;
4990
4991 PixelChannel channel = GetPixelChannelChannel(source,i);
4992 PixelTrait traits = GetPixelChannelTraits(source,channel);
4993 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4994 channel);
4995 if ((traits == UndefinedPixelTrait) ||
4996 (destination_traits == UndefinedPixelTrait))
4997 continue;
4998 delta.x=x-x_offset;
4999 delta.y=y-y_offset;
5000 epsilon.x=1.0-delta.x;
5001 epsilon.y=1.0-delta.y;
5002 pixels[0]=(double) p[i];
5003 pixels[1]=(double) p[(ssize_t) GetPixelChannels(source)+i];
5004 pixels[2]=(double) p[2*(ssize_t) GetPixelChannels(source)+i];
5005 pixels[3]=(double) p[3*(ssize_t) GetPixelChannels(source)+i];
5006 if ((traits & BlendPixelTrait) == 0)
5007 {
5008 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5009 gamma=MagickSafeReciprocal(gamma);
5010 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5011 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
5012 pixels[2]+delta.x*pixels[3]))),pixel);
5013 continue;
5014 }
5015 alpha[0]=QuantumScale*(double) GetPixelAlpha(source,p);
5016 alpha[1]=QuantumScale*(double) GetPixelAlpha(source,p+
5017 GetPixelChannels(source));
5018 alpha[2]=QuantumScale*(double) GetPixelAlpha(source,p+2*
5019 GetPixelChannels(source));
5020 alpha[3]=QuantumScale*(double) GetPixelAlpha(source,p+3*
5021 GetPixelChannels(source));
5022 pixels[0]*=alpha[0];
5023 pixels[1]*=alpha[1];
5024 pixels[2]*=alpha[2];
5025 pixels[3]*=alpha[3];
5026 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5027 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5028 gamma=MagickSafeReciprocal(gamma);
5029 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5030 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
5031 delta.x*pixels[3]))),pixel);
5032 }
5033 break;
5034 }
5035 case BlendInterpolatePixel:
5036 {
5037 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5038 if (p == (const Quantum *) NULL)
5039 {
5040 status=MagickFalse;
5041 break;
5042 }
5043 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5044 {
5045 ssize_t
5046 j;
5047
5048 PixelChannel channel = GetPixelChannelChannel(source,i);
5049 PixelTrait traits = GetPixelChannelTraits(source,channel);
5050 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5051 channel);
5052 if ((traits == UndefinedPixelTrait) ||
5053 (destination_traits == UndefinedPixelTrait))
5054 continue;
5055 if (source->alpha_trait != BlendPixelTrait)
5056 for (j=0; j < 4; j++)
5057 {
5058 alpha[j]=1.0;
5059 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5060 }
5061 else
5062 for (j=0; j < 4; j++)
5063 {
5064 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5065 (ssize_t) GetPixelChannels(source));
5066 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5067 if (channel != AlphaPixelChannel)
5068 pixels[j]*=alpha[j];
5069 }
5070 gamma=1.0; /* number of pixels blended together (its variable) */
5071 for (j=0; j <= 1L; j++)
5072 {
5073 if ((y-y_offset) >= 0.75)
5074 {
5075 alpha[j]=alpha[j+2]; /* take right pixels */
5076 pixels[j]=pixels[j+2];
5077 }
5078 else
5079 if ((y-y_offset) > 0.25)
5080 {
5081 gamma=2.0; /* blend both pixels in row */
5082 alpha[j]+=alpha[j+2]; /* add up alpha weights */
5083 pixels[j]+=pixels[j+2];
5084 }
5085 }
5086 if ((x-x_offset) >= 0.75)
5087 {
5088 alpha[0]=alpha[1]; /* take bottom row blend */
5089 pixels[0]=pixels[1];
5090 }
5091 else
5092 if ((x-x_offset) > 0.25)
5093 {
5094 gamma*=2.0; /* blend both rows */
5095 alpha[0]+=alpha[1]; /* add up alpha weights */
5096 pixels[0]+=pixels[1];
5097 }
5098 if (channel != AlphaPixelChannel)
5099 gamma=MagickSafeReciprocal(alpha[0]); /* (color) 1/alpha_weights */
5100 else
5101 gamma=MagickSafeReciprocal(gamma); /* (alpha) 1/number_of_pixels */
5102 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
5103 pixel);
5104 }
5105 break;
5106 }
5107 case CatromInterpolatePixel:
5108 {
5109 double
5110 cx[4],
5111 cy[4];
5112
5113 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5114 exception);
5115 if (p == (const Quantum *) NULL)
5116 {
5117 status=MagickFalse;
5118 break;
5119 }
5120 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5121 {
5122 ssize_t
5123 j;
5124
5125 PixelChannel channel = GetPixelChannelChannel(source,i);
5126 PixelTrait traits = GetPixelChannelTraits(source,channel);
5127 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5128 channel);
5129 if ((traits == UndefinedPixelTrait) ||
5130 (destination_traits == UndefinedPixelTrait))
5131 continue;
5132 if ((traits & BlendPixelTrait) == 0)
5133 for (j=0; j < 16; j++)
5134 {
5135 alpha[j]=1.0;
5136 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5137 }
5138 else
5139 for (j=0; j < 16; j++)
5140 {
5141 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5142 (ssize_t) GetPixelChannels(source));
5143 pixels[j]=alpha[j]*(double)
5144 p[j*(ssize_t) GetPixelChannels(source)+i];
5145 }
5146 CatromWeights((double) (x-x_offset),&cx);
5147 CatromWeights((double) (y-y_offset),&cy);
5148 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5149 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5150 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5151 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5152 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5153 cx[2]*alpha[14]+cx[3]*alpha[15])));
5154 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5155 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5156 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5157 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5158 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5159 pixels[14]+cx[3]*pixels[15]))),pixel);
5160 }
5161 break;
5162 }
5163 case IntegerInterpolatePixel:
5164 {
5165 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5166 if (p == (const Quantum *) NULL)
5167 {
5168 status=MagickFalse;
5169 break;
5170 }
5171 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5172 {
5173 PixelChannel channel = GetPixelChannelChannel(source,i);
5174 PixelTrait traits = GetPixelChannelTraits(source,channel);
5175 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5176 channel);
5177 if ((traits == UndefinedPixelTrait) ||
5178 (destination_traits == UndefinedPixelTrait))
5179 continue;
5180 SetPixelChannel(destination,channel,p[i],pixel);
5181 }
5182 break;
5183 }
5184 case NearestInterpolatePixel:
5185 {
5186 x_offset=CastDoubleToSsizeT(floor(x+0.5));
5187 y_offset=CastDoubleToSsizeT(floor(y+0.5));
5188 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5189 if (p == (const Quantum *) NULL)
5190 {
5191 status=MagickFalse;
5192 break;
5193 }
5194 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5195 {
5196 PixelChannel channel = GetPixelChannelChannel(source,i);
5197 PixelTrait traits = GetPixelChannelTraits(source,channel);
5198 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5199 channel);
5200 if ((traits == UndefinedPixelTrait) ||
5201 (destination_traits == UndefinedPixelTrait))
5202 continue;
5203 SetPixelChannel(destination,channel,p[i],pixel);
5204 }
5205 break;
5206 }
5207 case MeshInterpolatePixel:
5208 {
5209 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5210 if (p == (const Quantum *) NULL)
5211 {
5212 status=MagickFalse;
5213 break;
5214 }
5215 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5216 {
5217 PointInfo
5218 delta,
5219 luminance;
5220
5221 PixelChannel channel = GetPixelChannelChannel(source,i);
5222 PixelTrait traits = GetPixelChannelTraits(source,channel);
5223 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5224 channel);
5225 if ((traits == UndefinedPixelTrait) ||
5226 (destination_traits == UndefinedPixelTrait))
5227 continue;
5228 pixels[0]=(double) p[i];
5229 pixels[1]=(double) p[(ssize_t) GetPixelChannels(source)+i];
5230 pixels[2]=(double) p[2*(ssize_t) GetPixelChannels(source)+i];
5231 pixels[3]=(double) p[3*(ssize_t) GetPixelChannels(source)+i];
5232 if ((traits & BlendPixelTrait) == 0)
5233 {
5234 alpha[0]=1.0;
5235 alpha[1]=1.0;
5236 alpha[2]=1.0;
5237 alpha[3]=1.0;
5238 }
5239 else
5240 {
5241 alpha[0]=QuantumScale*(double) GetPixelAlpha(source,p);
5242 alpha[1]=QuantumScale*(double) GetPixelAlpha(source,p+
5243 GetPixelChannels(source));
5244 alpha[2]=QuantumScale*(double) GetPixelAlpha(source,p+2*
5245 GetPixelChannels(source));
5246 alpha[3]=QuantumScale*(double) GetPixelAlpha(source,p+3*
5247 GetPixelChannels(source));
5248 }
5249 delta.x=x-x_offset;
5250 delta.y=y-y_offset;
5251 luminance.x=fabs((double) (GetPixelLuma(source,p)-
5252 GetPixelLuma(source,p+3*GetPixelChannels(source))));
5253 luminance.y=fabs((double) (GetPixelLuma(source,p+
5254 GetPixelChannels(source))-GetPixelLuma(source,p+2*
5255 GetPixelChannels(source))));
5256 if (luminance.x < luminance.y)
5257 {
5258 /*
5259 Diagonal 0-3 NW-SE.
5260 */
5261 if (delta.x <= delta.y)
5262 {
5263 /*
5264 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5265 */
5266 delta.y=1.0-delta.y;
5267 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5268 gamma=MagickSafeReciprocal(gamma);
5269 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5270 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
5271 }
5272 else
5273 {
5274 /*
5275 Top-right triangle (pixel: 1, diagonal: 0-3).
5276 */
5277 delta.x=1.0-delta.x;
5278 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5279 gamma=MagickSafeReciprocal(gamma);
5280 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5281 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
5282 }
5283 }
5284 else
5285 {
5286 /*
5287 Diagonal 1-2 NE-SW.
5288 */
5289 if (delta.x <= (1.0-delta.y))
5290 {
5291 /*
5292 Top-left triangle (pixel: 0, diagonal: 1-2).
5293 */
5294 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5295 gamma=MagickSafeReciprocal(gamma);
5296 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5297 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
5298 }
5299 else
5300 {
5301 /*
5302 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5303 */
5304 delta.x=1.0-delta.x;
5305 delta.y=1.0-delta.y;
5306 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5307 gamma=MagickSafeReciprocal(gamma);
5308 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5309 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
5310 }
5311 }
5312 }
5313 break;
5314 }
5315 case SplineInterpolatePixel:
5316 {
5317 double
5318 cx[4],
5319 cy[4];
5320
5321 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5322 exception);
5323 if (p == (const Quantum *) NULL)
5324 {
5325 status=MagickFalse;
5326 break;
5327 }
5328 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5329 {
5330 ssize_t
5331 j;
5332
5333 PixelChannel channel = GetPixelChannelChannel(source,i);
5334 PixelTrait traits = GetPixelChannelTraits(source,channel);
5335 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5336 channel);
5337 if ((traits == UndefinedPixelTrait) ||
5338 (destination_traits == UndefinedPixelTrait))
5339 continue;
5340 if ((traits & BlendPixelTrait) == 0)
5341 for (j=0; j < 16; j++)
5342 {
5343 alpha[j]=1.0;
5344 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5345 }
5346 else
5347 for (j=0; j < 16; j++)
5348 {
5349 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5350 (ssize_t) GetPixelChannels(source));
5351 pixels[j]=alpha[j]*(double) p[j*(ssize_t) GetPixelChannels(source)+
5352 i];
5353 }
5354 SplineWeights((double) (x-x_offset),&cx);
5355 SplineWeights((double) (y-y_offset),&cy);
5356 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5357 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5358 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5359 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5360 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5361 cx[2]*alpha[14]+cx[3]*alpha[15])));
5362 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5363 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5364 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5365 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5366 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5367 pixels[14]+cx[3]*pixels[15]))),pixel);
5368 }
5369 break;
5370 }
5371 }
5372 return(status);
5373}
5374␌
5375/*
5376%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5377% %
5378% %
5379% %
5380% I n t e r p o l a t e P i x e l I n f o %
5381% %
5382% %
5383% %
5384%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5385%
5386% InterpolatePixelInfo() applies a pixel interpolation method between a
5387% floating point coordinate and the pixels surrounding that coordinate. No
5388% pixel area resampling, or scaling of the result is performed.
5389%
5390% Interpolation is restricted to just RGBKA channels.
5391%
5392% The format of the InterpolatePixelInfo method is:
5393%
5394% MagickBooleanType InterpolatePixelInfo(const Image *image,
5395% const CacheView *image_view,const PixelInterpolateMethod method,
5396% const double x,const double y,PixelInfo *pixel,
5397% ExceptionInfo *exception)
5398%
5399% A description of each parameter follows:
5400%
5401% o image: the image.
5402%
5403% o image_view: the image view.
5404%
5405% o method: the pixel color interpolation method.
5406%
5407% o x,y: A double representing the current (x,y) position of the pixel.
5408%
5409% o pixel: return the interpolated pixel here.
5410%
5411% o exception: return any errors or warnings in this structure.
5412%
5413*/
5414
5415static inline void AlphaBlendPixelInfo(const Image *image,
5416 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
5417{
5418 if ((image->alpha_trait & BlendPixelTrait) == 0)
5419 {
5420 *alpha=1.0;
5421 pixel_info->red=(double) GetPixelRed(image,pixel);
5422 pixel_info->green=(double) GetPixelGreen(image,pixel);
5423 pixel_info->blue=(double) GetPixelBlue(image,pixel);
5424 pixel_info->black=0.0;
5425 if (image->colorspace == CMYKColorspace)
5426 pixel_info->black=(double) GetPixelBlack(image,pixel);
5427 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5428 return;
5429 }
5430 *alpha=QuantumScale*(double) GetPixelAlpha(image,pixel);
5431 pixel_info->red=(*alpha*(double) GetPixelRed(image,pixel));
5432 pixel_info->green=(*alpha*(double) GetPixelGreen(image,pixel));
5433 pixel_info->blue=(*alpha*(double) GetPixelBlue(image,pixel));
5434 pixel_info->black=0.0;
5435 if (image->colorspace == CMYKColorspace)
5436 pixel_info->black=(*alpha*(double) GetPixelBlack(image,pixel));
5437 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5438}
5439
5440MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
5441 const CacheView_ *image_view,const PixelInterpolateMethod method,
5442 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5443{
5444 const Quantum
5445 *p;
5446
5447 double
5448 alpha[16],
5449 gamma;
5450
5451 MagickBooleanType
5452 status;
5453
5454 PixelInfo
5455 pixels[16];
5456
5457 PixelInterpolateMethod
5458 interpolate;
5459
5460 ssize_t
5461 i,
5462 x_offset,
5463 y_offset;
5464
5465 assert(image != (Image *) NULL);
5466 assert(image->signature == MagickCoreSignature);
5467 assert(image_view != (CacheView *) NULL);
5468 status=MagickTrue;
5469 x_offset=CastDoubleToSsizeT(floor(x));
5470 y_offset=CastDoubleToSsizeT(floor(y));
5471 interpolate=method;
5472 if (interpolate == UndefinedInterpolatePixel)
5473 interpolate=image->interpolate;
5474 GetPixelInfoPixel(image,(const Quantum *) NULL,pixel);
5475 (void) memset(&pixels,0,sizeof(pixels));
5476 switch (interpolate)
5477 {
5478 case AverageInterpolatePixel: /* nearest 4 neighbours */
5479 case Average9InterpolatePixel: /* nearest 9 neighbours */
5480 case Average16InterpolatePixel: /* nearest 16 neighbours */
5481 {
5482 ssize_t
5483 count;
5484
5485 count=2; /* size of the area to average - default nearest 4 */
5486 if (interpolate == Average9InterpolatePixel)
5487 {
5488 count=3;
5489 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
5490 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
5491 }
5492 else
5493 if (interpolate == Average16InterpolatePixel)
5494 {
5495 count=4;
5496 x_offset--;
5497 y_offset--;
5498 }
5499 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
5500 (size_t) count,exception);
5501 if (p == (const Quantum *) NULL)
5502 {
5503 status=MagickFalse;
5504 break;
5505 }
5506 pixel->red=0.0;
5507 pixel->green=0.0;
5508 pixel->blue=0.0;
5509 pixel->black=0.0;
5510 pixel->alpha=0.0;
5511 count*=count; /* number of pixels - square of size */
5512 for (i=0; i < (ssize_t) count; i++)
5513 {
5514 AlphaBlendPixelInfo(image,p,pixels,alpha);
5515 gamma=MagickSafeReciprocal(alpha[0]);
5516 pixel->red+=gamma*pixels[0].red;
5517 pixel->green+=gamma*pixels[0].green;
5518 pixel->blue+=gamma*pixels[0].blue;
5519 pixel->black+=gamma*pixels[0].black;
5520 pixel->alpha+=pixels[0].alpha;
5521 p+=(ptrdiff_t) GetPixelChannels(image);
5522 }
5523 gamma=1.0/count; /* average weighting of each pixel in area */
5524 pixel->red*=gamma;
5525 pixel->green*=gamma;
5526 pixel->blue*=gamma;
5527 pixel->black*=gamma;
5528 pixel->alpha*=gamma;
5529 break;
5530 }
5531 case BackgroundInterpolatePixel:
5532 {
5533 *pixel=image->background_color; /* Copy PixelInfo Structure */
5534 break;
5535 }
5536 case BilinearInterpolatePixel:
5537 default:
5538 {
5539 PointInfo
5540 delta,
5541 epsilon;
5542
5543 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5544 if (p == (const Quantum *) NULL)
5545 {
5546 status=MagickFalse;
5547 break;
5548 }
5549 for (i=0; i < 4L; i++)
5550 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5551 pixels+i,alpha+i);
5552 delta.x=x-x_offset;
5553 delta.y=y-y_offset;
5554 epsilon.x=1.0-delta.x;
5555 epsilon.y=1.0-delta.y;
5556 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5557 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5558 gamma=MagickSafeReciprocal(gamma);
5559 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5560 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5561 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5562 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5563 pixels[3].green));
5564 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5565 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5566 pixels[3].blue));
5567 if (image->colorspace == CMYKColorspace)
5568 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5569 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5570 pixels[3].black));
5571 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5572 gamma=MagickSafeReciprocal(gamma);
5573 pixel->alpha=gamma*(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5574 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5575 pixels[3].alpha));
5576 break;
5577 }
5578 case BlendInterpolatePixel:
5579 {
5580 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5581 if (p == (const Quantum *) NULL)
5582 {
5583 status=MagickFalse;
5584 break;
5585 }
5586 for (i=0; i < 4L; i++)
5587 {
5588 GetPixelInfoPixel(image,p+i*(ssize_t) GetPixelChannels(image),pixels+i);
5589 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5590 pixels+i,alpha+i);
5591 }
5592 gamma=1.0; /* number of pixels blended together (its variable) */
5593 for (i=0; i <= 1L; i++)
5594 {
5595 if ((y-y_offset) >= 0.75)
5596 {
5597 alpha[i]=alpha[i+2]; /* take right pixels */
5598 pixels[i]=pixels[i+2];
5599 }
5600 else
5601 if ((y-y_offset) > 0.25)
5602 {
5603 gamma=2.0; /* blend both pixels in row */
5604 alpha[i]+=alpha[i+2]; /* add up alpha weights */
5605 pixels[i].red+=pixels[i+2].red;
5606 pixels[i].green+=pixels[i+2].green;
5607 pixels[i].blue+=pixels[i+2].blue;
5608 pixels[i].black+=pixels[i+2].black;
5609 pixels[i].alpha+=pixels[i+2].alpha;
5610 }
5611 }
5612 if ((x-x_offset) >= 0.75)
5613 {
5614 alpha[0]=alpha[1];
5615 pixels[0]=pixels[1];
5616 }
5617 else
5618 if ((x-x_offset) > 0.25)
5619 {
5620 gamma*=2.0; /* blend both rows */
5621 alpha[0]+= alpha[1]; /* add up alpha weights */
5622 pixels[0].red+=pixels[1].red;
5623 pixels[0].green+=pixels[1].green;
5624 pixels[0].blue+=pixels[1].blue;
5625 pixels[0].black+=pixels[1].black;
5626 pixels[0].alpha+=pixels[1].alpha;
5627 }
5628 gamma=1.0/gamma;
5629 alpha[0]=MagickSafeReciprocal(alpha[0]);
5630 pixel->red=alpha[0]*pixels[0].red;
5631 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5632 pixel->blue=alpha[0]*pixels[0].blue;
5633 pixel->black=alpha[0]*pixels[0].black;
5634 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
5635 break;
5636 }
5637 case CatromInterpolatePixel:
5638 {
5639 double
5640 cx[4],
5641 cy[4];
5642
5643 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5644 exception);
5645 if (p == (const Quantum *) NULL)
5646 {
5647 status=MagickFalse;
5648 break;
5649 }
5650 for (i=0; i < 16L; i++)
5651 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5652 pixels+i,alpha+i);
5653 CatromWeights((double) (x-x_offset),&cx);
5654 CatromWeights((double) (y-y_offset),&cy);
5655 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5656 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5657 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5658 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5659 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5660 pixels[14].red+cx[3]*pixels[15].red));
5661 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5662 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5663 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5664 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5665 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5666 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5667 pixels[15].green));
5668 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5669 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5670 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5671 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5672 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5673 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5674 if (image->colorspace == CMYKColorspace)
5675 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5676 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5677 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5678 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5679 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5680 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5681 pixels[15].black));
5682 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5683 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5684 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5685 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5686 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5687 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5688 break;
5689 }
5690 case IntegerInterpolatePixel:
5691 {
5692 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5693 if (p == (const Quantum *) NULL)
5694 {
5695 status=MagickFalse;
5696 break;
5697 }
5698 GetPixelInfoPixel(image,p,pixel);
5699 break;
5700 }
5701 case MeshInterpolatePixel:
5702 {
5703 PointInfo
5704 delta,
5705 luminance;
5706
5707 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5708 if (p == (const Quantum *) NULL)
5709 {
5710 status=MagickFalse;
5711 break;
5712 }
5713 delta.x=x-x_offset;
5714 delta.y=y-y_offset;
5715 luminance.x=GetPixelLuma(image,p)-(double)
5716 GetPixelLuma(image,p+3*GetPixelChannels(image));
5717 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
5718 GetPixelLuma(image,p+2*GetPixelChannels(image));
5719 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5720 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5721 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5722 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5723 if (fabs((double) luminance.x) < fabs((double) luminance.y))
5724 {
5725 /*
5726 Diagonal 0-3 NW-SE.
5727 */
5728 if (delta.x <= delta.y)
5729 {
5730 /*
5731 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5732 */
5733 delta.y=1.0-delta.y;
5734 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5735 gamma=MagickSafeReciprocal(gamma);
5736 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5737 pixels[3].red,pixels[0].red);
5738 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5739 pixels[3].green,pixels[0].green);
5740 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5741 pixels[3].blue,pixels[0].blue);
5742 if (image->colorspace == CMYKColorspace)
5743 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5744 pixels[3].black,pixels[0].black);
5745 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5746 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5747 pixels[3].alpha,pixels[0].alpha);
5748 }
5749 else
5750 {
5751 /*
5752 Top-right triangle (pixel:1 , diagonal: 0-3).
5753 */
5754 delta.x=1.0-delta.x;
5755 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5756 gamma=MagickSafeReciprocal(gamma);
5757 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5758 pixels[0].red,pixels[3].red);
5759 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5760 pixels[0].green,pixels[3].green);
5761 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5762 pixels[0].blue,pixels[3].blue);
5763 if (image->colorspace == CMYKColorspace)
5764 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5765 pixels[0].black,pixels[3].black);
5766 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5767 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5768 pixels[0].alpha,pixels[3].alpha);
5769 }
5770 }
5771 else
5772 {
5773 /*
5774 Diagonal 1-2 NE-SW.
5775 */
5776 if (delta.x <= (1.0-delta.y))
5777 {
5778 /*
5779 Top-left triangle (pixel: 0, diagonal: 1-2).
5780 */
5781 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5782 gamma=MagickSafeReciprocal(gamma);
5783 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5784 pixels[1].red,pixels[2].red);
5785 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5786 pixels[1].green,pixels[2].green);
5787 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5788 pixels[1].blue,pixels[2].blue);
5789 if (image->colorspace == CMYKColorspace)
5790 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5791 pixels[1].black,pixels[2].black);
5792 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5793 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5794 pixels[1].alpha,pixels[2].alpha);
5795 }
5796 else
5797 {
5798 /*
5799 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5800 */
5801 delta.x=1.0-delta.x;
5802 delta.y=1.0-delta.y;
5803 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5804 gamma=MagickSafeReciprocal(gamma);
5805 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5806 pixels[2].red,pixels[1].red);
5807 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5808 pixels[2].green,pixels[1].green);
5809 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5810 pixels[2].blue,pixels[1].blue);
5811 if (image->colorspace == CMYKColorspace)
5812 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5813 pixels[2].black,pixels[1].black);
5814 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5815 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5816 pixels[2].alpha,pixels[1].alpha);
5817 }
5818 }
5819 break;
5820 }
5821 case NearestInterpolatePixel:
5822 {
5823 x_offset=CastDoubleToSsizeT(floor(x+0.5));
5824 y_offset=CastDoubleToSsizeT(floor(y+0.5));
5825 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5826 if (p == (const Quantum *) NULL)
5827 {
5828 status=MagickFalse;
5829 break;
5830 }
5831 GetPixelInfoPixel(image,p,pixel);
5832 break;
5833 }
5834 case SplineInterpolatePixel:
5835 {
5836 double
5837 cx[4],
5838 cy[4];
5839
5840 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5841 exception);
5842 if (p == (const Quantum *) NULL)
5843 {
5844 status=MagickFalse;
5845 break;
5846 }
5847 for (i=0; i < 16L; i++)
5848 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5849 pixels+i,alpha+i);
5850 SplineWeights((double) (x-x_offset),&cx);
5851 SplineWeights((double) (y-y_offset),&cy);
5852 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5853 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5854 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5855 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5856 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5857 pixels[14].red+cx[3]*pixels[15].red));
5858 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5859 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5860 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5861 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5862 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5863 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5864 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5865 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5866 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5867 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5868 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5869 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5870 if (image->colorspace == CMYKColorspace)
5871 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5872 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5873 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5874 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5875 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5876 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5877 pixels[15].black));
5878 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5879 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5880 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5881 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5882 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5883 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5884 break;
5885 }
5886 }
5887 return(status);
5888}
5889␌
5890/*
5891%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5892% %
5893% %
5894% %
5895+ I s F u z z y E q u i v a l e n c e P i x e l %
5896% %
5897% %
5898% %
5899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5900%
5901% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5902% pixels is less than the specified distance in a linear three (or four)
5903% dimensional color space.
5904%
5905% The format of the IsFuzzyEquivalencePixel method is:
5906%
5907% void IsFuzzyEquivalencePixel(const Image *image,const Quantum *p,
5908% const Image *target_image,const Quantum *q)
5909%
5910% A description of each parameter follows:
5911%
5912% o image: the source image.
5913%
5914% o p: Pixel p.
5915%
5916% o target: the target image.
5917%
5918% o q: Pixel q.
5919%
5920*/
5921MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *image,
5922 const Quantum *p,const Image *target_image,const Quantum *q)
5923{
5924 double
5925 alpha = QuantumScale*(double) GetPixelAlpha(image,p),
5926 fuzz = GetFuzzyColorDistance(image,target_image),
5927 target_alpha = QuantumScale*(double) GetPixelAlpha(target_image,q);
5928
5929 ssize_t
5930 i;
5931
5932 /*
5933 MSE metric for comparing two pixels.
5934 */
5935 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
5936 {
5937 double
5938 error;
5939
5940 PixelChannel channel = GetPixelChannelChannel(image,i);
5941 PixelTrait traits = GetPixelChannelTraits(image,channel);
5942 PixelTrait target_traits = GetPixelChannelTraits(target_image,channel);
5943 if (((traits & UpdatePixelTrait) == 0) ||
5944 ((target_traits & UpdatePixelTrait) == 0))
5945 continue;
5946 if (channel == AlphaPixelChannel)
5947 error=(double) p[i]-(double) GetPixelChannel(target_image,channel,q);
5948 else
5949 error=alpha*(double) p[i]-target_alpha*
5950 GetPixelChannel(target_image,channel,q);
5951 if (MagickSafeSignificantError(error*error,fuzz) != MagickFalse)
5952 return(MagickFalse);
5953 }
5954 return(MagickTrue);
5955}
5956␌
5957/*
5958%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5959% %
5960% %
5961% %
5962+ 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 %
5963% %
5964% %
5965% %
5966%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5967%
5968% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5969% colors is less than the specified distance in a linear three (or four)
5970% dimensional color space.
5971%
5972% This implements the equivalent of:
5973% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
5974%
5975% Which produces a multi-dimensional cone for that colorspace along the
5976% transparency vector.
5977%
5978% For example for an RGB:
5979% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5980%
5981% See https://imagemagick.org/Usage/bugs/fuzz_distance/
5982%
5983% Hue colorspace distances need more work. Hue is not a distance, it is an
5984% angle!
5985%
5986% A check that q is in the same color space as p should be made and the
5987% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5988%
5989% The format of the IsFuzzyEquivalencePixelInfo method is:
5990%
5991% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5992% const PixelInfo *q)
5993%
5994% A description of each parameter follows:
5995%
5996% o p: Pixel p.
5997%
5998% o q: Pixel q.
5999%
6000*/
6001MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6002 const PixelInfo *q)
6003{
6004 double
6005 distance,
6006 fuzz,
6007 pixel,
6008 scale;
6009
6010 fuzz=p->fuzz*p->fuzz+q->fuzz*q->fuzz;
6011 scale=1.0;
6012 distance=0.0;
6013 if ((p->alpha_trait != UndefinedPixelTrait) ||
6014 (q->alpha_trait != UndefinedPixelTrait))
6015 {
6016 /*
6017 Transparencies are involved - set alpha distance.
6018 */
6019 pixel=(p->alpha_trait != UndefinedPixelTrait ? p->alpha :
6020 (double) OpaqueAlpha)-(q->alpha_trait != UndefinedPixelTrait ?
6021 q->alpha : (double) OpaqueAlpha);
6022 distance=pixel*pixel;
6023 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6024 return(MagickFalse);
6025 /*
6026 Generate a alpha scaling factor to generate a 4D cone on colorspace.
6027 If one color is transparent, distance has no color component.
6028 */
6029 if (p->alpha_trait != UndefinedPixelTrait)
6030 scale=(QuantumScale*p->alpha);
6031 if (q->alpha_trait != UndefinedPixelTrait)
6032 scale*=(QuantumScale*q->alpha);
6033 if (scale <= MagickEpsilon)
6034 return(MagickTrue);
6035 }
6036 /*
6037 CMYK create a CMY cube with a multi-dimensional cone toward black.
6038 */
6039 if (p->colorspace == CMYKColorspace)
6040 {
6041 pixel=p->black-q->black;
6042 distance+=pixel*pixel*scale;
6043 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6044 return(MagickFalse);
6045 scale*=QuantumScale*((double) QuantumRange-(double) p->black);
6046 scale*=QuantumScale*((double) QuantumRange-(double) q->black);
6047 }
6048 /*
6049 RGB or CMY color cube.
6050 */
6051 distance*=3.0; /* rescale appropriately */
6052 fuzz*=3.0;
6053 pixel=p->red-q->red;
6054 if (IsHueCompatibleColorspace(p->colorspace) != MagickFalse)
6055 {
6056 /*
6057 This calculates a arc distance for hue-- it should be a vector
6058 angle of 'S'/'W' length with 'L'/'B' forming appropriate cones.
6059 In other words this is a hack - Anthony.
6060 */
6061 if (fabs((double) pixel) > ((double) QuantumRange/2.0))
6062 pixel-=(double) QuantumRange;
6063 pixel*=2.0;
6064 }
6065 distance+=pixel*pixel*scale;
6066 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6067 return(MagickFalse);
6068 pixel=p->green-q->green;
6069 distance+=pixel*pixel*scale;
6070 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6071 return(MagickFalse);
6072 pixel=p->blue-q->blue;
6073 distance+=pixel*pixel*scale;
6074 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6075 return(MagickFalse);
6076 return(MagickTrue);
6077}
6078␌
6079/*
6080%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6081% %
6082% %
6083% %
6084+ R e s e t P i x e l C h a n n e l M a p %
6085% %
6086% %
6087% %
6088%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6089%
6090% ResetPixelChannelMap() defines the standard pixel component map.
6091%
6092% The format of the ResetPixelChannelMap() method is:
6093%
6094% MagickBooleanType ResetPixelChannelMap(Image *image)
6095%
6096% A description of each parameter follows:
6097%
6098% o image: the image.
6099%
6100% o exception: return any errors or warnings in this structure.
6101%
6102*/
6103MagickPrivate MagickBooleanType ResetPixelChannelMap(Image *image,
6104 ExceptionInfo *exception)
6105{
6106 PixelTrait
6107 trait;
6108
6109 ssize_t
6110 n;
6111
6112 assert(image != (Image *) NULL);
6113 assert(image->signature == MagickCoreSignature);
6114 (void) memset(image->channel_map,0,MaxPixelChannels*
6115 sizeof(*image->channel_map));
6116 trait=UpdatePixelTrait;
6117 if (image->alpha_trait != UndefinedPixelTrait)
6118 trait=(PixelTrait) (trait | BlendPixelTrait);
6119 n=0;
6120 if ((image->colorspace == LinearGRAYColorspace) ||
6121 (image->colorspace == GRAYColorspace))
6122 {
6123 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
6124 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
6125 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
6126 }
6127 else
6128 {
6129 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
6130 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
6131 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
6132 }
6133 if (image->colorspace == CMYKColorspace)
6134 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
6135 if (image->alpha_trait != UndefinedPixelTrait)
6136 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
6137 if (image->storage_class == PseudoClass)
6138 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
6139 if ((image->channels & ReadMaskChannel) != 0)
6140 SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++);
6141 if ((image->channels & WriteMaskChannel) != 0)
6142 SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++);
6143 if ((image->channels & CompositeMaskChannel) != 0)
6144 SetPixelChannelAttributes(image,CompositeMaskPixelChannel,CopyPixelTrait,
6145 n++);
6146 if (image->number_meta_channels != 0)
6147 {
6148 PixelChannel
6149 meta_channel;
6150
6151 ssize_t
6152 i;
6153
6154 if (image->number_meta_channels >= (size_t) (MaxPixelChannels-MetaPixelChannels))
6155 {
6156 image->number_channels=(size_t) n;
6157 image->number_meta_channels=0;
6158 (void) SetPixelChannelMask(image,image->channel_mask);
6159 ThrowBinaryException(CorruptImageError,"MaximumChannelsExceeded",
6160 image->filename);
6161 }
6162 meta_channel=MetaPixelChannels;
6163 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
6164 {
6165 SetPixelChannelAttributes(image,meta_channel,UpdatePixelTrait,n);
6166 meta_channel=(PixelChannel) (meta_channel+1);
6167 n++;
6168 }
6169 }
6170 image->number_channels=(size_t) n;
6171 (void) SetPixelChannelMask(image,image->channel_mask);
6172 return(MagickTrue);
6173}
6174␌
6175/*
6176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6177% %
6178% %
6179% %
6180% S e t P i x e l C h a n n e l M a s k %
6181% %
6182% %
6183% %
6184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6185%
6186% SetPixelChannelMask() sets the pixel channel map from the specified channel
6187% mask.
6188%
6189% The format of the SetPixelChannelMask method is:
6190%
6191% ChannelType SetPixelChannelMask(Image *image,
6192% const ChannelType channel_mask)
6193%
6194% A description of each parameter follows:
6195%
6196% o image: the image.
6197%
6198% o channel_mask: the channel mask.
6199%
6200*/
6201
6202static void LogPixelChannels(const Image *image)
6203{
6204 ssize_t
6205 i;
6206
6207 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[0x%08llx]",
6208 image->filename,(MagickOffsetType) image->channel_mask);
6209 for (i=0; i < (ssize_t) image->number_channels; i++)
6210 {
6211 char
6212 channel_name[MagickPathExtent],
6213 traits[MagickPathExtent];
6214
6215 const char
6216 *name;
6217
6218 PixelChannel
6219 channel;
6220
6221 channel=GetPixelChannelChannel(image,i);
6222 switch (channel)
6223 {
6224 case RedPixelChannel:
6225 {
6226 name="red";
6227 if (image->colorspace == CMYKColorspace)
6228 name="cyan";
6229 if ((image->colorspace == LinearGRAYColorspace) ||
6230 (image->colorspace == GRAYColorspace))
6231 name="gray";
6232 break;
6233 }
6234 case GreenPixelChannel:
6235 {
6236 name="green";
6237 if (image->colorspace == CMYKColorspace)
6238 name="magenta";
6239 break;
6240 }
6241 case BluePixelChannel:
6242 {
6243 name="blue";
6244 if (image->colorspace == CMYKColorspace)
6245 name="yellow";
6246 break;
6247 }
6248 case BlackPixelChannel:
6249 {
6250 name="black";
6251 if (image->storage_class == PseudoClass)
6252 name="index";
6253 break;
6254 }
6255 case IndexPixelChannel:
6256 {
6257 name="index";
6258 break;
6259 }
6260 case AlphaPixelChannel:
6261 {
6262 name="alpha";
6263 break;
6264 }
6265 case ReadMaskPixelChannel:
6266 {
6267 name="read-mask";
6268 break;
6269 }
6270 case WriteMaskPixelChannel:
6271 {
6272 name="write-mask";
6273 break;
6274 }
6275 case CompositeMaskPixelChannel:
6276 {
6277 name="composite-mask";
6278 break;
6279 }
6280 case MetaPixelChannels:
6281 {
6282 name="meta";
6283 break;
6284 }
6285 default:
6286 name="undefined";
6287 }
6288 if (image->colorspace == UndefinedColorspace)
6289 {
6290 (void) FormatLocaleString(channel_name,MagickPathExtent,"%.17g",
6291 (double) channel);
6292 name=(const char *) channel_name;
6293 }
6294 *traits='\0';
6295 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0)
6296 (void) ConcatenateMagickString(traits,"update,",MagickPathExtent);
6297 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0)
6298 (void) ConcatenateMagickString(traits,"blend,",MagickPathExtent);
6299 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0)
6300 (void) ConcatenateMagickString(traits,"copy,",MagickPathExtent);
6301 if (*traits == '\0')
6302 (void) ConcatenateMagickString(traits,"undefined,",MagickPathExtent);
6303 traits[strlen(traits)-1]='\0';
6304 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.17g: %s (%s)",
6305 (double) i,name,traits);
6306 }
6307}
6308
6309MagickExport ChannelType SetPixelChannelMask(Image *image,
6310 const ChannelType channel_mask)
6311{
6312#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
6313
6314 ChannelType
6315 mask;
6316
6317 ssize_t
6318 i;
6319
6320 assert(image != (Image *) NULL);
6321 assert(image->signature == MagickCoreSignature);
6322 if (image->debug != MagickFalse)
6323 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[0x%08llx]",
6324 image->filename,(MagickOffsetType) channel_mask);
6325 mask=image->channel_mask;
6326 image->channel_mask=channel_mask;
6327 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
6328 {
6329 PixelChannel channel = GetPixelChannelChannel(image,i);
6330 if (GetChannelBit(channel_mask,channel) == 0)
6331 {
6332 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6333 continue;
6334 }
6335 if (channel == AlphaPixelChannel)
6336 {
6337 if ((image->alpha_trait & CopyPixelTrait) != 0)
6338 {
6339 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6340 continue;
6341 }
6342 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
6343 continue;
6344 }
6345 if (image->alpha_trait != UndefinedPixelTrait)
6346 {
6347 SetPixelChannelTraits(image,channel,(PixelTrait) (UpdatePixelTrait |
6348 BlendPixelTrait));
6349 continue;
6350 }
6351 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
6352 }
6353 if (image->storage_class == PseudoClass)
6354 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
6355 if ((image->channels & ReadMaskChannel) != 0)
6356 SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait);
6357 if ((image->channels & WriteMaskChannel) != 0)
6358 SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait);
6359 if ((image->channels & CompositeMaskChannel) != 0)
6360 SetPixelChannelTraits(image,CompositeMaskPixelChannel,CopyPixelTrait);
6361 if ((GetLogEventMask() & PixelEvent) != 0)
6362 LogPixelChannels(image);
6363 return(mask);
6364}
6365␌
6366/*
6367%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6368% %
6369% %
6370% %
6371% S e t P i x e l M e t a C h a n n e l s %
6372% %
6373% %
6374% %
6375%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6376%
6377% SetPixelMetaChannels() sets the image meta channels.
6378%
6379% The format of the SetPixelMetaChannels method is:
6380%
6381% MagickBooleanType SetPixelMetaChannels(Image *image,
6382% const size_t number_meta_channels,ExceptionInfo *exception)
6383%
6384% A description of each parameter follows:
6385%
6386% o image: the image.
6387%
6388% o number_meta_channels: the number of meta channels.
6389%
6390% o exception: return any errors or warnings in this structure.
6391%
6392*/
6393MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
6394 const size_t number_meta_channels,ExceptionInfo *exception)
6395{
6396 MagickBooleanType
6397 status;
6398
6399 if (number_meta_channels >= (size_t) (MaxPixelChannels-MetaPixelChannels))
6400 ThrowBinaryException(CorruptImageError,"MaximumChannelsExceeded",
6401 image->filename);
6402 image->number_meta_channels=number_meta_channels;
6403 status=ResetPixelChannelMap(image,exception);
6404 if (status == MagickFalse)
6405 return(MagickFalse);
6406 return(SyncImagePixelCache(image,exception));
6407}
6408␌
6409/*
6410%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6411% %
6412% %
6413% %
6414% S o r t I m a g e P i x e l s %
6415% %
6416% %
6417% %
6418%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6419%
6420% SortImagePixels() sorts pixels within each scanline in ascending order of
6421% intensity.
6422%
6423% The format of the SortImagePixels method is:
6424%
6425% MagickBooleanType SortImagePixels(Image *image,ExceptionInfo *exception)
6426%
6427% A description of each parameter follows:
6428%
6429% o image: the image.
6430%
6431% o exception: return any errors or warnings in this structure.
6432%
6433*/
6434MagickExport MagickBooleanType SortImagePixels(Image *image,
6435 ExceptionInfo *exception)
6436{
6437#define SolarizeImageTag "Solarize/Image"
6438
6439 CacheView
6440 *image_view;
6441
6442 MagickBooleanType
6443 status;
6444
6445 MagickOffsetType
6446 progress;
6447
6448 ssize_t
6449 y;
6450
6451 /*
6452 Sort image pixels.
6453 */
6454 assert(image != (Image *) NULL);
6455 assert(image->signature == MagickCoreSignature);
6456 if (IsEventLogging() != MagickFalse)
6457 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6458 status=MagickTrue;
6459 progress=0;
6460 image_view=AcquireAuthenticCacheView(image,exception);
6461#if defined(MAGICKCORE_OPENMP_SUPPORT)
6462 #pragma omp parallel for schedule(static) shared(progress,status) \
6463 magick_number_threads(image,image,image->rows,1)
6464#endif
6465 for (y=0; y < (ssize_t) image->rows; y++)
6466 {
6467 Quantum
6468 *magick_restrict q;
6469
6470 ssize_t
6471 x;
6472
6473 if (status == MagickFalse)
6474 continue;
6475 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
6476 if (q == (Quantum *) NULL)
6477 {
6478 status=MagickFalse;
6479 continue;
6480 }
6481 for (x=0; x < (ssize_t) image->columns-1; x++)
6482 {
6483 MagickRealType
6484 current,
6485 previous;
6486
6487 ssize_t
6488 j;
6489
6490 previous=GetPixelIntensity(image,q);
6491 for (j=0; j < ((ssize_t) image->columns-x-1); j++)
6492 {
6493 current=GetPixelIntensity(image,q+(j+1)*(ssize_t)
6494 GetPixelChannels(image));
6495 if (previous > current)
6496 {
6497 Quantum
6498 pixel[MaxPixelChannels];
6499
6500 /*
6501 Swap adjacent pixels.
6502 */
6503 (void) memcpy(pixel,q+j*(ssize_t) GetPixelChannels(image),
6504 GetPixelChannels(image)*sizeof(Quantum));
6505 (void) memcpy(q+j*(ssize_t) GetPixelChannels(image),q+(j+1)*
6506 (ssize_t) GetPixelChannels(image),GetPixelChannels(image)*
6507 sizeof(Quantum));
6508 (void) memcpy(q+(j+1)*(ssize_t) GetPixelChannels(image),pixel,
6509 GetPixelChannels(image)*sizeof(Quantum));
6510 }
6511 else
6512 previous=current;
6513 }
6514 }
6515 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
6516 status=MagickFalse;
6517 if (image->progress_monitor != (MagickProgressMonitor) NULL)
6518 {
6519 MagickBooleanType
6520 proceed;
6521
6522#if defined(MAGICKCORE_OPENMP_SUPPORT)
6523 #pragma omp atomic
6524#endif
6525 progress++;
6526 proceed=SetImageProgress(image,SolarizeImageTag,progress,image->rows);
6527 if (proceed == MagickFalse)
6528 status=MagickFalse;
6529 }
6530 }
6531 image_view=DestroyCacheView(image_view);
6532 return(status);
6533}