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