MagickCore 7.1.2-35
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 {
4284 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4285 return(MagickFalse);
4286 }
4287 /*
4288 Transfer the pixels from the pixel data to the image.
4289 */
4290 roi.width=width;
4291 roi.height=height;
4292 roi.x=x;
4293 roi.y=y;
4294 switch (type)
4295 {
4296 case CharPixel:
4297 {
4298 status=ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
4299 break;
4300 }
4301 case DoublePixel:
4302 {
4303 status=ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
4304 break;
4305 }
4306 case FloatPixel:
4307 {
4308 status=ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
4309 break;
4310 }
4311 case LongPixel:
4312 {
4313 status=ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
4314 break;
4315 }
4316 case LongLongPixel:
4317 {
4318 status=ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
4319 break;
4320 }
4321 case QuantumPixel:
4322 {
4323 status=ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
4324 break;
4325 }
4326 case ShortPixel:
4327 {
4328 status=ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
4329 break;
4330 }
4331 default:
4332 {
4333 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
4334 "UnrecognizedStorageType","`%d'",type);
4335 status=MagickFalse;
4336 }
4337 }
4338 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4339 return(status);
4340}
4341␌
4342/*
4343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4344% %
4345% %
4346% %
4347% I n t e r p o l a t e P i x e l C h a n n e l %
4348% %
4349% %
4350% %
4351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4352%
4353% InterpolatePixelChannel() applies a pixel interpolation method between a
4354% floating point coordinate and the pixels surrounding that coordinate. No
4355% pixel area resampling, or scaling of the result is performed.
4356%
4357% Interpolation is restricted to just the specified channel.
4358%
4359% The format of the InterpolatePixelChannel method is:
4360%
4361% MagickBooleanType InterpolatePixelChannel(
4362% const Image *magick_restrict image,const CacheView *image_view,
4363% const PixelChannel channel,const PixelInterpolateMethod method,
4364% const double x,const double y,double *pixel,ExceptionInfo *exception)
4365%
4366% A description of each parameter follows:
4367%
4368% o image: the image.
4369%
4370% o image_view: the image view.
4371%
4372% o channel: the pixel channel to interpolate.
4373%
4374% o method: the pixel color interpolation method.
4375%
4376% o x,y: A double representing the current (x,y) position of the pixel.
4377%
4378% o pixel: return the interpolated pixel here.
4379%
4380% o exception: return any errors or warnings in this structure.
4381%
4382*/
4383
4384static inline void CatromWeights(const double x,double (*weights)[4])
4385{
4386 double
4387 alpha,
4388 beta,
4389 gamma;
4390
4391 /*
4392 Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4393 of the standard four 1D Catmull-Rom weights. The sampling location is
4394 assumed between the second and third input pixel locations, and x is the
4395 position relative to the second input pixel location. Formulas originally
4396 derived for the VIPS (Virtual Image Processing System) library.
4397 */
4398 alpha=(double) 1.0-x;
4399 beta=(double) (-0.5)*x*alpha;
4400 (*weights)[0]=alpha*beta;
4401 (*weights)[3]=x*beta;
4402 /*
4403 The following computation of the inner weights from the outer ones work
4404 for all Keys cubics.
4405 */
4406 gamma=(*weights)[3]-(*weights)[0];
4407 (*weights)[1]=alpha-(*weights)[0]+gamma;
4408 (*weights)[2]=x-(*weights)[3]-gamma;
4409}
4410
4411static inline void SplineWeights(const double x,double (*weights)[4])
4412{
4413 double
4414 alpha,
4415 beta;
4416
4417 /*
4418 Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation
4419 of the standard four 1D cubic B-spline smoothing weights. The sampling
4420 location is assumed between the second and third input pixel locations,
4421 and x is the position relative to the second input pixel location.
4422 */
4423 alpha=(double) 1.0-x;
4424 (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4425 (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
4426 beta=(*weights)[3]-(*weights)[0];
4427 (*weights)[1]=alpha-(*weights)[0]+beta;
4428 (*weights)[2]=x-(*weights)[3]-beta;
4429}
4430
4431static inline double MeshInterpolate(const PointInfo *delta,const double p,
4432 const double x,const double y)
4433{
4434 return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4435}
4436
4437MagickExport MagickBooleanType InterpolatePixelChannel(
4438 const Image *magick_restrict image,const CacheView_ *image_view,
4439 const PixelChannel channel,const PixelInterpolateMethod method,const double x,
4440 const double y,double *pixel,ExceptionInfo *exception)
4441{
4442 const Quantum
4443 *magick_restrict p;
4444
4445 double
4446 alpha[16],
4447 gamma,
4448 pixels[16];
4449
4450 MagickBooleanType
4451 status;
4452
4453 PixelInterpolateMethod
4454 interpolate;
4455
4456 PixelTrait
4457 traits;
4458
4459 ssize_t
4460 i,
4461 x_offset,
4462 y_offset;
4463
4464 assert(image != (Image *) NULL);
4465 assert(image->signature == MagickCoreSignature);
4466 assert(image_view != (CacheView *) NULL);
4467 *pixel=0.0;
4468 if ((channel < 0) || (channel >= MaxPixelChannels))
4469 ThrowBinaryException(OptionError,"NoSuchImageChannel",image->filename);
4470 traits=GetPixelChannelTraits(image,channel);
4471 x_offset=CastDoubleToSsizeT(floor(x));
4472 y_offset=CastDoubleToSsizeT(floor(y));
4473 interpolate=method;
4474 if (interpolate == UndefinedInterpolatePixel)
4475 interpolate=image->interpolate;
4476 status=MagickTrue;
4477 switch (interpolate)
4478 {
4479 case AverageInterpolatePixel: /* nearest 4 neighbours */
4480 case Average9InterpolatePixel: /* nearest 9 neighbours */
4481 case Average16InterpolatePixel: /* nearest 16 neighbours */
4482 {
4483 ssize_t
4484 count;
4485
4486 count=2; /* size of the area to average - default nearest 4 */
4487 if (interpolate == Average9InterpolatePixel)
4488 {
4489 count=3;
4490 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
4491 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
4492 }
4493 else
4494 if (interpolate == Average16InterpolatePixel)
4495 {
4496 count=4;
4497 x_offset--;
4498 y_offset--;
4499 }
4500 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
4501 (size_t) count,exception);
4502 if (p == (const Quantum *) NULL)
4503 {
4504 status=MagickFalse;
4505 break;
4506 }
4507 count*=count; /* Number of pixels to average */
4508 if ((traits & BlendPixelTrait) == 0)
4509 for (i=0; i < (ssize_t) count; i++)
4510 {
4511 alpha[i]=1.0;
4512 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4513 GetPixelChannelOffset(image,channel)];
4514 }
4515 else
4516 for (i=0; i < (ssize_t) count; i++)
4517 {
4518 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4519 (ssize_t) GetPixelChannels(image));
4520 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4521 GetPixelChannelOffset(image,channel)];
4522 }
4523 for (i=0; i < (ssize_t) count; i++)
4524 {
4525 gamma=MagickSafeReciprocal(alpha[i])/count;
4526 *pixel+=gamma*pixels[i];
4527 }
4528 break;
4529 }
4530 case BilinearInterpolatePixel:
4531 default:
4532 {
4533 PointInfo
4534 delta,
4535 epsilon;
4536
4537 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4538 if (p == (const Quantum *) NULL)
4539 {
4540 status=MagickFalse;
4541 break;
4542 }
4543 if ((traits & BlendPixelTrait) == 0)
4544 for (i=0; i < 4; i++)
4545 {
4546 alpha[i]=1.0;
4547 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4548 GetPixelChannelOffset(image,channel)];
4549 }
4550 else
4551 for (i=0; i < 4; i++)
4552 {
4553 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4554 (ssize_t) GetPixelChannels(image));
4555 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4556 GetPixelChannelOffset(image,channel)];
4557 }
4558 delta.x=x-x_offset;
4559 delta.y=y-y_offset;
4560 epsilon.x=1.0-delta.x;
4561 epsilon.y=1.0-delta.y;
4562 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4563 (epsilon.x*alpha[2]+delta.x*alpha[3])));
4564 gamma=MagickSafeReciprocal(gamma);
4565 *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4566 (epsilon.x*pixels[2]+delta.x*pixels[3]));
4567 break;
4568 }
4569 case BlendInterpolatePixel:
4570 {
4571 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4572 if (p == (const Quantum *) NULL)
4573 {
4574 status=MagickFalse;
4575 break;
4576 }
4577 if ((traits & BlendPixelTrait) == 0)
4578 for (i=0; i < 4; i++)
4579 {
4580 alpha[i]=1.0;
4581 pixels[i]=(MagickRealType) p[i*(ssize_t) GetPixelChannels(image)+
4582 GetPixelChannelOffset(image,channel)];
4583 }
4584 else
4585 for (i=0; i < 4; i++)
4586 {
4587 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4588 (ssize_t) GetPixelChannels(image));
4589 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4590 GetPixelChannelOffset(image,channel)];
4591 }
4592 gamma=1.0; /* number of pixels blended together (its variable) */
4593 for (i=0; i <= 1L; i++) {
4594 if ((y-y_offset) >= 0.75)
4595 {
4596 alpha[i]=alpha[i+2]; /* take right pixels */
4597 pixels[i]=pixels[i+2];
4598 }
4599 else
4600 if ((y-y_offset) > 0.25)
4601 {
4602 gamma=2.0; /* blend both pixels in row */
4603 alpha[i]+=alpha[i+2]; /* add up alpha weights */
4604 pixels[i]+=pixels[i+2];
4605 }
4606 }
4607 if ((x-x_offset) >= 0.75)
4608 {
4609 alpha[0]=alpha[1]; /* take bottom row blend */
4610 pixels[0]=pixels[1];
4611 }
4612 else
4613 if ((x-x_offset) > 0.25)
4614 {
4615 gamma*=2.0; /* blend both rows */
4616 alpha[0]+=alpha[1]; /* add up alpha weights */
4617 pixels[0]+=pixels[1];
4618 }
4619 if (channel != AlphaPixelChannel)
4620 gamma=MagickSafeReciprocal(alpha[0]); /* (color) 1/alpha_weights */
4621 else
4622 gamma=MagickSafeReciprocal(gamma); /* (alpha) 1/number_of_pixels */
4623 *pixel=gamma*pixels[0];
4624 break;
4625 }
4626 case CatromInterpolatePixel:
4627 {
4628 double
4629 cx[4],
4630 cy[4];
4631
4632 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4633 exception);
4634 if (p == (const Quantum *) NULL)
4635 {
4636 status=MagickFalse;
4637 break;
4638 }
4639 if ((traits & BlendPixelTrait) == 0)
4640 for (i=0; i < 16; i++)
4641 {
4642 alpha[i]=1.0;
4643 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4644 GetPixelChannelOffset(image,channel)];
4645 }
4646 else
4647 for (i=0; i < 16; i++)
4648 {
4649 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4650 (ssize_t) GetPixelChannels(image));
4651 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4652 GetPixelChannelOffset(image,channel)];
4653 }
4654 CatromWeights((double) (x-x_offset),&cx);
4655 CatromWeights((double) (y-y_offset),&cy);
4656 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4657 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4658 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4659 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4660 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4661 cx[2]*alpha[14]+cx[3]*alpha[15])));
4662 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4663 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4664 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4665 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4666 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4667 break;
4668 }
4669 case IntegerInterpolatePixel:
4670 {
4671 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4672 if (p == (const Quantum *) NULL)
4673 {
4674 status=MagickFalse;
4675 break;
4676 }
4677 *pixel=(double) GetPixelChannel(image,channel,p);
4678 break;
4679 }
4680 case NearestInterpolatePixel:
4681 {
4682 x_offset=CastDoubleToSsizeT(floor(x+0.5));
4683 y_offset=CastDoubleToSsizeT(floor(y+0.5));
4684 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4685 if (p == (const Quantum *) NULL)
4686 {
4687 status=MagickFalse;
4688 break;
4689 }
4690 *pixel=(double) GetPixelChannel(image,channel,p);
4691 break;
4692 }
4693 case MeshInterpolatePixel:
4694 {
4695 PointInfo
4696 delta,
4697 luminance;
4698
4699 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4700 if (p == (const Quantum *) NULL)
4701 {
4702 status=MagickFalse;
4703 break;
4704 }
4705 if ((traits & BlendPixelTrait) == 0)
4706 for (i=0; i < 4; i++)
4707 {
4708 alpha[i]=1.0;
4709 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4710 GetPixelChannelOffset(image,channel)];
4711 }
4712 else
4713 for (i=0; i < 4; i++)
4714 {
4715 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4716 (ssize_t) GetPixelChannels(image));
4717 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4718 GetPixelChannelOffset(image,channel)];
4719 }
4720 delta.x=x-x_offset;
4721 delta.y=y-y_offset;
4722 luminance.x=GetPixelLuma(image,p)-(double)
4723 GetPixelLuma(image,p+3*GetPixelChannels(image));
4724 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
4725 GetPixelLuma(image,p+2*GetPixelChannels(image));
4726 if (fabs((double) luminance.x) < fabs((double) luminance.y))
4727 {
4728 /*
4729 Diagonal 0-3 NW-SE.
4730 */
4731 if (delta.x <= delta.y)
4732 {
4733 /*
4734 Bottom-left triangle (pixel: 2, diagonal: 0-3).
4735 */
4736 delta.y=1.0-delta.y;
4737 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4738 gamma=MagickSafeReciprocal(gamma);
4739 *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4740 pixels[0]);
4741 }
4742 else
4743 {
4744 /*
4745 Top-right triangle (pixel: 1, diagonal: 0-3).
4746 */
4747 delta.x=1.0-delta.x;
4748 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4749 gamma=MagickSafeReciprocal(gamma);
4750 *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4751 pixels[3]);
4752 }
4753 }
4754 else
4755 {
4756 /*
4757 Diagonal 1-2 NE-SW.
4758 */
4759 if (delta.x <= (1.0-delta.y))
4760 {
4761 /*
4762 Top-left triangle (pixel: 0, diagonal: 1-2).
4763 */
4764 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4765 gamma=MagickSafeReciprocal(gamma);
4766 *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4767 pixels[2]);
4768 }
4769 else
4770 {
4771 /*
4772 Bottom-right triangle (pixel: 3, diagonal: 1-2).
4773 */
4774 delta.x=1.0-delta.x;
4775 delta.y=1.0-delta.y;
4776 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4777 gamma=MagickSafeReciprocal(gamma);
4778 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4779 pixels[1]);
4780 }
4781 }
4782 break;
4783 }
4784 case SplineInterpolatePixel:
4785 {
4786 double
4787 cx[4],
4788 cy[4];
4789
4790 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4791 exception);
4792 if (p == (const Quantum *) NULL)
4793 {
4794 status=MagickFalse;
4795 break;
4796 }
4797 if ((traits & BlendPixelTrait) == 0)
4798 for (i=0; i < 16; i++)
4799 {
4800 alpha[i]=1.0;
4801 pixels[i]=(double) p[i*(ssize_t) GetPixelChannels(image)+
4802 GetPixelChannelOffset(image,channel)];
4803 }
4804 else
4805 for (i=0; i < 16; i++)
4806 {
4807 alpha[i]=QuantumScale*(double) GetPixelAlpha(image,p+i*
4808 (ssize_t) GetPixelChannels(image));
4809 pixels[i]=alpha[i]*(double) p[i*(ssize_t) GetPixelChannels(image)+
4810 GetPixelChannelOffset(image,channel)];
4811 }
4812 SplineWeights((double) (x-x_offset),&cx);
4813 SplineWeights((double) (y-y_offset),&cy);
4814 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4815 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4816 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4817 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4818 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4819 cx[2]*alpha[14]+cx[3]*alpha[15])));
4820 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4821 cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4822 pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4823 cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4824 pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4825 break;
4826 }
4827 }
4828 return(status);
4829}
4830␌
4831/*
4832%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4833% %
4834% %
4835% %
4836% I n t e r p o l a t e P i x e l C h a n n e l s %
4837% %
4838% %
4839% %
4840%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4841%
4842% InterpolatePixelChannels() applies a pixel interpolation method between a
4843% floating point coordinate and the pixels surrounding that coordinate. No
4844% pixel area resampling, or scaling of the result is performed.
4845%
4846% Interpolation is restricted to just the current channel setting of the
4847% destination image into which the color is to be stored
4848%
4849% The format of the InterpolatePixelChannels method is:
4850%
4851% MagickBooleanType InterpolatePixelChannels(
4852% const Image *magick_restrict source,const CacheView *source_view,
4853% const Image *magick_restrict destination,
4854% const PixelInterpolateMethod method,const double x,const double y,
4855% Quantum *pixel,ExceptionInfo *exception)
4856%
4857% A description of each parameter follows:
4858%
4859% o source: the source.
4860%
4861% o source_view: the source view.
4862%
4863% o destination: the destination image, for the interpolated color
4864%
4865% o method: the pixel color interpolation method.
4866%
4867% o x,y: A double representing the current (x,y) position of the pixel.
4868%
4869% o pixel: return the interpolated pixel here.
4870%
4871% o exception: return any errors or warnings in this structure.
4872%
4873*/
4874MagickExport MagickBooleanType InterpolatePixelChannels(
4875 const Image *magick_restrict source,const CacheView_ *source_view,
4876 const Image *magick_restrict destination,const PixelInterpolateMethod method,
4877 const double x,const double y,Quantum *pixel,ExceptionInfo *exception)
4878{
4879 MagickBooleanType
4880 status;
4881
4882 double
4883 alpha[16],
4884 gamma,
4885 pixels[16];
4886
4887 const Quantum
4888 *magick_restrict p;
4889
4890 ssize_t
4891 i;
4892
4893 ssize_t
4894 x_offset,
4895 y_offset;
4896
4897 PixelInterpolateMethod
4898 interpolate;
4899
4900 assert(source != (Image *) NULL);
4901 assert(source->signature == MagickCoreSignature);
4902 assert(source_view != (CacheView *) NULL);
4903 status=MagickTrue;
4904 x_offset=CastDoubleToSsizeT(floor(x));
4905 y_offset=CastDoubleToSsizeT(floor(y));
4906 interpolate=method;
4907 if (interpolate == UndefinedInterpolatePixel)
4908 interpolate=source->interpolate;
4909 switch (interpolate)
4910 {
4911 case AverageInterpolatePixel: /* nearest 4 neighbours */
4912 case Average9InterpolatePixel: /* nearest 9 neighbours */
4913 case Average16InterpolatePixel: /* nearest 16 neighbours */
4914 {
4915 ssize_t
4916 count;
4917
4918 count=2; /* size of the area to average - default nearest 4 */
4919 if (interpolate == Average9InterpolatePixel)
4920 {
4921 count=3;
4922 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
4923 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
4924 }
4925 else
4926 if (interpolate == Average16InterpolatePixel)
4927 {
4928 count=4;
4929 x_offset--;
4930 y_offset--;
4931 }
4932 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count,
4933 (size_t) count,exception);
4934 if (p == (const Quantum *) NULL)
4935 {
4936 status=MagickFalse;
4937 break;
4938 }
4939 count*=count; /* Number of pixels to average */
4940 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4941 {
4942 double
4943 sum;
4944
4945 ssize_t
4946 j;
4947
4948 PixelChannel channel = GetPixelChannelChannel(source,i);
4949 PixelTrait traits = GetPixelChannelTraits(source,channel);
4950 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4951 channel);
4952 if ((traits == UndefinedPixelTrait) ||
4953 (destination_traits == UndefinedPixelTrait))
4954 continue;
4955 for (j=0; j < (ssize_t) count; j++)
4956 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
4957 sum=0.0;
4958 if ((traits & BlendPixelTrait) == 0)
4959 {
4960 for (j=0; j < (ssize_t) count; j++)
4961 sum+=pixels[j];
4962 sum/=count;
4963 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4964 continue;
4965 }
4966 for (j=0; j < (ssize_t) count; j++)
4967 {
4968 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
4969 (ssize_t) GetPixelChannels(source));
4970 pixels[j]*=alpha[j];
4971 gamma=MagickSafeReciprocal(alpha[j]);
4972 sum+=gamma*pixels[j];
4973 }
4974 sum/=count;
4975 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4976 }
4977 break;
4978 }
4979 case BilinearInterpolatePixel:
4980 default:
4981 {
4982 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
4983 if (p == (const Quantum *) NULL)
4984 {
4985 status=MagickFalse;
4986 break;
4987 }
4988 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4989 {
4990 PointInfo
4991 delta,
4992 epsilon;
4993
4994 PixelChannel channel = GetPixelChannelChannel(source,i);
4995 PixelTrait traits = GetPixelChannelTraits(source,channel);
4996 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4997 channel);
4998 if ((traits == UndefinedPixelTrait) ||
4999 (destination_traits == UndefinedPixelTrait))
5000 continue;
5001 delta.x=x-x_offset;
5002 delta.y=y-y_offset;
5003 epsilon.x=1.0-delta.x;
5004 epsilon.y=1.0-delta.y;
5005 pixels[0]=(double) p[i];
5006 pixels[1]=(double) p[(ssize_t) GetPixelChannels(source)+i];
5007 pixels[2]=(double) p[2*(ssize_t) GetPixelChannels(source)+i];
5008 pixels[3]=(double) p[3*(ssize_t) GetPixelChannels(source)+i];
5009 if ((traits & BlendPixelTrait) == 0)
5010 {
5011 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5012 gamma=MagickSafeReciprocal(gamma);
5013 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5014 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
5015 pixels[2]+delta.x*pixels[3]))),pixel);
5016 continue;
5017 }
5018 alpha[0]=QuantumScale*(double) GetPixelAlpha(source,p);
5019 alpha[1]=QuantumScale*(double) GetPixelAlpha(source,p+
5020 GetPixelChannels(source));
5021 alpha[2]=QuantumScale*(double) GetPixelAlpha(source,p+2*
5022 GetPixelChannels(source));
5023 alpha[3]=QuantumScale*(double) GetPixelAlpha(source,p+3*
5024 GetPixelChannels(source));
5025 pixels[0]*=alpha[0];
5026 pixels[1]*=alpha[1];
5027 pixels[2]*=alpha[2];
5028 pixels[3]*=alpha[3];
5029 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5030 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5031 gamma=MagickSafeReciprocal(gamma);
5032 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5033 (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
5034 delta.x*pixels[3]))),pixel);
5035 }
5036 break;
5037 }
5038 case BlendInterpolatePixel:
5039 {
5040 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5041 if (p == (const Quantum *) NULL)
5042 {
5043 status=MagickFalse;
5044 break;
5045 }
5046 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5047 {
5048 ssize_t
5049 j;
5050
5051 PixelChannel channel = GetPixelChannelChannel(source,i);
5052 PixelTrait traits = GetPixelChannelTraits(source,channel);
5053 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5054 channel);
5055 if ((traits == UndefinedPixelTrait) ||
5056 (destination_traits == UndefinedPixelTrait))
5057 continue;
5058 if (source->alpha_trait != BlendPixelTrait)
5059 for (j=0; j < 4; j++)
5060 {
5061 alpha[j]=1.0;
5062 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5063 }
5064 else
5065 for (j=0; j < 4; j++)
5066 {
5067 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5068 (ssize_t) GetPixelChannels(source));
5069 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5070 if (channel != AlphaPixelChannel)
5071 pixels[j]*=alpha[j];
5072 }
5073 gamma=1.0; /* number of pixels blended together (its variable) */
5074 for (j=0; j <= 1L; j++)
5075 {
5076 if ((y-y_offset) >= 0.75)
5077 {
5078 alpha[j]=alpha[j+2]; /* take right pixels */
5079 pixels[j]=pixels[j+2];
5080 }
5081 else
5082 if ((y-y_offset) > 0.25)
5083 {
5084 gamma=2.0; /* blend both pixels in row */
5085 alpha[j]+=alpha[j+2]; /* add up alpha weights */
5086 pixels[j]+=pixels[j+2];
5087 }
5088 }
5089 if ((x-x_offset) >= 0.75)
5090 {
5091 alpha[0]=alpha[1]; /* take bottom row blend */
5092 pixels[0]=pixels[1];
5093 }
5094 else
5095 if ((x-x_offset) > 0.25)
5096 {
5097 gamma*=2.0; /* blend both rows */
5098 alpha[0]+=alpha[1]; /* add up alpha weights */
5099 pixels[0]+=pixels[1];
5100 }
5101 if (channel != AlphaPixelChannel)
5102 gamma=MagickSafeReciprocal(alpha[0]); /* (color) 1/alpha_weights */
5103 else
5104 gamma=MagickSafeReciprocal(gamma); /* (alpha) 1/number_of_pixels */
5105 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
5106 pixel);
5107 }
5108 break;
5109 }
5110 case CatromInterpolatePixel:
5111 {
5112 double
5113 cx[4],
5114 cy[4];
5115
5116 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5117 exception);
5118 if (p == (const Quantum *) NULL)
5119 {
5120 status=MagickFalse;
5121 break;
5122 }
5123 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5124 {
5125 ssize_t
5126 j;
5127
5128 PixelChannel channel = GetPixelChannelChannel(source,i);
5129 PixelTrait traits = GetPixelChannelTraits(source,channel);
5130 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5131 channel);
5132 if ((traits == UndefinedPixelTrait) ||
5133 (destination_traits == UndefinedPixelTrait))
5134 continue;
5135 if ((traits & BlendPixelTrait) == 0)
5136 for (j=0; j < 16; j++)
5137 {
5138 alpha[j]=1.0;
5139 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5140 }
5141 else
5142 for (j=0; j < 16; j++)
5143 {
5144 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5145 (ssize_t) GetPixelChannels(source));
5146 pixels[j]=alpha[j]*(double)
5147 p[j*(ssize_t) GetPixelChannels(source)+i];
5148 }
5149 CatromWeights((double) (x-x_offset),&cx);
5150 CatromWeights((double) (y-y_offset),&cy);
5151 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5152 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5153 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5154 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5155 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5156 cx[2]*alpha[14]+cx[3]*alpha[15])));
5157 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5158 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5159 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5160 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5161 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5162 pixels[14]+cx[3]*pixels[15]))),pixel);
5163 }
5164 break;
5165 }
5166 case IntegerInterpolatePixel:
5167 {
5168 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5169 if (p == (const Quantum *) NULL)
5170 {
5171 status=MagickFalse;
5172 break;
5173 }
5174 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5175 {
5176 PixelChannel channel = GetPixelChannelChannel(source,i);
5177 PixelTrait traits = GetPixelChannelTraits(source,channel);
5178 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5179 channel);
5180 if ((traits == UndefinedPixelTrait) ||
5181 (destination_traits == UndefinedPixelTrait))
5182 continue;
5183 SetPixelChannel(destination,channel,p[i],pixel);
5184 }
5185 break;
5186 }
5187 case NearestInterpolatePixel:
5188 {
5189 x_offset=CastDoubleToSsizeT(floor(x+0.5));
5190 y_offset=CastDoubleToSsizeT(floor(y+0.5));
5191 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5192 if (p == (const Quantum *) NULL)
5193 {
5194 status=MagickFalse;
5195 break;
5196 }
5197 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5198 {
5199 PixelChannel channel = GetPixelChannelChannel(source,i);
5200 PixelTrait traits = GetPixelChannelTraits(source,channel);
5201 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5202 channel);
5203 if ((traits == UndefinedPixelTrait) ||
5204 (destination_traits == UndefinedPixelTrait))
5205 continue;
5206 SetPixelChannel(destination,channel,p[i],pixel);
5207 }
5208 break;
5209 }
5210 case MeshInterpolatePixel:
5211 {
5212 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5213 if (p == (const Quantum *) NULL)
5214 {
5215 status=MagickFalse;
5216 break;
5217 }
5218 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5219 {
5220 PointInfo
5221 delta,
5222 luminance;
5223
5224 PixelChannel channel = GetPixelChannelChannel(source,i);
5225 PixelTrait traits = GetPixelChannelTraits(source,channel);
5226 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5227 channel);
5228 if ((traits == UndefinedPixelTrait) ||
5229 (destination_traits == UndefinedPixelTrait))
5230 continue;
5231 pixels[0]=(double) p[i];
5232 pixels[1]=(double) p[(ssize_t) GetPixelChannels(source)+i];
5233 pixels[2]=(double) p[2*(ssize_t) GetPixelChannels(source)+i];
5234 pixels[3]=(double) p[3*(ssize_t) GetPixelChannels(source)+i];
5235 if ((traits & BlendPixelTrait) == 0)
5236 {
5237 alpha[0]=1.0;
5238 alpha[1]=1.0;
5239 alpha[2]=1.0;
5240 alpha[3]=1.0;
5241 }
5242 else
5243 {
5244 alpha[0]=QuantumScale*(double) GetPixelAlpha(source,p);
5245 alpha[1]=QuantumScale*(double) GetPixelAlpha(source,p+
5246 GetPixelChannels(source));
5247 alpha[2]=QuantumScale*(double) GetPixelAlpha(source,p+2*
5248 GetPixelChannels(source));
5249 alpha[3]=QuantumScale*(double) GetPixelAlpha(source,p+3*
5250 GetPixelChannels(source));
5251 }
5252 delta.x=x-x_offset;
5253 delta.y=y-y_offset;
5254 luminance.x=fabs((double) (GetPixelLuma(source,p)-
5255 GetPixelLuma(source,p+3*GetPixelChannels(source))));
5256 luminance.y=fabs((double) (GetPixelLuma(source,p+
5257 GetPixelChannels(source))-GetPixelLuma(source,p+2*
5258 GetPixelChannels(source))));
5259 if (luminance.x < luminance.y)
5260 {
5261 /*
5262 Diagonal 0-3 NW-SE.
5263 */
5264 if (delta.x <= delta.y)
5265 {
5266 /*
5267 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5268 */
5269 delta.y=1.0-delta.y;
5270 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5271 gamma=MagickSafeReciprocal(gamma);
5272 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5273 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
5274 }
5275 else
5276 {
5277 /*
5278 Top-right triangle (pixel: 1, diagonal: 0-3).
5279 */
5280 delta.x=1.0-delta.x;
5281 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5282 gamma=MagickSafeReciprocal(gamma);
5283 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5284 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
5285 }
5286 }
5287 else
5288 {
5289 /*
5290 Diagonal 1-2 NE-SW.
5291 */
5292 if (delta.x <= (1.0-delta.y))
5293 {
5294 /*
5295 Top-left triangle (pixel: 0, diagonal: 1-2).
5296 */
5297 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5298 gamma=MagickSafeReciprocal(gamma);
5299 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5300 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
5301 }
5302 else
5303 {
5304 /*
5305 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5306 */
5307 delta.x=1.0-delta.x;
5308 delta.y=1.0-delta.y;
5309 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5310 gamma=MagickSafeReciprocal(gamma);
5311 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5312 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
5313 }
5314 }
5315 }
5316 break;
5317 }
5318 case SplineInterpolatePixel:
5319 {
5320 double
5321 cx[4],
5322 cy[4];
5323
5324 p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5325 exception);
5326 if (p == (const Quantum *) NULL)
5327 {
5328 status=MagickFalse;
5329 break;
5330 }
5331 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5332 {
5333 ssize_t
5334 j;
5335
5336 PixelChannel channel = GetPixelChannelChannel(source,i);
5337 PixelTrait traits = GetPixelChannelTraits(source,channel);
5338 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5339 channel);
5340 if ((traits == UndefinedPixelTrait) ||
5341 (destination_traits == UndefinedPixelTrait))
5342 continue;
5343 if ((traits & BlendPixelTrait) == 0)
5344 for (j=0; j < 16; j++)
5345 {
5346 alpha[j]=1.0;
5347 pixels[j]=(double) p[j*(ssize_t) GetPixelChannels(source)+i];
5348 }
5349 else
5350 for (j=0; j < 16; j++)
5351 {
5352 alpha[j]=QuantumScale*(double) GetPixelAlpha(source,p+j*
5353 (ssize_t) GetPixelChannels(source));
5354 pixels[j]=alpha[j]*(double) p[j*(ssize_t) GetPixelChannels(source)+
5355 i];
5356 }
5357 SplineWeights((double) (x-x_offset),&cx);
5358 SplineWeights((double) (y-y_offset),&cy);
5359 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5360 MagickSafeReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5361 alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5362 alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5363 alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5364 cx[2]*alpha[14]+cx[3]*alpha[15])));
5365 SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5366 pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5367 (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5368 cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5369 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5370 pixels[14]+cx[3]*pixels[15]))),pixel);
5371 }
5372 break;
5373 }
5374 }
5375 return(status);
5376}
5377␌
5378/*
5379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5380% %
5381% %
5382% %
5383% I n t e r p o l a t e P i x e l I n f o %
5384% %
5385% %
5386% %
5387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5388%
5389% InterpolatePixelInfo() applies a pixel interpolation method between a
5390% floating point coordinate and the pixels surrounding that coordinate. No
5391% pixel area resampling, or scaling of the result is performed.
5392%
5393% Interpolation is restricted to just RGBKA channels.
5394%
5395% The format of the InterpolatePixelInfo method is:
5396%
5397% MagickBooleanType InterpolatePixelInfo(const Image *image,
5398% const CacheView *image_view,const PixelInterpolateMethod method,
5399% const double x,const double y,PixelInfo *pixel,
5400% ExceptionInfo *exception)
5401%
5402% A description of each parameter follows:
5403%
5404% o image: the image.
5405%
5406% o image_view: the image view.
5407%
5408% o method: the pixel color interpolation method.
5409%
5410% o x,y: A double representing the current (x,y) position of the pixel.
5411%
5412% o pixel: return the interpolated pixel here.
5413%
5414% o exception: return any errors or warnings in this structure.
5415%
5416*/
5417
5418static inline void AlphaBlendPixelInfo(const Image *image,
5419 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
5420{
5421 if ((image->alpha_trait & BlendPixelTrait) == 0)
5422 {
5423 *alpha=1.0;
5424 pixel_info->red=(double) GetPixelRed(image,pixel);
5425 pixel_info->green=(double) GetPixelGreen(image,pixel);
5426 pixel_info->blue=(double) GetPixelBlue(image,pixel);
5427 pixel_info->black=0.0;
5428 if (image->colorspace == CMYKColorspace)
5429 pixel_info->black=(double) GetPixelBlack(image,pixel);
5430 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5431 return;
5432 }
5433 *alpha=QuantumScale*(double) GetPixelAlpha(image,pixel);
5434 pixel_info->red=(*alpha*(double) GetPixelRed(image,pixel));
5435 pixel_info->green=(*alpha*(double) GetPixelGreen(image,pixel));
5436 pixel_info->blue=(*alpha*(double) GetPixelBlue(image,pixel));
5437 pixel_info->black=0.0;
5438 if (image->colorspace == CMYKColorspace)
5439 pixel_info->black=(*alpha*(double) GetPixelBlack(image,pixel));
5440 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5441}
5442
5443MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
5444 const CacheView_ *image_view,const PixelInterpolateMethod method,
5445 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5446{
5447 const Quantum
5448 *p;
5449
5450 double
5451 alpha[16],
5452 gamma;
5453
5454 MagickBooleanType
5455 status;
5456
5457 PixelInfo
5458 pixels[16];
5459
5460 PixelInterpolateMethod
5461 interpolate;
5462
5463 ssize_t
5464 i,
5465 x_offset,
5466 y_offset;
5467
5468 assert(image != (Image *) NULL);
5469 assert(image->signature == MagickCoreSignature);
5470 assert(image_view != (CacheView *) NULL);
5471 status=MagickTrue;
5472 x_offset=CastDoubleToSsizeT(floor(x));
5473 y_offset=CastDoubleToSsizeT(floor(y));
5474 interpolate=method;
5475 if (interpolate == UndefinedInterpolatePixel)
5476 interpolate=image->interpolate;
5477 GetPixelInfoPixel(image,(const Quantum *) NULL,pixel);
5478 (void) memset(&pixels,0,sizeof(pixels));
5479 switch (interpolate)
5480 {
5481 case AverageInterpolatePixel: /* nearest 4 neighbours */
5482 case Average9InterpolatePixel: /* nearest 9 neighbours */
5483 case Average16InterpolatePixel: /* nearest 16 neighbours */
5484 {
5485 ssize_t
5486 count;
5487
5488 count=2; /* size of the area to average - default nearest 4 */
5489 if (interpolate == Average9InterpolatePixel)
5490 {
5491 count=3;
5492 x_offset=CastDoubleToSsizeT(floor(x+0.5)-1.0);
5493 y_offset=CastDoubleToSsizeT(floor(y+0.5)-1.0);
5494 }
5495 else
5496 if (interpolate == Average16InterpolatePixel)
5497 {
5498 count=4;
5499 x_offset--;
5500 y_offset--;
5501 }
5502 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
5503 (size_t) count,exception);
5504 if (p == (const Quantum *) NULL)
5505 {
5506 status=MagickFalse;
5507 break;
5508 }
5509 pixel->red=0.0;
5510 pixel->green=0.0;
5511 pixel->blue=0.0;
5512 pixel->black=0.0;
5513 pixel->alpha=0.0;
5514 count*=count; /* number of pixels - square of size */
5515 for (i=0; i < (ssize_t) count; i++)
5516 {
5517 AlphaBlendPixelInfo(image,p,pixels,alpha);
5518 gamma=MagickSafeReciprocal(alpha[0]);
5519 pixel->red+=gamma*pixels[0].red;
5520 pixel->green+=gamma*pixels[0].green;
5521 pixel->blue+=gamma*pixels[0].blue;
5522 pixel->black+=gamma*pixels[0].black;
5523 pixel->alpha+=pixels[0].alpha;
5524 p+=(ptrdiff_t) GetPixelChannels(image);
5525 }
5526 gamma=1.0/count; /* average weighting of each pixel in area */
5527 pixel->red*=gamma;
5528 pixel->green*=gamma;
5529 pixel->blue*=gamma;
5530 pixel->black*=gamma;
5531 pixel->alpha*=gamma;
5532 break;
5533 }
5534 case BackgroundInterpolatePixel:
5535 {
5536 *pixel=image->background_color; /* Copy PixelInfo Structure */
5537 break;
5538 }
5539 case BilinearInterpolatePixel:
5540 default:
5541 {
5542 PointInfo
5543 delta,
5544 epsilon;
5545
5546 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5547 if (p == (const Quantum *) NULL)
5548 {
5549 status=MagickFalse;
5550 break;
5551 }
5552 for (i=0; i < 4L; i++)
5553 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5554 pixels+i,alpha+i);
5555 delta.x=x-x_offset;
5556 delta.y=y-y_offset;
5557 epsilon.x=1.0-delta.x;
5558 epsilon.y=1.0-delta.y;
5559 gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5560 (epsilon.x*alpha[2]+delta.x*alpha[3])));
5561 gamma=MagickSafeReciprocal(gamma);
5562 pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5563 pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5564 pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5565 pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5566 pixels[3].green));
5567 pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5568 pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5569 pixels[3].blue));
5570 if (image->colorspace == CMYKColorspace)
5571 pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5572 pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5573 pixels[3].black));
5574 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5575 gamma=MagickSafeReciprocal(gamma);
5576 pixel->alpha=gamma*(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5577 pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5578 pixels[3].alpha));
5579 break;
5580 }
5581 case BlendInterpolatePixel:
5582 {
5583 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5584 if (p == (const Quantum *) NULL)
5585 {
5586 status=MagickFalse;
5587 break;
5588 }
5589 for (i=0; i < 4L; i++)
5590 {
5591 GetPixelInfoPixel(image,p+i*(ssize_t) GetPixelChannels(image),pixels+i);
5592 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5593 pixels+i,alpha+i);
5594 }
5595 gamma=1.0; /* number of pixels blended together (its variable) */
5596 for (i=0; i <= 1L; i++)
5597 {
5598 if ((y-y_offset) >= 0.75)
5599 {
5600 alpha[i]=alpha[i+2]; /* take right pixels */
5601 pixels[i]=pixels[i+2];
5602 }
5603 else
5604 if ((y-y_offset) > 0.25)
5605 {
5606 gamma=2.0; /* blend both pixels in row */
5607 alpha[i]+=alpha[i+2]; /* add up alpha weights */
5608 pixels[i].red+=pixels[i+2].red;
5609 pixels[i].green+=pixels[i+2].green;
5610 pixels[i].blue+=pixels[i+2].blue;
5611 pixels[i].black+=pixels[i+2].black;
5612 pixels[i].alpha+=pixels[i+2].alpha;
5613 }
5614 }
5615 if ((x-x_offset) >= 0.75)
5616 {
5617 alpha[0]=alpha[1];
5618 pixels[0]=pixels[1];
5619 }
5620 else
5621 if ((x-x_offset) > 0.25)
5622 {
5623 gamma*=2.0; /* blend both rows */
5624 alpha[0]+= alpha[1]; /* add up alpha weights */
5625 pixels[0].red+=pixels[1].red;
5626 pixels[0].green+=pixels[1].green;
5627 pixels[0].blue+=pixels[1].blue;
5628 pixels[0].black+=pixels[1].black;
5629 pixels[0].alpha+=pixels[1].alpha;
5630 }
5631 gamma=1.0/gamma;
5632 alpha[0]=MagickSafeReciprocal(alpha[0]);
5633 pixel->red=alpha[0]*pixels[0].red;
5634 pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5635 pixel->blue=alpha[0]*pixels[0].blue;
5636 pixel->black=alpha[0]*pixels[0].black;
5637 pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
5638 break;
5639 }
5640 case CatromInterpolatePixel:
5641 {
5642 double
5643 cx[4],
5644 cy[4];
5645
5646 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5647 exception);
5648 if (p == (const Quantum *) NULL)
5649 {
5650 status=MagickFalse;
5651 break;
5652 }
5653 for (i=0; i < 16L; i++)
5654 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5655 pixels+i,alpha+i);
5656 CatromWeights((double) (x-x_offset),&cx);
5657 CatromWeights((double) (y-y_offset),&cy);
5658 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5659 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5660 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5661 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5662 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5663 pixels[14].red+cx[3]*pixels[15].red));
5664 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5665 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5666 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5667 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5668 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5669 pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5670 pixels[15].green));
5671 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5672 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5673 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5674 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5675 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5676 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5677 if (image->colorspace == CMYKColorspace)
5678 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5679 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5680 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5681 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5682 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5683 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5684 pixels[15].black));
5685 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5686 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5687 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5688 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5689 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5690 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5691 break;
5692 }
5693 case IntegerInterpolatePixel:
5694 {
5695 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5696 if (p == (const Quantum *) NULL)
5697 {
5698 status=MagickFalse;
5699 break;
5700 }
5701 GetPixelInfoPixel(image,p,pixel);
5702 break;
5703 }
5704 case MeshInterpolatePixel:
5705 {
5706 PointInfo
5707 delta,
5708 luminance;
5709
5710 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5711 if (p == (const Quantum *) NULL)
5712 {
5713 status=MagickFalse;
5714 break;
5715 }
5716 delta.x=x-x_offset;
5717 delta.y=y-y_offset;
5718 luminance.x=GetPixelLuma(image,p)-(double)
5719 GetPixelLuma(image,p+3*GetPixelChannels(image));
5720 luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
5721 GetPixelLuma(image,p+2*GetPixelChannels(image));
5722 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5723 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5724 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5725 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5726 if (fabs((double) luminance.x) < fabs((double) luminance.y))
5727 {
5728 /*
5729 Diagonal 0-3 NW-SE.
5730 */
5731 if (delta.x <= delta.y)
5732 {
5733 /*
5734 Bottom-left triangle (pixel: 2, diagonal: 0-3).
5735 */
5736 delta.y=1.0-delta.y;
5737 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5738 gamma=MagickSafeReciprocal(gamma);
5739 pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5740 pixels[3].red,pixels[0].red);
5741 pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5742 pixels[3].green,pixels[0].green);
5743 pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5744 pixels[3].blue,pixels[0].blue);
5745 if (image->colorspace == CMYKColorspace)
5746 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5747 pixels[3].black,pixels[0].black);
5748 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5749 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5750 pixels[3].alpha,pixels[0].alpha);
5751 }
5752 else
5753 {
5754 /*
5755 Top-right triangle (pixel:1 , diagonal: 0-3).
5756 */
5757 delta.x=1.0-delta.x;
5758 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5759 gamma=MagickSafeReciprocal(gamma);
5760 pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5761 pixels[0].red,pixels[3].red);
5762 pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5763 pixels[0].green,pixels[3].green);
5764 pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5765 pixels[0].blue,pixels[3].blue);
5766 if (image->colorspace == CMYKColorspace)
5767 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5768 pixels[0].black,pixels[3].black);
5769 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5770 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5771 pixels[0].alpha,pixels[3].alpha);
5772 }
5773 }
5774 else
5775 {
5776 /*
5777 Diagonal 1-2 NE-SW.
5778 */
5779 if (delta.x <= (1.0-delta.y))
5780 {
5781 /*
5782 Top-left triangle (pixel: 0, diagonal: 1-2).
5783 */
5784 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5785 gamma=MagickSafeReciprocal(gamma);
5786 pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5787 pixels[1].red,pixels[2].red);
5788 pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5789 pixels[1].green,pixels[2].green);
5790 pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5791 pixels[1].blue,pixels[2].blue);
5792 if (image->colorspace == CMYKColorspace)
5793 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5794 pixels[1].black,pixels[2].black);
5795 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5796 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5797 pixels[1].alpha,pixels[2].alpha);
5798 }
5799 else
5800 {
5801 /*
5802 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5803 */
5804 delta.x=1.0-delta.x;
5805 delta.y=1.0-delta.y;
5806 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5807 gamma=MagickSafeReciprocal(gamma);
5808 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5809 pixels[2].red,pixels[1].red);
5810 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5811 pixels[2].green,pixels[1].green);
5812 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5813 pixels[2].blue,pixels[1].blue);
5814 if (image->colorspace == CMYKColorspace)
5815 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5816 pixels[2].black,pixels[1].black);
5817 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5818 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5819 pixels[2].alpha,pixels[1].alpha);
5820 }
5821 }
5822 break;
5823 }
5824 case NearestInterpolatePixel:
5825 {
5826 x_offset=CastDoubleToSsizeT(floor(x+0.5));
5827 y_offset=CastDoubleToSsizeT(floor(y+0.5));
5828 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5829 if (p == (const Quantum *) NULL)
5830 {
5831 status=MagickFalse;
5832 break;
5833 }
5834 GetPixelInfoPixel(image,p,pixel);
5835 break;
5836 }
5837 case SplineInterpolatePixel:
5838 {
5839 double
5840 cx[4],
5841 cy[4];
5842
5843 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5844 exception);
5845 if (p == (const Quantum *) NULL)
5846 {
5847 status=MagickFalse;
5848 break;
5849 }
5850 for (i=0; i < 16L; i++)
5851 AlphaBlendPixelInfo(image,p+i*(ssize_t) GetPixelChannels(image),
5852 pixels+i,alpha+i);
5853 SplineWeights((double) (x-x_offset),&cx);
5854 SplineWeights((double) (y-y_offset),&cy);
5855 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5856 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5857 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5858 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5859 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5860 pixels[14].red+cx[3]*pixels[15].red));
5861 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5862 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5863 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5864 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5865 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5866 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5867 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5868 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5869 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5870 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5871 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5872 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5873 if (image->colorspace == CMYKColorspace)
5874 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5875 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5876 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5877 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5878 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5879 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5880 pixels[15].black));
5881 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5882 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5883 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5884 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5885 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5886 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5887 break;
5888 }
5889 }
5890 return(status);
5891}
5892␌
5893/*
5894%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5895% %
5896% %
5897% %
5898+ I s F u z z y E q u i v a l e n c e P i x e l %
5899% %
5900% %
5901% %
5902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5903%
5904% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
5905% pixels is less than the specified distance in a linear three (or four)
5906% dimensional color space.
5907%
5908% The format of the IsFuzzyEquivalencePixel method is:
5909%
5910% void IsFuzzyEquivalencePixel(const Image *image,const Quantum *p,
5911% const Image *target_image,const Quantum *q)
5912%
5913% A description of each parameter follows:
5914%
5915% o image: the source image.
5916%
5917% o p: Pixel p.
5918%
5919% o target: the target image.
5920%
5921% o q: Pixel q.
5922%
5923*/
5924MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *image,
5925 const Quantum *p,const Image *target_image,const Quantum *q)
5926{
5927 double
5928 alpha = QuantumScale*(double) GetPixelAlpha(image,p),
5929 fuzz = GetFuzzyColorDistance(image,target_image),
5930 target_alpha = QuantumScale*(double) GetPixelAlpha(target_image,q);
5931
5932 ssize_t
5933 i;
5934
5935 /*
5936 MSE metric for comparing two pixels.
5937 */
5938 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
5939 {
5940 double
5941 error;
5942
5943 PixelChannel channel = GetPixelChannelChannel(image,i);
5944 PixelTrait traits = GetPixelChannelTraits(image,channel);
5945 PixelTrait target_traits = GetPixelChannelTraits(target_image,channel);
5946 if (((traits & UpdatePixelTrait) == 0) ||
5947 ((target_traits & UpdatePixelTrait) == 0))
5948 continue;
5949 if (channel == AlphaPixelChannel)
5950 error=(double) p[i]-(double) GetPixelChannel(target_image,channel,q);
5951 else
5952 error=alpha*(double) p[i]-target_alpha*
5953 GetPixelChannel(target_image,channel,q);
5954 if (MagickSafeSignificantError(error*error,fuzz) != MagickFalse)
5955 return(MagickFalse);
5956 }
5957 return(MagickTrue);
5958}
5959␌
5960/*
5961%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5962% %
5963% %
5964% %
5965+ 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 %
5966% %
5967% %
5968% %
5969%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5970%
5971% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
5972% colors is less than the specified distance in a linear three (or four)
5973% dimensional color space.
5974%
5975% This implements the equivalent of:
5976% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
5977%
5978% Which produces a multi-dimensional cone for that colorspace along the
5979% transparency vector.
5980%
5981% For example for an RGB:
5982% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
5983%
5984% See https://imagemagick.org/Usage/bugs/fuzz_distance/
5985%
5986% Hue colorspace distances need more work. Hue is not a distance, it is an
5987% angle!
5988%
5989% A check that q is in the same color space as p should be made and the
5990% appropriate mapping made. -- Anthony Thyssen 8 December 2010
5991%
5992% The format of the IsFuzzyEquivalencePixelInfo method is:
5993%
5994% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
5995% const PixelInfo *q)
5996%
5997% A description of each parameter follows:
5998%
5999% o p: Pixel p.
6000%
6001% o q: Pixel q.
6002%
6003*/
6004MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6005 const PixelInfo *q)
6006{
6007 double
6008 distance,
6009 fuzz,
6010 pixel,
6011 scale;
6012
6013 fuzz=p->fuzz*p->fuzz+q->fuzz*q->fuzz;
6014 scale=1.0;
6015 distance=0.0;
6016 if ((p->alpha_trait != UndefinedPixelTrait) ||
6017 (q->alpha_trait != UndefinedPixelTrait))
6018 {
6019 /*
6020 Transparencies are involved - set alpha distance.
6021 */
6022 pixel=(p->alpha_trait != UndefinedPixelTrait ? p->alpha :
6023 (double) OpaqueAlpha)-(q->alpha_trait != UndefinedPixelTrait ?
6024 q->alpha : (double) OpaqueAlpha);
6025 distance=pixel*pixel;
6026 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6027 return(MagickFalse);
6028 /*
6029 Generate a alpha scaling factor to generate a 4D cone on colorspace.
6030 If one color is transparent, distance has no color component.
6031 */
6032 if (p->alpha_trait != UndefinedPixelTrait)
6033 scale=(QuantumScale*p->alpha);
6034 if (q->alpha_trait != UndefinedPixelTrait)
6035 scale*=(QuantumScale*q->alpha);
6036 if (scale <= MagickEpsilon)
6037 return(MagickTrue);
6038 }
6039 /*
6040 CMYK create a CMY cube with a multi-dimensional cone toward black.
6041 */
6042 if (p->colorspace == CMYKColorspace)
6043 {
6044 pixel=p->black-q->black;
6045 distance+=pixel*pixel*scale;
6046 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6047 return(MagickFalse);
6048 scale*=QuantumScale*((double) QuantumRange-(double) p->black);
6049 scale*=QuantumScale*((double) QuantumRange-(double) q->black);
6050 }
6051 /*
6052 RGB or CMY color cube.
6053 */
6054 distance*=3.0; /* rescale appropriately */
6055 fuzz*=3.0;
6056 pixel=p->red-q->red;
6057 if (IsHueCompatibleColorspace(p->colorspace) != MagickFalse)
6058 {
6059 /*
6060 This calculates a arc distance for hue-- it should be a vector
6061 angle of 'S'/'W' length with 'L'/'B' forming appropriate cones.
6062 In other words this is a hack - Anthony.
6063 */
6064 if (fabs((double) pixel) > ((double) QuantumRange/2.0))
6065 pixel-=(double) QuantumRange;
6066 pixel*=2.0;
6067 }
6068 distance+=pixel*pixel*scale;
6069 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6070 return(MagickFalse);
6071 pixel=p->green-q->green;
6072 distance+=pixel*pixel*scale;
6073 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6074 return(MagickFalse);
6075 pixel=p->blue-q->blue;
6076 distance+=pixel*pixel*scale;
6077 if (MagickSafeSignificantError(distance,fuzz) != MagickFalse)
6078 return(MagickFalse);
6079 return(MagickTrue);
6080}
6081␌
6082/*
6083%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6084% %
6085% %
6086% %
6087+ R e s e t P i x e l C h a n n e l M a p %
6088% %
6089% %
6090% %
6091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6092%
6093% ResetPixelChannelMap() defines the standard pixel component map.
6094%
6095% The format of the ResetPixelChannelMap() method is:
6096%
6097% MagickBooleanType ResetPixelChannelMap(Image *image)
6098%
6099% A description of each parameter follows:
6100%
6101% o image: the image.
6102%
6103% o exception: return any errors or warnings in this structure.
6104%
6105*/
6106MagickPrivate MagickBooleanType ResetPixelChannelMap(Image *image,
6107 ExceptionInfo *exception)
6108{
6109 PixelTrait
6110 trait;
6111
6112 ssize_t
6113 n;
6114
6115 assert(image != (Image *) NULL);
6116 assert(image->signature == MagickCoreSignature);
6117 (void) memset(image->channel_map,0,MaxPixelChannels*
6118 sizeof(*image->channel_map));
6119 trait=UpdatePixelTrait;
6120 if (image->alpha_trait != UndefinedPixelTrait)
6121 trait=(PixelTrait) (trait | BlendPixelTrait);
6122 n=0;
6123 if ((image->colorspace == LinearGRAYColorspace) ||
6124 (image->colorspace == GRAYColorspace))
6125 {
6126 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
6127 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
6128 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
6129 }
6130 else
6131 {
6132 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
6133 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
6134 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
6135 }
6136 if (image->colorspace == CMYKColorspace)
6137 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
6138 if (image->alpha_trait != UndefinedPixelTrait)
6139 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
6140 if (image->storage_class == PseudoClass)
6141 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
6142 if ((image->channels & ReadMaskChannel) != 0)
6143 SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++);
6144 if ((image->channels & WriteMaskChannel) != 0)
6145 SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++);
6146 if ((image->channels & CompositeMaskChannel) != 0)
6147 SetPixelChannelAttributes(image,CompositeMaskPixelChannel,CopyPixelTrait,
6148 n++);
6149 if (image->number_meta_channels != 0)
6150 {
6151 PixelChannel
6152 meta_channel;
6153
6154 ssize_t
6155 i;
6156
6157 if (image->number_meta_channels >= (size_t) (MaxPixelChannels-MetaPixelChannels))
6158 {
6159 image->number_channels=(size_t) n;
6160 image->number_meta_channels=0;
6161 (void) SetPixelChannelMask(image,image->channel_mask);
6162 ThrowBinaryException(CorruptImageError,"MaximumChannelsExceeded",
6163 image->filename);
6164 }
6165 meta_channel=MetaPixelChannels;
6166 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
6167 {
6168 SetPixelChannelAttributes(image,meta_channel,UpdatePixelTrait,n);
6169 meta_channel=(PixelChannel) (meta_channel+1);
6170 n++;
6171 }
6172 }
6173 image->number_channels=(size_t) n;
6174 (void) SetPixelChannelMask(image,image->channel_mask);
6175 return(MagickTrue);
6176}
6177␌
6178/*
6179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6180% %
6181% %
6182% %
6183% S e t P i x e l C h a n n e l M a s k %
6184% %
6185% %
6186% %
6187%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6188%
6189% SetPixelChannelMask() sets the pixel channel map from the specified channel
6190% mask.
6191%
6192% The format of the SetPixelChannelMask method is:
6193%
6194% ChannelType SetPixelChannelMask(Image *image,
6195% const ChannelType channel_mask)
6196%
6197% A description of each parameter follows:
6198%
6199% o image: the image.
6200%
6201% o channel_mask: the channel mask.
6202%
6203*/
6204
6205static void LogPixelChannels(const Image *image)
6206{
6207 ssize_t
6208 i;
6209
6210 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[0x%08llx]",
6211 image->filename,(MagickOffsetType) image->channel_mask);
6212 for (i=0; i < (ssize_t) image->number_channels; i++)
6213 {
6214 char
6215 channel_name[MagickPathExtent],
6216 traits[MagickPathExtent];
6217
6218 const char
6219 *name;
6220
6221 PixelChannel
6222 channel;
6223
6224 channel=GetPixelChannelChannel(image,i);
6225 switch (channel)
6226 {
6227 case RedPixelChannel:
6228 {
6229 name="red";
6230 if (image->colorspace == CMYKColorspace)
6231 name="cyan";
6232 if ((image->colorspace == LinearGRAYColorspace) ||
6233 (image->colorspace == GRAYColorspace))
6234 name="gray";
6235 break;
6236 }
6237 case GreenPixelChannel:
6238 {
6239 name="green";
6240 if (image->colorspace == CMYKColorspace)
6241 name="magenta";
6242 break;
6243 }
6244 case BluePixelChannel:
6245 {
6246 name="blue";
6247 if (image->colorspace == CMYKColorspace)
6248 name="yellow";
6249 break;
6250 }
6251 case BlackPixelChannel:
6252 {
6253 name="black";
6254 if (image->storage_class == PseudoClass)
6255 name="index";
6256 break;
6257 }
6258 case IndexPixelChannel:
6259 {
6260 name="index";
6261 break;
6262 }
6263 case AlphaPixelChannel:
6264 {
6265 name="alpha";
6266 break;
6267 }
6268 case ReadMaskPixelChannel:
6269 {
6270 name="read-mask";
6271 break;
6272 }
6273 case WriteMaskPixelChannel:
6274 {
6275 name="write-mask";
6276 break;
6277 }
6278 case CompositeMaskPixelChannel:
6279 {
6280 name="composite-mask";
6281 break;
6282 }
6283 case MetaPixelChannels:
6284 {
6285 name="meta";
6286 break;
6287 }
6288 default:
6289 name="undefined";
6290 }
6291 if (image->colorspace == UndefinedColorspace)
6292 {
6293 (void) FormatLocaleString(channel_name,MagickPathExtent,"%.17g",
6294 (double) channel);
6295 name=(const char *) channel_name;
6296 }
6297 *traits='\0';
6298 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0)
6299 (void) ConcatenateMagickString(traits,"update,",MagickPathExtent);
6300 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0)
6301 (void) ConcatenateMagickString(traits,"blend,",MagickPathExtent);
6302 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0)
6303 (void) ConcatenateMagickString(traits,"copy,",MagickPathExtent);
6304 if (*traits == '\0')
6305 (void) ConcatenateMagickString(traits,"undefined,",MagickPathExtent);
6306 traits[strlen(traits)-1]='\0';
6307 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.17g: %s (%s)",
6308 (double) i,name,traits);
6309 }
6310}
6311
6312MagickExport ChannelType SetPixelChannelMask(Image *image,
6313 const ChannelType channel_mask)
6314{
6315#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
6316
6317 ChannelType
6318 mask;
6319
6320 ssize_t
6321 i;
6322
6323 assert(image != (Image *) NULL);
6324 assert(image->signature == MagickCoreSignature);
6325 if (image->debug != MagickFalse)
6326 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[0x%08llx]",
6327 image->filename,(MagickOffsetType) channel_mask);
6328 mask=image->channel_mask;
6329 image->channel_mask=channel_mask;
6330 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
6331 {
6332 PixelChannel channel = GetPixelChannelChannel(image,i);
6333 if (GetChannelBit(channel_mask,channel) == 0)
6334 {
6335 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6336 continue;
6337 }
6338 if (channel == AlphaPixelChannel)
6339 {
6340 if ((image->alpha_trait & CopyPixelTrait) != 0)
6341 {
6342 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6343 continue;
6344 }
6345 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
6346 continue;
6347 }
6348 if (image->alpha_trait != UndefinedPixelTrait)
6349 {
6350 SetPixelChannelTraits(image,channel,(PixelTrait) (UpdatePixelTrait |
6351 BlendPixelTrait));
6352 continue;
6353 }
6354 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
6355 }
6356 if (image->storage_class == PseudoClass)
6357 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
6358 if ((image->channels & ReadMaskChannel) != 0)
6359 SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait);
6360 if ((image->channels & WriteMaskChannel) != 0)
6361 SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait);
6362 if ((image->channels & CompositeMaskChannel) != 0)
6363 SetPixelChannelTraits(image,CompositeMaskPixelChannel,CopyPixelTrait);
6364 if ((GetLogEventMask() & PixelEvent) != 0)
6365 LogPixelChannels(image);
6366 return(mask);
6367}
6368␌
6369/*
6370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6371% %
6372% %
6373% %
6374% S e t P i x e l M e t a C h a n n e l s %
6375% %
6376% %
6377% %
6378%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6379%
6380% SetPixelMetaChannels() sets the image meta channels.
6381%
6382% The format of the SetPixelMetaChannels method is:
6383%
6384% MagickBooleanType SetPixelMetaChannels(Image *image,
6385% const size_t number_meta_channels,ExceptionInfo *exception)
6386%
6387% A description of each parameter follows:
6388%
6389% o image: the image.
6390%
6391% o number_meta_channels: the number of meta channels.
6392%
6393% o exception: return any errors or warnings in this structure.
6394%
6395*/
6396MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
6397 const size_t number_meta_channels,ExceptionInfo *exception)
6398{
6399 MagickBooleanType
6400 status;
6401
6402 if (number_meta_channels >= (size_t) (MaxPixelChannels-MetaPixelChannels))
6403 ThrowBinaryException(CorruptImageError,"MaximumChannelsExceeded",
6404 image->filename);
6405 image->number_meta_channels=number_meta_channels;
6406 status=ResetPixelChannelMap(image,exception);
6407 if (status == MagickFalse)
6408 return(MagickFalse);
6409 return(SyncImagePixelCache(image,exception));
6410}
6411␌
6412/*
6413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6414% %
6415% %
6416% %
6417% S o r t I m a g e P i x e l s %
6418% %
6419% %
6420% %
6421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6422%
6423% SortImagePixels() sorts pixels within each scanline in ascending order of
6424% intensity.
6425%
6426% The format of the SortImagePixels method is:
6427%
6428% MagickBooleanType SortImagePixels(Image *image,ExceptionInfo *exception)
6429%
6430% A description of each parameter follows:
6431%
6432% o image: the image.
6433%
6434% o exception: return any errors or warnings in this structure.
6435%
6436*/
6437MagickExport MagickBooleanType SortImagePixels(Image *image,
6438 ExceptionInfo *exception)
6439{
6440#define SolarizeImageTag "Solarize/Image"
6441
6442 CacheView
6443 *image_view;
6444
6445 MagickBooleanType
6446 status;
6447
6448 MagickOffsetType
6449 progress;
6450
6451 ssize_t
6452 y;
6453
6454 /*
6455 Sort image pixels.
6456 */
6457 assert(image != (Image *) NULL);
6458 assert(image->signature == MagickCoreSignature);
6459 if (IsEventLogging() != MagickFalse)
6460 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
6461 status=MagickTrue;
6462 progress=0;
6463 image_view=AcquireAuthenticCacheView(image,exception);
6464#if defined(MAGICKCORE_OPENMP_SUPPORT)
6465 #pragma omp parallel for schedule(static) shared(progress,status) \
6466 magick_number_threads(image,image,image->rows,1)
6467#endif
6468 for (y=0; y < (ssize_t) image->rows; y++)
6469 {
6470 Quantum
6471 *magick_restrict q;
6472
6473 ssize_t
6474 x;
6475
6476 if (status == MagickFalse)
6477 continue;
6478 q=GetCacheViewAuthenticPixels(image_view,0,y,image->columns,1,exception);
6479 if (q == (Quantum *) NULL)
6480 {
6481 status=MagickFalse;
6482 continue;
6483 }
6484 for (x=0; x < (ssize_t) image->columns-1; x++)
6485 {
6486 MagickRealType
6487 current,
6488 previous;
6489
6490 ssize_t
6491 j;
6492
6493 previous=GetPixelIntensity(image,q);
6494 for (j=0; j < ((ssize_t) image->columns-x-1); j++)
6495 {
6496 current=GetPixelIntensity(image,q+(j+1)*(ssize_t)
6497 GetPixelChannels(image));
6498 if (previous > current)
6499 {
6500 Quantum
6501 pixel[MaxPixelChannels];
6502
6503 /*
6504 Swap adjacent pixels.
6505 */
6506 (void) memcpy(pixel,q+j*(ssize_t) GetPixelChannels(image),
6507 GetPixelChannels(image)*sizeof(Quantum));
6508 (void) memcpy(q+j*(ssize_t) GetPixelChannels(image),q+(j+1)*
6509 (ssize_t) GetPixelChannels(image),GetPixelChannels(image)*
6510 sizeof(Quantum));
6511 (void) memcpy(q+(j+1)*(ssize_t) GetPixelChannels(image),pixel,
6512 GetPixelChannels(image)*sizeof(Quantum));
6513 }
6514 else
6515 previous=current;
6516 }
6517 }
6518 if (SyncCacheViewAuthenticPixels(image_view,exception) == MagickFalse)
6519 status=MagickFalse;
6520 if (image->progress_monitor != (MagickProgressMonitor) NULL)
6521 {
6522 MagickBooleanType
6523 proceed;
6524
6525#if defined(MAGICKCORE_OPENMP_SUPPORT)
6526 #pragma omp atomic
6527#endif
6528 progress++;
6529 proceed=SetImageProgress(image,SolarizeImageTag,progress,image->rows);
6530 if (proceed == MagickFalse)
6531 status=MagickFalse;
6532 }
6533 }
6534 image_view=DestroyCacheView(image_view);
6535 return(status);
6536}