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