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