MagickCore  7.0.7
Convert, Edit, Or Compose Bitmap Images
pixel.c
Go to the documentation of this file.
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-2018 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://www.imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 
38 /*
39  Include declarations.
40 */
41 #include "MagickCore/studio.h"
42 #include "MagickCore/property.h"
43 #include "MagickCore/blob.h"
48 #include "MagickCore/draw.h"
49 #include "MagickCore/exception.h"
51 #include "MagickCore/cache.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/geometry.h"
56 #include "MagickCore/list.h"
57 #include "MagickCore/magick.h"
58 #include "MagickCore/memory_.h"
60 #include "MagickCore/monitor.h"
61 #include "MagickCore/option.h"
62 #include "MagickCore/pixel.h"
65 #include "MagickCore/quantum.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 */
94 {
96  *channel_map;
97 
98  register ssize_t
99  i;
100 
102  sizeof(*channel_map));
103  if (channel_map == (PixelChannelMap *) NULL)
104  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
105  (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
106  for (i=0; i < MaxPixelChannels; i++)
107  channel_map[i].channel=(PixelChannel) i;
108  return(channel_map);
109 }
110 
111 /*
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113 % %
114 % %
115 % %
116 + C l o n e P i x e l C h a n n e l M a p %
117 % %
118 % %
119 % %
120 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121 %
122 % ClonePixelChannelMap() clones a pixel component map.
123 %
124 % The format of the ClonePixelChannelMap() method is:
125 %
126 % PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
127 %
128 % A description of each parameter follows:
129 %
130 % o channel_map: the pixel component map.
131 %
132 */
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) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
143  sizeof(*channel_map));
144  return(clone_map);
145 }
146 
147 /*
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 % %
150 % %
151 % %
152 + C l o n e P i x e l I n f o %
153 % %
154 % %
155 % %
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 %
158 % ClonePixelInfo() makes a duplicate of the given pixel info structure, or if
159 % pixel info is NULL, a new one.
160 %
161 % The format of the ClonePixelInfo method is:
162 %
163 % PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
164 %
165 % A description of each parameter follows:
166 %
167 % o pixel: the pixel info.
168 %
169 */
171 {
172  PixelInfo
173  *pixel_info;
174 
175  pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
176  if (pixel_info == (PixelInfo *) NULL)
177  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
178  *pixel_info=(*pixel);
179  return(pixel_info);
180 }
181 
182 /*
183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184 % %
185 % %
186 % %
187 + C o n f o r m P i x e l I n f o %
188 % %
189 % %
190 % %
191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 %
193 % ConformPixelInfo() ensures the pixel conforms with the colorspace and alpha
194 % attribute of the image.
195 %
196 % The format of the ConformPixelInfo method is:
197 %
198 % void *ConformPixelInfo((Image *image,const PixelInfo *source,
199 % PixelInfo *destination,ExceptionInfo *exception)
200 %
201 % A description of each parameter follows:
202 %
203 % o image: the image.
204 %
205 % o source: the source pixel info.
206 %
207 % o destination: the destination pixel info.
208 %
209 % o exception: return any errors or warnings in this structure.
210 %
211 */
212 MagickExport void ConformPixelInfo(Image *image,const PixelInfo *source,
213  PixelInfo *destination,ExceptionInfo *exception)
214 {
215  assert(image != (Image *) NULL);
216  assert(image->signature == MagickCoreSignature);
217  assert(destination != (const PixelInfo *) NULL);
218  *destination=(*source);
219  if (image->colorspace == CMYKColorspace)
220  {
221  if (IssRGBCompatibleColorspace(destination->colorspace))
222  ConvertRGBToCMYK(destination);
223  }
224  else
225  if (destination->colorspace == CMYKColorspace)
226  {
228  ConvertCMYKToRGB(destination);
229  }
230  if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
232  (void) TransformImageColorspace(image,sRGBColorspace,exception);
233  if ((destination->alpha_trait != UndefinedPixelTrait) &&
234  (image->alpha_trait == UndefinedPixelTrait))
235  (void) SetImageAlpha(image,OpaqueAlpha,exception);
236 }
237 
238 /*
239 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240 % %
241 % %
242 % %
243 % D e c o d e P i x e l G a m m a %
244 % %
245 % %
246 % %
247 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
248 %
249 % DecodePixelGamma() applies the expansive power-law nonlinearity to the pixel.
250 %
251 % The format of the DecodePixelGamma method is:
252 %
253 % double DecodePixelGamma(const MagickRealType pixel)
254 %
255 % A description of each parameter follows:
256 %
257 % o pixel: the pixel.
258 %
259 */
260 
261 static inline double DecodeGamma(const double x)
262 {
263  div_t
264  quotient;
265 
266  double
267  p,
268  term[9];
269 
270  int
271  exponent;
272 
273  static const double coefficient[] = /* terms for x^(7/5), x=1.5 */
274  {
275  1.7917488588043277509,
276  0.82045614371976854984,
277  0.027694100686325412819,
278  -0.00094244335181762134018,
279  0.000064355540911469709545,
280  -5.7224404636060757485e-06,
281  5.8767669437311184313e-07,
282  -6.6139920053589721168e-08,
283  7.9323242696227458163e-09
284  };
285 
286  static const double powers_of_two[] = /* (2^x)^(7/5) */
287  {
288  1.0,
289  2.6390158215457883983,
290  6.9644045063689921093,
291  1.8379173679952558018e+01,
292  4.8502930128332728543e+01
293  };
294 
295  /*
296  Compute x^2.4 == x*x^(7/5) == pow(x,2.4).
297  */
298  term[0]=1.0;
299  term[1]=4.0*frexp(x,&exponent)-3.0;
300  term[2]=2.0*term[1]*term[1]-term[0];
301  term[3]=2.0*term[1]*term[2]-term[1];
302  term[4]=2.0*term[1]*term[3]-term[2];
303  term[5]=2.0*term[1]*term[4]-term[3];
304  term[6]=2.0*term[1]*term[5]-term[4];
305  term[7]=2.0*term[1]*term[6]-term[5];
306  term[8]=2.0*term[1]*term[7]-term[6];
307  p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
308  coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
309  coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
310  quotient=div(exponent-1,5);
311  if (quotient.rem < 0)
312  {
313  quotient.quot-=1;
314  quotient.rem+=5;
315  }
316  return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot));
317 }
318 
320 {
321  if (pixel <= (0.0404482362771076*QuantumRange))
322  return(pixel/12.92f);
324  pixel+0.055)/1.055)));
325 }
326 
327 /*
328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 % %
330 % %
331 % %
332 + D e s t r o y P i x e l C h a n n e l M a p %
333 % %
334 % %
335 % %
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337 %
338 % DestroyPixelChannelMap() deallocates memory associated with the pixel
339 % channel map.
340 %
341 % The format of the DestroyPixelChannelMap() method is:
342 %
343 % PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
344 %
345 % A description of each parameter follows:
346 %
347 % o channel_map: the pixel component map.
348 %
349 */
351  PixelChannelMap *channel_map)
352 {
353  assert(channel_map != (PixelChannelMap *) NULL);
354  channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
355  return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
356 }
357 
358 /*
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360 % %
361 % %
362 % %
363 + E n c o d e P i x e l G a m m a %
364 % %
365 % %
366 % %
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368 %
369 % EncodePixelGamma() cancels any nonlinearity in the pixel.
370 %
371 % The format of the EncodePixelGamma method is:
372 %
373 % MagickRealType EncodePixelGamma(const double MagickRealType)
374 %
375 % A description of each parameter follows:
376 %
377 % o pixel: the pixel.
378 %
379 */
380 
381 static inline double EncodeGamma(const double x)
382 {
383  div_t
384  quotient;
385 
386  double
387  p,
388  term[9];
389 
390  int
391  exponent;
392 
393  static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */
394  {
395  1.1758200232996901923,
396  0.16665763094889061230,
397  -0.0083154894939042125035,
398  0.00075187976780420279038,
399  -0.000083240178519391795367,
400  0.000010229209410070008679,
401  -1.3400466409860246e-06,
402  1.8333422241635376682e-07,
403  -2.5878596761348859722e-08
404  };
405 
406  static const double powers_of_two[] = /* (2^N)^(5/12) */
407  {
408  1.0,
409  1.3348398541700343678,
410  1.7817974362806785482,
411  2.3784142300054420538,
412  3.1748021039363991669,
413  4.2378523774371812394,
414  5.6568542494923805819,
415  7.5509945014535482244,
416  1.0079368399158985525e1,
417  1.3454342644059433809e1,
418  1.7959392772949968275e1,
419  2.3972913230026907883e1
420  };
421 
422  /*
423  Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4).
424  */
425  term[0]=1.0;
426  term[1]=4.0*frexp(x,&exponent)-3.0;
427  term[2]=2.0*term[1]*term[1]-term[0];
428  term[3]=2.0*term[1]*term[2]-term[1];
429  term[4]=2.0*term[1]*term[3]-term[2];
430  term[5]=2.0*term[1]*term[4]-term[3];
431  term[6]=2.0*term[1]*term[5]-term[4];
432  term[7]=2.0*term[1]*term[6]-term[5];
433  term[8]=2.0*term[1]*term[7]-term[6];
434  p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
435  coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
436  coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
437  quotient=div(exponent-1,12);
438  if (quotient.rem < 0)
439  {
440  quotient.quot-=1;
441  quotient.rem+=12;
442  }
443  return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot));
444 }
445 
447 {
448  if (pixel <= (0.0031306684425005883*QuantumRange))
449  return(12.92f*pixel);
450  return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale*
451  pixel)-0.055));
452 }
453 
454 /*
455 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456 % %
457 % %
458 % %
459 % E x p o r t I m a g e P i x e l s %
460 % %
461 % %
462 % %
463 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
464 %
465 % ExportImagePixels() extracts pixel data from an image and returns it to you.
466 % The method returns MagickTrue on success otherwise MagickFalse if an error is
467 % encountered. The data is returned as char, short int, Quantum, unsigned int,
468 % unsigned long long, float, or double in the order specified by map.
469 %
470 % Suppose you want to extract the first scanline of a 640x480 image as
471 % character data in red-green-blue order:
472 %
473 % ExportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels,exception);
474 %
475 % The format of the ExportImagePixels method is:
476 %
477 % MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
478 % const ssize_t y,const size_t width,const size_t height,
479 % const char *map,const StorageType type,void *pixels,
480 % ExceptionInfo *exception)
481 %
482 % A description of each parameter follows:
483 %
484 % o image: the image.
485 %
486 % o x,y,width,height: These values define the perimeter
487 % of a region of pixels you want to extract.
488 %
489 % o map: This string reflects the expected ordering of the pixel array.
490 % It can be any combination or order of R = red, G = green, B = blue,
491 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
492 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
493 % P = pad.
494 %
495 % o type: Define the data type of the pixels. Float and double types are
496 % normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
497 % types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
498 % LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
499 % QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
500 %
501 % o pixels: This array of values contain the pixel components as defined by
502 % map and type. You must preallocate this array where the expected
503 % length varies depending on the values of width, height, map, and type.
504 %
505 % o exception: return any errors or warnings in this structure.
506 %
507 */
508 
509 static void ExportCharPixel(const Image *image,const RectangleInfo *roi,
510  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
511  ExceptionInfo *exception)
512 {
513  register const Quantum
514  *magick_restrict p;
515 
516  register ssize_t
517  x;
518 
519  register unsigned char
520  *magick_restrict q;
521 
522  size_t
523  length;
524 
525  ssize_t
526  y;
527 
528  q=(unsigned char *) pixels;
529  if (LocaleCompare(map,"BGR") == 0)
530  {
531  for (y=0; y < (ssize_t) roi->height; y++)
532  {
533  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
534  if (p == (const Quantum *) NULL)
535  break;
536  for (x=0; x < (ssize_t) roi->width; x++)
537  {
538  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
539  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
540  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
541  p+=GetPixelChannels(image);
542  }
543  }
544  return;
545  }
546  if (LocaleCompare(map,"BGRA") == 0)
547  {
548  for (y=0; y < (ssize_t) roi->height; y++)
549  {
550  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
551  if (p == (const Quantum *) NULL)
552  break;
553  for (x=0; x < (ssize_t) roi->width; x++)
554  {
555  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
556  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
557  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
558  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
559  p+=GetPixelChannels(image);
560  }
561  }
562  return;
563  }
564  if (LocaleCompare(map,"BGRP") == 0)
565  {
566  for (y=0; y < (ssize_t) roi->height; y++)
567  {
568  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
569  if (p == (const Quantum *) NULL)
570  break;
571  for (x=0; x < (ssize_t) roi->width; x++)
572  {
573  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
574  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
575  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
576  *q++=ScaleQuantumToChar((Quantum) 0);
577  p+=GetPixelChannels(image);
578  }
579  }
580  return;
581  }
582  if (LocaleCompare(map,"I") == 0)
583  {
584  for (y=0; y < (ssize_t) roi->height; y++)
585  {
586  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
587  if (p == (const Quantum *) NULL)
588  break;
589  for (x=0; x < (ssize_t) roi->width; x++)
590  {
591  *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
592  p+=GetPixelChannels(image);
593  }
594  }
595  return;
596  }
597  if (LocaleCompare(map,"RGB") == 0)
598  {
599  for (y=0; y < (ssize_t) roi->height; y++)
600  {
601  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
602  if (p == (const Quantum *) NULL)
603  break;
604  for (x=0; x < (ssize_t) roi->width; x++)
605  {
606  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
607  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
608  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
609  p+=GetPixelChannels(image);
610  }
611  }
612  return;
613  }
614  if (LocaleCompare(map,"RGBA") == 0)
615  {
616  for (y=0; y < (ssize_t) roi->height; y++)
617  {
618  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
619  if (p == (const Quantum *) NULL)
620  break;
621  for (x=0; x < (ssize_t) roi->width; x++)
622  {
623  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
624  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
625  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
626  *q++=ScaleQuantumToChar(GetPixelAlpha(image,p));
627  p+=GetPixelChannels(image);
628  }
629  }
630  return;
631  }
632  if (LocaleCompare(map,"RGBP") == 0)
633  {
634  for (y=0; y < (ssize_t) roi->height; y++)
635  {
636  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
637  if (p == (const Quantum *) NULL)
638  break;
639  for (x=0; x < (ssize_t) roi->width; x++)
640  {
641  *q++=ScaleQuantumToChar(GetPixelRed(image,p));
642  *q++=ScaleQuantumToChar(GetPixelGreen(image,p));
643  *q++=ScaleQuantumToChar(GetPixelBlue(image,p));
644  *q++=ScaleQuantumToChar((Quantum) 0);
645  p+=GetPixelChannels(image);
646  }
647  }
648  return;
649  }
650  length=strlen(map);
651  for (y=0; y < (ssize_t) roi->height; y++)
652  {
653  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
654  if (p == (const Quantum *) NULL)
655  break;
656  for (x=0; x < (ssize_t) roi->width; x++)
657  {
658  register ssize_t
659  i;
660 
661  for (i=0; i < (ssize_t) length; i++)
662  {
663  *q=0;
664  switch (quantum_map[i])
665  {
666  case RedQuantum:
667  case CyanQuantum:
668  {
669  *q=ScaleQuantumToChar(GetPixelRed(image,p));
670  break;
671  }
672  case GreenQuantum:
673  case MagentaQuantum:
674  {
675  *q=ScaleQuantumToChar(GetPixelGreen(image,p));
676  break;
677  }
678  case BlueQuantum:
679  case YellowQuantum:
680  {
681  *q=ScaleQuantumToChar(GetPixelBlue(image,p));
682  break;
683  }
684  case AlphaQuantum:
685  {
686  *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
687  break;
688  }
689  case OpacityQuantum:
690  {
691  *q=ScaleQuantumToChar(GetPixelAlpha(image,p));
692  break;
693  }
694  case BlackQuantum:
695  {
696  if (image->colorspace == CMYKColorspace)
697  *q=ScaleQuantumToChar(GetPixelBlack(image,p));
698  break;
699  }
700  case IndexQuantum:
701  {
702  *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
703  break;
704  }
705  default:
706  break;
707  }
708  q++;
709  }
710  p+=GetPixelChannels(image);
711  }
712  }
713 }
714 
715 static void ExportDoublePixel(const Image *image,const RectangleInfo *roi,
716  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
717  ExceptionInfo *exception)
718 {
719  register const Quantum
720  *magick_restrict p;
721 
722  register double
723  *magick_restrict q;
724 
725  register 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++=(double) (QuantumScale*GetPixelBlue(image,p));
745  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
746  *q++=(double) (QuantumScale*GetPixelRed(image,p));
747  p+=GetPixelChannels(image);
748  }
749  }
750  return;
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++=(double) (QuantumScale*GetPixelBlue(image,p));
762  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
763  *q++=(double) (QuantumScale*GetPixelRed(image,p));
764  *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
765  p+=GetPixelChannels(image);
766  }
767  }
768  return;
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++=(double) (QuantumScale*GetPixelBlue(image,p));
780  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
781  *q++=(double) (QuantumScale*GetPixelRed(image,p));
782  *q++=0.0;
783  p+=GetPixelChannels(image);
784  }
785  }
786  return;
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*GetPixelIntensity(image,p));
798  p+=GetPixelChannels(image);
799  }
800  }
801  return;
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++=(double) (QuantumScale*GetPixelRed(image,p));
813  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
814  *q++=(double) (QuantumScale*GetPixelBlue(image,p));
815  p+=GetPixelChannels(image);
816  }
817  }
818  return;
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++=(double) (QuantumScale*GetPixelRed(image,p));
830  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
831  *q++=(double) (QuantumScale*GetPixelBlue(image,p));
832  *q++=(double) (QuantumScale*GetPixelAlpha(image,p));
833  p+=GetPixelChannels(image);
834  }
835  }
836  return;
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++=(double) (QuantumScale*GetPixelRed(image,p));
848  *q++=(double) (QuantumScale*GetPixelGreen(image,p));
849  *q++=(double) (QuantumScale*GetPixelBlue(image,p));
850  *q++=0.0;
851  p+=GetPixelChannels(image);
852  }
853  }
854  return;
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  register 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=(double) (QuantumScale*GetPixelRed(image,p));
876  break;
877  }
878  case GreenQuantum:
879  case MagentaQuantum:
880  {
881  *q=(double) (QuantumScale*GetPixelGreen(image,p));
882  break;
883  }
884  case BlueQuantum:
885  case YellowQuantum:
886  {
887  *q=(double) (QuantumScale*GetPixelBlue(image,p));
888  break;
889  }
890  case AlphaQuantum:
891  {
892  *q=(double) (QuantumScale*GetPixelAlpha(image,p));
893  break;
894  }
895  case OpacityQuantum:
896  {
897  *q=(double) (QuantumScale*GetPixelAlpha(image,p));
898  break;
899  }
900  case BlackQuantum:
901  {
902  if (image->colorspace == CMYKColorspace)
903  *q=(double) (QuantumScale*
904  GetPixelBlack(image,p));
905  break;
906  }
907  case IndexQuantum:
908  {
909  *q=(double) (QuantumScale*GetPixelIntensity(image,p));
910  break;
911  }
912  default:
913  *q=0;
914  }
915  q++;
916  }
917  p+=GetPixelChannels(image);
918  }
919  }
920 }
921 
922 static void ExportFloatPixel(const Image *image,const RectangleInfo *roi,
923  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
924  ExceptionInfo *exception)
925 {
926  register const Quantum
927  *magick_restrict p;
928 
929  register float
930  *magick_restrict q;
931 
932  register 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*GetPixelBlue(image,p));
952  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
953  *q++=(float) (QuantumScale*GetPixelRed(image,p));
954  p+=GetPixelChannels(image);
955  }
956  }
957  return;
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*GetPixelBlue(image,p));
969  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
970  *q++=(float) (QuantumScale*GetPixelRed(image,p));
971  *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
972  p+=GetPixelChannels(image);
973  }
974  }
975  return;
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*GetPixelBlue(image,p));
987  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
988  *q++=(float) (QuantumScale*GetPixelRed(image,p));
989  *q++=0.0;
990  p+=GetPixelChannels(image);
991  }
992  }
993  return;
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*GetPixelIntensity(image,p));
1005  p+=GetPixelChannels(image);
1006  }
1007  }
1008  return;
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*GetPixelRed(image,p));
1020  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1021  *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1022  p+=GetPixelChannels(image);
1023  }
1024  }
1025  return;
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*GetPixelRed(image,p));
1037  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1038  *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1039  *q++=(float) (QuantumScale*GetPixelAlpha(image,p));
1040  p+=GetPixelChannels(image);
1041  }
1042  }
1043  return;
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*GetPixelRed(image,p));
1055  *q++=(float) (QuantumScale*GetPixelGreen(image,p));
1056  *q++=(float) (QuantumScale*GetPixelBlue(image,p));
1057  *q++=0.0;
1058  p+=GetPixelChannels(image);
1059  }
1060  }
1061  return;
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  register 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*GetPixelRed(image,p));
1083  break;
1084  }
1085  case GreenQuantum:
1086  case MagentaQuantum:
1087  {
1088  *q=(float) (QuantumScale*GetPixelGreen(image,p));
1089  break;
1090  }
1091  case BlueQuantum:
1092  case YellowQuantum:
1093  {
1094  *q=(float) (QuantumScale*GetPixelBlue(image,p));
1095  break;
1096  }
1097  case AlphaQuantum:
1098  {
1099  *q=(float) (QuantumScale*((Quantum) (GetPixelAlpha(image,p))));
1100  break;
1101  }
1102  case OpacityQuantum:
1103  {
1104  *q=(float) (QuantumScale*GetPixelAlpha(image,p));
1105  break;
1106  }
1107  case BlackQuantum:
1108  {
1109  if (image->colorspace == CMYKColorspace)
1110  *q=(float) (QuantumScale* GetPixelBlack(image,p));
1111  break;
1112  }
1113  case IndexQuantum:
1114  {
1115  *q=(float) (QuantumScale*GetPixelIntensity(image,p));
1116  break;
1117  }
1118  default:
1119  *q=0;
1120  }
1121  q++;
1122  }
1123  p+=GetPixelChannels(image);
1124  }
1125  }
1126 }
1127 
1128 static void ExportLongPixel(const Image *image,const RectangleInfo *roi,
1129  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
1130  ExceptionInfo *exception)
1131 {
1132  register const Quantum
1133  *magick_restrict p;
1134 
1135  register ssize_t
1136  x;
1137 
1138  register unsigned int
1139  *magick_restrict q;
1140 
1141  size_t
1142  length;
1143 
1144  ssize_t
1145  y;
1146 
1147  q=(unsigned int *) pixels;
1148  if (LocaleCompare(map,"BGR") == 0)
1149  {
1150  for (y=0; y < (ssize_t) roi->height; y++)
1151  {
1152  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1153  if (p == (const Quantum *) NULL)
1154  break;
1155  for (x=0; x < (ssize_t) roi->width; x++)
1156  {
1157  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1158  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1159  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1160  p+=GetPixelChannels(image);
1161  }
1162  }
1163  return;
1164  }
1165  if (LocaleCompare(map,"BGRA") == 0)
1166  {
1167  for (y=0; y < (ssize_t) roi->height; y++)
1168  {
1169  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1170  if (p == (const Quantum *) NULL)
1171  break;
1172  for (x=0; x < (ssize_t) roi->width; x++)
1173  {
1174  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1175  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1176  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1177  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1178  p+=GetPixelChannels(image);
1179  }
1180  }
1181  return;
1182  }
1183  if (LocaleCompare(map,"BGRP") == 0)
1184  {
1185  for (y=0; y < (ssize_t) roi->height; y++)
1186  {
1187  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1188  if (p == (const Quantum *) NULL)
1189  break;
1190  for (x=0; x < (ssize_t) roi->width; x++)
1191  {
1192  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1193  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1194  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1195  *q++=0;
1196  p+=GetPixelChannels(image);
1197  }
1198  }
1199  return;
1200  }
1201  if (LocaleCompare(map,"I") == 0)
1202  {
1203  for (y=0; y < (ssize_t) roi->height; y++)
1204  {
1205  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1206  if (p == (const Quantum *) NULL)
1207  break;
1208  for (x=0; x < (ssize_t) roi->width; x++)
1209  {
1210  *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1211  p+=GetPixelChannels(image);
1212  }
1213  }
1214  return;
1215  }
1216  if (LocaleCompare(map,"RGB") == 0)
1217  {
1218  for (y=0; y < (ssize_t) roi->height; y++)
1219  {
1220  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1221  if (p == (const Quantum *) NULL)
1222  break;
1223  for (x=0; x < (ssize_t) roi->width; x++)
1224  {
1225  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1226  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1227  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1228  p+=GetPixelChannels(image);
1229  }
1230  }
1231  return;
1232  }
1233  if (LocaleCompare(map,"RGBA") == 0)
1234  {
1235  for (y=0; y < (ssize_t) roi->height; y++)
1236  {
1237  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1238  if (p == (const Quantum *) NULL)
1239  break;
1240  for (x=0; x < (ssize_t) roi->width; x++)
1241  {
1242  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1243  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1244  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1245  *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
1246  p+=GetPixelChannels(image);
1247  }
1248  }
1249  return;
1250  }
1251  if (LocaleCompare(map,"RGBP") == 0)
1252  {
1253  for (y=0; y < (ssize_t) roi->height; y++)
1254  {
1255  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1256  if (p == (const Quantum *) NULL)
1257  break;
1258  for (x=0; x < (ssize_t) roi->width; x++)
1259  {
1260  *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1261  *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1262  *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1263  *q++=0;
1264  p+=GetPixelChannels(image);
1265  }
1266  }
1267  return;
1268  }
1269  length=strlen(map);
1270  for (y=0; y < (ssize_t) roi->height; y++)
1271  {
1272  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1273  if (p == (const Quantum *) NULL)
1274  break;
1275  for (x=0; x < (ssize_t) roi->width; x++)
1276  {
1277  register ssize_t
1278  i;
1279 
1280  for (i=0; i < (ssize_t) length; i++)
1281  {
1282  *q=0;
1283  switch (quantum_map[i])
1284  {
1285  case RedQuantum:
1286  case CyanQuantum:
1287  {
1288  *q=ScaleQuantumToLong(GetPixelRed(image,p));
1289  break;
1290  }
1291  case GreenQuantum:
1292  case MagentaQuantum:
1293  {
1294  *q=ScaleQuantumToLong(GetPixelGreen(image,p));
1295  break;
1296  }
1297  case BlueQuantum:
1298  case YellowQuantum:
1299  {
1300  *q=ScaleQuantumToLong(GetPixelBlue(image,p));
1301  break;
1302  }
1303  case AlphaQuantum:
1304  {
1305  *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1306  break;
1307  }
1308  case OpacityQuantum:
1309  {
1310  *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
1311  break;
1312  }
1313  case BlackQuantum:
1314  {
1315  if (image->colorspace == CMYKColorspace)
1316  *q=ScaleQuantumToLong(GetPixelBlack(image,p));
1317  break;
1318  }
1319  case IndexQuantum:
1320  {
1321  *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
1322  break;
1323  }
1324  default:
1325  break;
1326  }
1327  q++;
1328  }
1329  p+=GetPixelChannels(image);
1330  }
1331  }
1332 }
1333 
1334 static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi,
1335  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
1336  ExceptionInfo *exception)
1337 {
1338  register const Quantum
1339  *magick_restrict p;
1340 
1341  register ssize_t
1342  x;
1343 
1344  register MagickSizeType
1345  *magick_restrict q;
1346 
1347  size_t
1348  length;
1349 
1350  ssize_t
1351  y;
1352 
1353  q=(MagickSizeType *) pixels;
1354  if (LocaleCompare(map,"BGR") == 0)
1355  {
1356  for (y=0; y < (ssize_t) roi->height; y++)
1357  {
1358  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1359  if (p == (const Quantum *) NULL)
1360  break;
1361  for (x=0; x < (ssize_t) roi->width; x++)
1362  {
1363  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1364  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1365  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1366  p+=GetPixelChannels(image);
1367  }
1368  }
1369  return;
1370  }
1371  if (LocaleCompare(map,"BGRA") == 0)
1372  {
1373  for (y=0; y < (ssize_t) roi->height; y++)
1374  {
1375  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1376  if (p == (const Quantum *) NULL)
1377  break;
1378  for (x=0; x < (ssize_t) roi->width; x++)
1379  {
1380  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1381  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1382  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1383  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1384  p+=GetPixelChannels(image);
1385  }
1386  }
1387  return;
1388  }
1389  if (LocaleCompare(map,"BGRP") == 0)
1390  {
1391  for (y=0; y < (ssize_t) roi->height; y++)
1392  {
1393  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1394  if (p == (const Quantum *) NULL)
1395  break;
1396  for (x=0; x < (ssize_t) roi->width; x++)
1397  {
1398  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1399  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1400  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1401  *q++=0;
1402  p+=GetPixelChannels(image);
1403  }
1404  }
1405  return;
1406  }
1407  if (LocaleCompare(map,"I") == 0)
1408  {
1409  for (y=0; y < (ssize_t) roi->height; y++)
1410  {
1411  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1412  if (p == (const Quantum *) NULL)
1413  break;
1414  for (x=0; x < (ssize_t) roi->width; x++)
1415  {
1416  *q++=ScaleQuantumToLongLong(ClampToQuantum(
1417  GetPixelIntensity(image,p)));
1418  p+=GetPixelChannels(image);
1419  }
1420  }
1421  return;
1422  }
1423  if (LocaleCompare(map,"RGB") == 0)
1424  {
1425  for (y=0; y < (ssize_t) roi->height; y++)
1426  {
1427  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1428  if (p == (const Quantum *) NULL)
1429  break;
1430  for (x=0; x < (ssize_t) roi->width; x++)
1431  {
1432  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1433  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1434  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1435  p+=GetPixelChannels(image);
1436  }
1437  }
1438  return;
1439  }
1440  if (LocaleCompare(map,"RGBA") == 0)
1441  {
1442  for (y=0; y < (ssize_t) roi->height; y++)
1443  {
1444  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1445  if (p == (const Quantum *) NULL)
1446  break;
1447  for (x=0; x < (ssize_t) roi->width; x++)
1448  {
1449  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1450  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1451  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1452  *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1453  p+=GetPixelChannels(image);
1454  }
1455  }
1456  return;
1457  }
1458  if (LocaleCompare(map,"RGBP") == 0)
1459  {
1460  for (y=0; y < (ssize_t) roi->height; y++)
1461  {
1462  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1463  if (p == (const Quantum *) NULL)
1464  break;
1465  for (x=0; x < (ssize_t) roi->width; x++)
1466  {
1467  *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1468  *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1469  *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1470  *q++=0;
1471  p+=GetPixelChannels(image);
1472  }
1473  }
1474  return;
1475  }
1476  length=strlen(map);
1477  for (y=0; y < (ssize_t) roi->height; y++)
1478  {
1479  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1480  if (p == (const Quantum *) NULL)
1481  break;
1482  for (x=0; x < (ssize_t) roi->width; x++)
1483  {
1484  register ssize_t
1485  i;
1486 
1487  for (i=0; i < (ssize_t) length; i++)
1488  {
1489  *q=0;
1490  switch (quantum_map[i])
1491  {
1492  case RedQuantum:
1493  case CyanQuantum:
1494  {
1495  *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
1496  break;
1497  }
1498  case GreenQuantum:
1499  case MagentaQuantum:
1500  {
1501  *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1502  break;
1503  }
1504  case BlueQuantum:
1505  case YellowQuantum:
1506  {
1507  *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1508  break;
1509  }
1510  case AlphaQuantum:
1511  {
1512  *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1513  break;
1514  }
1515  case OpacityQuantum:
1516  {
1517  *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
1518  break;
1519  }
1520  case BlackQuantum:
1521  {
1522  if (image->colorspace == CMYKColorspace)
1523  *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
1524  break;
1525  }
1526  case IndexQuantum:
1527  {
1528  *q=ScaleQuantumToLongLong(ClampToQuantum(
1529  GetPixelIntensity(image,p)));
1530  break;
1531  }
1532  default:
1533  break;
1534  }
1535  q++;
1536  }
1537  p+=GetPixelChannels(image);
1538  }
1539  }
1540 }
1541 
1542 static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi,
1543  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
1544  ExceptionInfo *exception)
1545 {
1546  register const Quantum
1547  *magick_restrict p;
1548 
1549  register Quantum
1550  *magick_restrict q;
1551 
1552  register ssize_t
1553  x;
1554 
1555  size_t
1556  length;
1557 
1558  ssize_t
1559  y;
1560 
1561  q=(Quantum *) pixels;
1562  if (LocaleCompare(map,"BGR") == 0)
1563  {
1564  for (y=0; y < (ssize_t) roi->height; y++)
1565  {
1566  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1567  if (p == (const Quantum *) NULL)
1568  break;
1569  for (x=0; x < (ssize_t) roi->width; x++)
1570  {
1571  *q++=GetPixelBlue(image,p);
1572  *q++=GetPixelGreen(image,p);
1573  *q++=GetPixelRed(image,p);
1574  p+=GetPixelChannels(image);
1575  }
1576  }
1577  return;
1578  }
1579  if (LocaleCompare(map,"BGRA") == 0)
1580  {
1581  for (y=0; y < (ssize_t) roi->height; y++)
1582  {
1583  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1584  if (p == (const Quantum *) NULL)
1585  break;
1586  for (x=0; x < (ssize_t) roi->width; x++)
1587  {
1588  *q++=GetPixelBlue(image,p);
1589  *q++=GetPixelGreen(image,p);
1590  *q++=GetPixelRed(image,p);
1591  *q++=(Quantum) (GetPixelAlpha(image,p));
1592  p+=GetPixelChannels(image);
1593  }
1594  }
1595  return;
1596  }
1597  if (LocaleCompare(map,"BGRP") == 0)
1598  {
1599  for (y=0; y < (ssize_t) roi->height; y++)
1600  {
1601  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1602  if (p == (const Quantum *) NULL)
1603  break;
1604  for (x=0; x < (ssize_t) roi->width; x++)
1605  {
1606  *q++=GetPixelBlue(image,p);
1607  *q++=GetPixelGreen(image,p);
1608  *q++=GetPixelRed(image,p);
1609  *q++=(Quantum) 0;
1610  p+=GetPixelChannels(image);
1611  }
1612  }
1613  return;
1614  }
1615  if (LocaleCompare(map,"I") == 0)
1616  {
1617  for (y=0; y < (ssize_t) roi->height; y++)
1618  {
1619  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1620  if (p == (const Quantum *) NULL)
1621  break;
1622  for (x=0; x < (ssize_t) roi->width; x++)
1623  {
1624  *q++=ClampToQuantum(GetPixelIntensity(image,p));
1625  p+=GetPixelChannels(image);
1626  }
1627  }
1628  return;
1629  }
1630  if (LocaleCompare(map,"RGB") == 0)
1631  {
1632  for (y=0; y < (ssize_t) roi->height; y++)
1633  {
1634  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1635  if (p == (const Quantum *) NULL)
1636  break;
1637  for (x=0; x < (ssize_t) roi->width; x++)
1638  {
1639  *q++=GetPixelRed(image,p);
1640  *q++=GetPixelGreen(image,p);
1641  *q++=GetPixelBlue(image,p);
1642  p+=GetPixelChannels(image);
1643  }
1644  }
1645  return;
1646  }
1647  if (LocaleCompare(map,"RGBA") == 0)
1648  {
1649  for (y=0; y < (ssize_t) roi->height; y++)
1650  {
1651  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1652  if (p == (const Quantum *) NULL)
1653  break;
1654  for (x=0; x < (ssize_t) roi->width; x++)
1655  {
1656  *q++=GetPixelRed(image,p);
1657  *q++=GetPixelGreen(image,p);
1658  *q++=GetPixelBlue(image,p);
1659  *q++=(Quantum) (GetPixelAlpha(image,p));
1660  p+=GetPixelChannels(image);
1661  }
1662  }
1663  return;
1664  }
1665  if (LocaleCompare(map,"RGBP") == 0)
1666  {
1667  for (y=0; y < (ssize_t) roi->height; y++)
1668  {
1669  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1670  if (p == (const Quantum *) NULL)
1671  break;
1672  for (x=0; x < (ssize_t) roi->width; x++)
1673  {
1674  *q++=GetPixelRed(image,p);
1675  *q++=GetPixelGreen(image,p);
1676  *q++=GetPixelBlue(image,p);
1677  *q++=(Quantum) 0;
1678  p+=GetPixelChannels(image);
1679  }
1680  }
1681  return;
1682  }
1683  length=strlen(map);
1684  for (y=0; y < (ssize_t) roi->height; y++)
1685  {
1686  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1687  if (p == (const Quantum *) NULL)
1688  break;
1689  for (x=0; x < (ssize_t) roi->width; x++)
1690  {
1691  register ssize_t
1692  i;
1693 
1694  for (i=0; i < (ssize_t) length; i++)
1695  {
1696  *q=(Quantum) 0;
1697  switch (quantum_map[i])
1698  {
1699  case RedQuantum:
1700  case CyanQuantum:
1701  {
1702  *q=GetPixelRed(image,p);
1703  break;
1704  }
1705  case GreenQuantum:
1706  case MagentaQuantum:
1707  {
1708  *q=GetPixelGreen(image,p);
1709  break;
1710  }
1711  case BlueQuantum:
1712  case YellowQuantum:
1713  {
1714  *q=GetPixelBlue(image,p);
1715  break;
1716  }
1717  case AlphaQuantum:
1718  {
1719  *q=GetPixelAlpha(image,p);
1720  break;
1721  }
1722  case OpacityQuantum:
1723  {
1724  *q=GetPixelAlpha(image,p);
1725  break;
1726  }
1727  case BlackQuantum:
1728  {
1729  if (image->colorspace == CMYKColorspace)
1730  *q=GetPixelBlack(image,p);
1731  break;
1732  }
1733  case IndexQuantum:
1734  {
1735  *q=ClampToQuantum(GetPixelIntensity(image,p));
1736  break;
1737  }
1738  default:
1739  {
1740  *q=(Quantum) 0;
1741  break;
1742  }
1743  }
1744  q++;
1745  }
1746  p+=GetPixelChannels(image);
1747  }
1748  }
1749 }
1750 
1751 static void ExportShortPixel(const Image *image,const RectangleInfo *roi,
1752  const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
1753  ExceptionInfo *exception)
1754 {
1755  register const Quantum
1756  *magick_restrict p;
1757 
1758  register ssize_t
1759  x;
1760 
1761  register unsigned short
1762  *magick_restrict q;
1763 
1764  size_t
1765  length;
1766 
1767  ssize_t
1768  y;
1769 
1770  q=(unsigned short *) pixels;
1771  if (LocaleCompare(map,"BGR") == 0)
1772  {
1773  for (y=0; y < (ssize_t) roi->height; y++)
1774  {
1775  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1776  if (p == (const Quantum *) NULL)
1777  break;
1778  for (x=0; x < (ssize_t) roi->width; x++)
1779  {
1780  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1781  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1782  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1783  p+=GetPixelChannels(image);
1784  }
1785  }
1786  return;
1787  }
1788  if (LocaleCompare(map,"BGRA") == 0)
1789  {
1790  for (y=0; y < (ssize_t) roi->height; y++)
1791  {
1792  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1793  if (p == (const Quantum *) NULL)
1794  break;
1795  for (x=0; x < (ssize_t) roi->width; x++)
1796  {
1797  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1798  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1799  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1800  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1801  p+=GetPixelChannels(image);
1802  }
1803  }
1804  return;
1805  }
1806  if (LocaleCompare(map,"BGRP") == 0)
1807  {
1808  for (y=0; y < (ssize_t) roi->height; y++)
1809  {
1810  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1811  if (p == (const Quantum *) NULL)
1812  break;
1813  for (x=0; x < (ssize_t) roi->width; x++)
1814  {
1815  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1816  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1817  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1818  *q++=0;
1819  p+=GetPixelChannels(image);
1820  }
1821  }
1822  return;
1823  }
1824  if (LocaleCompare(map,"I") == 0)
1825  {
1826  for (y=0; y < (ssize_t) roi->height; y++)
1827  {
1828  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1829  if (p == (const Quantum *) NULL)
1830  break;
1831  for (x=0; x < (ssize_t) roi->width; x++)
1832  {
1833  *q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1834  p+=GetPixelChannels(image);
1835  }
1836  }
1837  return;
1838  }
1839  if (LocaleCompare(map,"RGB") == 0)
1840  {
1841  for (y=0; y < (ssize_t) roi->height; y++)
1842  {
1843  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1844  if (p == (const Quantum *) NULL)
1845  break;
1846  for (x=0; x < (ssize_t) roi->width; x++)
1847  {
1848  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1849  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1850  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1851  p+=GetPixelChannels(image);
1852  }
1853  }
1854  return;
1855  }
1856  if (LocaleCompare(map,"RGBA") == 0)
1857  {
1858  for (y=0; y < (ssize_t) roi->height; y++)
1859  {
1860  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1861  if (p == (const Quantum *) NULL)
1862  break;
1863  for (x=0; x < (ssize_t) roi->width; x++)
1864  {
1865  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1866  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1867  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1868  *q++=ScaleQuantumToShort(GetPixelAlpha(image,p));
1869  p+=GetPixelChannels(image);
1870  }
1871  }
1872  return;
1873  }
1874  if (LocaleCompare(map,"RGBP") == 0)
1875  {
1876  for (y=0; y < (ssize_t) roi->height; y++)
1877  {
1878  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1879  if (p == (const Quantum *) NULL)
1880  break;
1881  for (x=0; x < (ssize_t) roi->width; x++)
1882  {
1883  *q++=ScaleQuantumToShort(GetPixelRed(image,p));
1884  *q++=ScaleQuantumToShort(GetPixelGreen(image,p));
1885  *q++=ScaleQuantumToShort(GetPixelBlue(image,p));
1886  *q++=0;
1887  p+=GetPixelChannels(image);
1888  }
1889  }
1890  return;
1891  }
1892  length=strlen(map);
1893  for (y=0; y < (ssize_t) roi->height; y++)
1894  {
1895  p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
1896  if (p == (const Quantum *) NULL)
1897  break;
1898  for (x=0; x < (ssize_t) roi->width; x++)
1899  {
1900  register ssize_t
1901  i;
1902 
1903  for (i=0; i < (ssize_t) length; i++)
1904  {
1905  *q=0;
1906  switch (quantum_map[i])
1907  {
1908  case RedQuantum:
1909  case CyanQuantum:
1910  {
1911  *q=ScaleQuantumToShort(GetPixelRed(image,p));
1912  break;
1913  }
1914  case GreenQuantum:
1915  case MagentaQuantum:
1916  {
1917  *q=ScaleQuantumToShort(GetPixelGreen(image,p));
1918  break;
1919  }
1920  case BlueQuantum:
1921  case YellowQuantum:
1922  {
1923  *q=ScaleQuantumToShort(GetPixelBlue(image,p));
1924  break;
1925  }
1926  case AlphaQuantum:
1927  {
1928  *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1929  break;
1930  }
1931  case OpacityQuantum:
1932  {
1933  *q=ScaleQuantumToShort(GetPixelAlpha(image,p));
1934  break;
1935  }
1936  case BlackQuantum:
1937  {
1938  if (image->colorspace == CMYKColorspace)
1939  *q=ScaleQuantumToShort(GetPixelBlack(image,p));
1940  break;
1941  }
1942  case IndexQuantum:
1943  {
1944  *q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
1945  break;
1946  }
1947  default:
1948  break;
1949  }
1950  q++;
1951  }
1952  p+=GetPixelChannels(image);
1953  }
1954  }
1955 }
1956 
1958  const ssize_t y,const size_t width,const size_t height,const char *map,
1959  const StorageType type,void *pixels,ExceptionInfo *exception)
1960 {
1961  QuantumType
1962  *quantum_map;
1963 
1965  roi;
1966 
1967  register ssize_t
1968  i;
1969 
1970  size_t
1971  length;
1972 
1973  assert(image != (Image *) NULL);
1974  assert(image->signature == MagickCoreSignature);
1975  if (image->debug != MagickFalse)
1976  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1977  length=strlen(map);
1978  quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
1979  if (quantum_map == (QuantumType *) NULL)
1980  {
1981  (void) ThrowMagickException(exception,GetMagickModule(),
1982  ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1983  return(MagickFalse);
1984  }
1985  for (i=0; i < (ssize_t) length; i++)
1986  {
1987  switch (map[i])
1988  {
1989  case 'A':
1990  case 'a':
1991  {
1992  quantum_map[i]=AlphaQuantum;
1993  break;
1994  }
1995  case 'B':
1996  case 'b':
1997  {
1998  quantum_map[i]=BlueQuantum;
1999  break;
2000  }
2001  case 'C':
2002  case 'c':
2003  {
2004  quantum_map[i]=CyanQuantum;
2005  if (image->colorspace == CMYKColorspace)
2006  break;
2007  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2008  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2009  "ColorSeparatedImageRequired","`%s'",map);
2010  return(MagickFalse);
2011  }
2012  case 'g':
2013  case 'G':
2014  {
2015  quantum_map[i]=GreenQuantum;
2016  break;
2017  }
2018  case 'I':
2019  case 'i':
2020  {
2021  quantum_map[i]=IndexQuantum;
2022  break;
2023  }
2024  case 'K':
2025  case 'k':
2026  {
2027  quantum_map[i]=BlackQuantum;
2028  if (image->colorspace == CMYKColorspace)
2029  break;
2030  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2031  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2032  "ColorSeparatedImageRequired","`%s'",map);
2033  return(MagickFalse);
2034  }
2035  case 'M':
2036  case 'm':
2037  {
2038  quantum_map[i]=MagentaQuantum;
2039  if (image->colorspace == CMYKColorspace)
2040  break;
2041  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2042  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2043  "ColorSeparatedImageRequired","`%s'",map);
2044  return(MagickFalse);
2045  }
2046  case 'o':
2047  case 'O':
2048  {
2049  quantum_map[i]=OpacityQuantum;
2050  break;
2051  }
2052  case 'P':
2053  case 'p':
2054  {
2055  quantum_map[i]=UndefinedQuantum;
2056  break;
2057  }
2058  case 'R':
2059  case 'r':
2060  {
2061  quantum_map[i]=RedQuantum;
2062  break;
2063  }
2064  case 'Y':
2065  case 'y':
2066  {
2067  quantum_map[i]=YellowQuantum;
2068  if (image->colorspace == CMYKColorspace)
2069  break;
2070  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2071  (void) ThrowMagickException(exception,GetMagickModule(),ImageError,
2072  "ColorSeparatedImageRequired","`%s'",map);
2073  return(MagickFalse);
2074  }
2075  default:
2076  {
2077  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2079  "UnrecognizedPixelMap","`%s'",map);
2080  return(MagickFalse);
2081  }
2082  }
2083  }
2084  roi.width=width;
2085  roi.height=height;
2086  roi.x=x;
2087  roi.y=y;
2088  switch (type)
2089  {
2090  case CharPixel:
2091  {
2092  ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
2093  break;
2094  }
2095  case DoublePixel:
2096  {
2097  ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
2098  break;
2099  }
2100  case FloatPixel:
2101  {
2102  ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
2103  break;
2104  }
2105  case LongPixel:
2106  {
2107  ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
2108  break;
2109  }
2110  case LongLongPixel:
2111  {
2112  ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
2113  break;
2114  }
2115  case QuantumPixel:
2116  {
2117  ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
2118  break;
2119  }
2120  case ShortPixel:
2121  {
2122  ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
2123  break;
2124  }
2125  default:
2126  {
2127  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2129  "UnrecognizedPixelMap","`%s'",map);
2130  break;
2131  }
2132  }
2133  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2134  return(MagickTrue);
2135 }
2136 
2137 /*
2138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2139 % %
2140 % %
2141 % %
2142 % G e t P i x e l I n f o %
2143 % %
2144 % %
2145 % %
2146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2147 %
2148 % GetPixelInfo() initializes the PixelInfo structure.
2149 %
2150 % The format of the GetPixelInfo method is:
2151 %
2152 % GetPixelInfo(const Image *image,PixelInfo *pixel)
2153 %
2154 % A description of each parameter follows:
2155 %
2156 % o image: the image. (optional - may be NULL)
2157 %
2158 % o pixel: Specifies a pointer to a PixelInfo structure.
2159 %
2160 */
2161 MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
2162 {
2163  pixel->storage_class=DirectClass;
2164  pixel->colorspace=sRGBColorspace;
2166  pixel->fuzz=0.0;
2168  pixel->red=0.0;
2169  pixel->green=0.0;
2170  pixel->blue=0.0;
2171  pixel->black=0.0;
2172  pixel->alpha=(double) OpaqueAlpha;
2173  pixel->index=0.0;
2174  pixel->count=0;
2175  pixel->fuzz=0.0;
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 */
2223  const Image *magick_restrict image,const PixelInfo *magick_restrict pixel)
2224 {
2226  blue,
2227  green,
2228  red,
2229  intensity;
2230 
2232  method;
2233 
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  {
2243  {
2244  intensity=(red+green+blue)/3.0;
2245  break;
2246  }
2248  {
2249  intensity=MagickMax(MagickMax(red,green),blue);
2250  break;
2251  }
2253  {
2254  intensity=(MagickMin(MagickMin(red,green),blue)+
2255  MagickMax(MagickMax(red,green),blue))/2.0;
2256  break;
2257  }
2259  {
2260  intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2261  (3.0*QuantumRange));
2262  break;
2263  }
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  }
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  }
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  }
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  }
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 */
2357  const Image *magick_restrict image,const Quantum *magick_restrict pixel)
2358 {
2360  blue,
2361  green,
2362  red,
2363  intensity;
2364 
2365  red=(MagickRealType) GetPixelRed(image,pixel);
2366  green=(MagickRealType) GetPixelGreen(image,pixel);
2367  blue=(MagickRealType) GetPixelBlue(image,pixel);
2368  switch (image->intensity)
2369  {
2371  {
2372  intensity=(red+green+blue)/3.0;
2373  break;
2374  }
2376  {
2377  intensity=MagickMax(MagickMax(red,green),blue);
2378  break;
2379  }
2381  {
2382  intensity=(MagickMin(MagickMin(red,green),blue)+
2383  MagickMax(MagickMax(red,green),blue))/2.0;
2384  break;
2385  }
2387  {
2388  intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2389  (3.0*QuantumRange));
2390  break;
2391  }
2393  {
2394  if (image->colorspace == RGBColorspace)
2395  {
2396  red=EncodePixelGamma(red);
2397  green=EncodePixelGamma(green);
2398  blue=EncodePixelGamma(blue);
2399  }
2400  intensity=0.298839*red+0.586811*green+0.114350*blue;
2401  break;
2402  }
2404  {
2405  if (image->colorspace == sRGBColorspace)
2406  {
2407  red=DecodePixelGamma(red);
2408  green=DecodePixelGamma(green);
2409  blue=DecodePixelGamma(blue);
2410  }
2411  intensity=0.298839*red+0.586811*green+0.114350*blue;
2412  break;
2413  }
2415  default:
2416  {
2417  if (image->colorspace == RGBColorspace)
2418  {
2419  red=EncodePixelGamma(red);
2420  green=EncodePixelGamma(green);
2421  blue=EncodePixelGamma(blue);
2422  }
2423  intensity=0.212656*red+0.715158*green+0.072186*blue;
2424  break;
2425  }
2427  {
2428  if (image->colorspace == sRGBColorspace)
2429  {
2430  red=DecodePixelGamma(red);
2431  green=DecodePixelGamma(green);
2432  blue=DecodePixelGamma(blue);
2433  }
2434  intensity=0.212656*red+0.715158*green+0.072186*blue;
2435  break;
2436  }
2438  {
2439  intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2440  sqrt(3.0));
2441  break;
2442  }
2443  }
2444  return(intensity);
2445 }
2446 
2447 /*
2448 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2449 % %
2450 % %
2451 % %
2452 % I m p o r t I m a g e P i x e l s %
2453 % %
2454 % %
2455 % %
2456 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2457 %
2458 % ImportImagePixels() accepts pixel data and stores in the image at the
2459 % location you specify. The method returns MagickTrue on success otherwise
2460 % MagickFalse if an error is encountered. The pixel data can be either char,
2461 % Quantum, short int, unsigned int, unsigned long long, float, or double in
2462 % the order specified by map.
2463 %
2464 % Suppose your want to upload the first scanline of a 640x480 image from
2465 % character data in red-green-blue order:
2466 %
2467 % ImportImagePixels(image,0,0,640,1,"RGB",CharPixel,pixels);
2468 %
2469 % The format of the ImportImagePixels method is:
2470 %
2471 % MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
2472 % const ssize_t y,const size_t width,const size_t height,
2473 % const char *map,const StorageType type,const void *pixels,
2474 % ExceptionInfo *exception)
2475 %
2476 % A description of each parameter follows:
2477 %
2478 % o image: the image.
2479 %
2480 % o x,y,width,height: These values define the perimeter
2481 % of a region of pixels you want to define.
2482 %
2483 % o map: This string reflects the expected ordering of the pixel array.
2484 % It can be any combination or order of R = red, G = green, B = blue,
2485 % A = alpha (0 is transparent), O = opacity (0 is opaque), C = cyan,
2486 % Y = yellow, M = magenta, K = black, I = intensity (for grayscale),
2487 % P = pad.
2488 %
2489 % o type: Define the data type of the pixels. Float and double types are
2490 % normalized to [0..1] otherwise [0..QuantumRange]. Choose from these
2491 % types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
2492 % LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
2493 % QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
2494 %
2495 % o pixels: This array of values contain the pixel components as defined by
2496 % map and type. You must preallocate this array where the expected
2497 % length varies depending on the values of width, height, map, and type.
2498 %
2499 % o exception: return any errors or warnings in this structure.
2500 %
2501 */
2502 
2503 static void ImportCharPixel(Image *image,const RectangleInfo *roi,
2504  const char *magick_restrict map,const QuantumType *quantum_map,
2505  const void *pixels,ExceptionInfo *exception)
2506 {
2507  register const unsigned char
2508  *magick_restrict p;
2509 
2510  register Quantum
2511  *magick_restrict q;
2512 
2513  register ssize_t
2514  x;
2515 
2516  size_t
2517  length;
2518 
2519  ssize_t
2520  y;
2521 
2522  p=(const unsigned char *) pixels;
2523  if (LocaleCompare(map,"BGR") == 0)
2524  {
2525  for (y=0; y < (ssize_t) roi->height; y++)
2526  {
2527  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2528  if (q == (Quantum *) NULL)
2529  break;
2530  for (x=0; x < (ssize_t) roi->width; x++)
2531  {
2532  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2533  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2534  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2535  q+=GetPixelChannels(image);
2536  }
2537  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2538  break;
2539  }
2540  return;
2541  }
2542  if (LocaleCompare(map,"BGRA") == 0)
2543  {
2544  for (y=0; y < (ssize_t) roi->height; y++)
2545  {
2546  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2547  if (q == (Quantum *) NULL)
2548  break;
2549  for (x=0; x < (ssize_t) roi->width; x++)
2550  {
2551  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2552  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2553  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2554  SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2555  q+=GetPixelChannels(image);
2556  }
2557  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2558  break;
2559  }
2560  return;
2561  }
2562  if (LocaleCompare(map,"BGRO") == 0)
2563  {
2564  for (y=0; y < (ssize_t) roi->height; y++)
2565  {
2566  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2567  if (q == (Quantum *) NULL)
2568  break;
2569  for (x=0; x < (ssize_t) roi->width; x++)
2570  {
2571  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2572  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2573  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2574  SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2575  q+=GetPixelChannels(image);
2576  }
2577  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2578  break;
2579  }
2580  return;
2581  }
2582  if (LocaleCompare(map,"BGRP") == 0)
2583  {
2584  for (y=0; y < (ssize_t) roi->height; y++)
2585  {
2586  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2587  if (q == (Quantum *) NULL)
2588  break;
2589  for (x=0; x < (ssize_t) roi->width; x++)
2590  {
2591  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2592  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2593  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2594  p++;
2595  q+=GetPixelChannels(image);
2596  }
2597  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2598  break;
2599  }
2600  return;
2601  }
2602  if (LocaleCompare(map,"I") == 0)
2603  {
2604  for (y=0; y < (ssize_t) roi->height; y++)
2605  {
2606  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2607  if (q == (Quantum *) NULL)
2608  break;
2609  for (x=0; x < (ssize_t) roi->width; x++)
2610  {
2611  SetPixelGray(image,ScaleCharToQuantum(*p++),q);
2612  q+=GetPixelChannels(image);
2613  }
2614  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2615  break;
2616  }
2617  return;
2618  }
2619  if (LocaleCompare(map,"RGB") == 0)
2620  {
2621  for (y=0; y < (ssize_t) roi->height; y++)
2622  {
2623  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2624  if (q == (Quantum *) NULL)
2625  break;
2626  for (x=0; x < (ssize_t) roi->width; x++)
2627  {
2628  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2629  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2630  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2631  q+=GetPixelChannels(image);
2632  }
2633  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2634  break;
2635  }
2636  return;
2637  }
2638  if (LocaleCompare(map,"RGBA") == 0)
2639  {
2640  for (y=0; y < (ssize_t) roi->height; y++)
2641  {
2642  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2643  if (q == (Quantum *) NULL)
2644  break;
2645  for (x=0; x < (ssize_t) roi->width; x++)
2646  {
2647  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2648  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2649  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2650  SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2651  q+=GetPixelChannels(image);
2652  }
2653  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2654  break;
2655  }
2656  return;
2657  }
2658  if (LocaleCompare(map,"RGBO") == 0)
2659  {
2660  for (y=0; y < (ssize_t) roi->height; y++)
2661  {
2662  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2663  if (q == (Quantum *) NULL)
2664  break;
2665  for (x=0; x < (ssize_t) roi->width; x++)
2666  {
2667  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2668  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2669  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2670  SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
2671  q+=GetPixelChannels(image);
2672  }
2673  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2674  break;
2675  }
2676  return;
2677  }
2678  if (LocaleCompare(map,"RGBP") == 0)
2679  {
2680  for (y=0; y < (ssize_t) roi->height; y++)
2681  {
2682  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2683  if (q == (Quantum *) NULL)
2684  break;
2685  for (x=0; x < (ssize_t) roi->width; x++)
2686  {
2687  SetPixelRed(image,ScaleCharToQuantum(*p++),q);
2688  SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
2689  SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
2690  p++;
2691  q+=GetPixelChannels(image);
2692  }
2693  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2694  break;
2695  }
2696  return;
2697  }
2698  length=strlen(map);
2699  for (y=0; y < (ssize_t) roi->height; y++)
2700  {
2701  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2702  if (q == (Quantum *) NULL)
2703  break;
2704  for (x=0; x < (ssize_t) roi->width; x++)
2705  {
2706  register ssize_t
2707  i;
2708 
2709  for (i=0; i < (ssize_t) length; i++)
2710  {
2711  switch (quantum_map[i])
2712  {
2713  case RedQuantum:
2714  case CyanQuantum:
2715  {
2716  SetPixelRed(image,ScaleCharToQuantum(*p),q);
2717  break;
2718  }
2719  case GreenQuantum:
2720  case MagentaQuantum:
2721  {
2722  SetPixelGreen(image,ScaleCharToQuantum(*p),q);
2723  break;
2724  }
2725  case BlueQuantum:
2726  case YellowQuantum:
2727  {
2728  SetPixelBlue(image,ScaleCharToQuantum(*p),q);
2729  break;
2730  }
2731  case AlphaQuantum:
2732  {
2733  SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2734  break;
2735  }
2736  case OpacityQuantum:
2737  {
2738  SetPixelAlpha(image,ScaleCharToQuantum(*p),q);
2739  break;
2740  }
2741  case BlackQuantum:
2742  {
2743  SetPixelBlack(image,ScaleCharToQuantum(*p),q);
2744  break;
2745  }
2746  case IndexQuantum:
2747  {
2748  SetPixelGray(image,ScaleCharToQuantum(*p),q);
2749  break;
2750  }
2751  default:
2752  break;
2753  }
2754  p++;
2755  }
2756  q+=GetPixelChannels(image);
2757  }
2758  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2759  break;
2760  }
2761 }
2762 
2763 static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
2764  const char *magick_restrict map,const QuantumType *quantum_map,
2765  const void *pixels,ExceptionInfo *exception)
2766 {
2767  register const double
2768  *magick_restrict p;
2769 
2770  register Quantum
2771  *magick_restrict q;
2772 
2773  register ssize_t
2774  x;
2775 
2776  size_t
2777  length;
2778 
2779  ssize_t
2780  y;
2781 
2782  p=(const double *) pixels;
2783  if (LocaleCompare(map,"BGR") == 0)
2784  {
2785  for (y=0; y < (ssize_t) roi->height; y++)
2786  {
2787  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2788  if (q == (Quantum *) NULL)
2789  break;
2790  for (x=0; x < (ssize_t) roi->width; x++)
2791  {
2792  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2793  p++;
2794  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2795  p++;
2796  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2797  p++;
2798  q+=GetPixelChannels(image);
2799  }
2800  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2801  break;
2802  }
2803  return;
2804  }
2805  if (LocaleCompare(map,"BGRA") == 0)
2806  {
2807  for (y=0; y < (ssize_t) roi->height; y++)
2808  {
2809  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2810  if (q == (Quantum *) NULL)
2811  break;
2812  for (x=0; x < (ssize_t) roi->width; x++)
2813  {
2814  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2815  p++;
2816  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2817  p++;
2818  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2819  p++;
2820  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2821  p++;
2822  q+=GetPixelChannels(image);
2823  }
2824  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2825  break;
2826  }
2827  return;
2828  }
2829  if (LocaleCompare(map,"BGRP") == 0)
2830  {
2831  for (y=0; y < (ssize_t) roi->height; y++)
2832  {
2833  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2834  if (q == (Quantum *) NULL)
2835  break;
2836  for (x=0; x < (ssize_t) roi->width; x++)
2837  {
2838  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2839  p++;
2840  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2841  p++;
2842  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2843  p++;
2844  p++;
2845  q+=GetPixelChannels(image);
2846  }
2847  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2848  break;
2849  }
2850  return;
2851  }
2852  if (LocaleCompare(map,"I") == 0)
2853  {
2854  for (y=0; y < (ssize_t) roi->height; y++)
2855  {
2856  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2857  if (q == (Quantum *) NULL)
2858  break;
2859  for (x=0; x < (ssize_t) roi->width; x++)
2860  {
2861  SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
2862  p++;
2863  q+=GetPixelChannels(image);
2864  }
2865  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2866  break;
2867  }
2868  return;
2869  }
2870  if (LocaleCompare(map,"RGB") == 0)
2871  {
2872  for (y=0; y < (ssize_t) roi->height; y++)
2873  {
2874  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2875  if (q == (Quantum *) NULL)
2876  break;
2877  for (x=0; x < (ssize_t) roi->width; x++)
2878  {
2879  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2880  p++;
2881  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2882  p++;
2883  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2884  p++;
2885  q+=GetPixelChannels(image);
2886  }
2887  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2888  break;
2889  }
2890  return;
2891  }
2892  if (LocaleCompare(map,"RGBA") == 0)
2893  {
2894  for (y=0; y < (ssize_t) roi->height; y++)
2895  {
2896  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2897  if (q == (Quantum *) NULL)
2898  break;
2899  for (x=0; x < (ssize_t) roi->width; x++)
2900  {
2901  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2902  p++;
2903  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2904  p++;
2905  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2906  p++;
2907  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2908  p++;
2909  q+=GetPixelChannels(image);
2910  }
2911  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2912  break;
2913  }
2914  return;
2915  }
2916  if (LocaleCompare(map,"RGBP") == 0)
2917  {
2918  for (y=0; y < (ssize_t) roi->height; y++)
2919  {
2920  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2921  if (q == (Quantum *) NULL)
2922  break;
2923  for (x=0; x < (ssize_t) roi->width; x++)
2924  {
2925  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2926  p++;
2927  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2928  p++;
2929  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2930  p++;
2931  q+=GetPixelChannels(image);
2932  }
2933  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2934  break;
2935  }
2936  return;
2937  }
2938  length=strlen(map);
2939  for (y=0; y < (ssize_t) roi->height; y++)
2940  {
2941  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
2942  if (q == (Quantum *) NULL)
2943  break;
2944  for (x=0; x < (ssize_t) roi->width; x++)
2945  {
2946  register ssize_t
2947  i;
2948 
2949  for (i=0; i < (ssize_t) length; i++)
2950  {
2951  switch (quantum_map[i])
2952  {
2953  case RedQuantum:
2954  case CyanQuantum:
2955  {
2956  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
2957  break;
2958  }
2959  case GreenQuantum:
2960  case MagentaQuantum:
2961  {
2962  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
2963  break;
2964  }
2965  case BlueQuantum:
2966  case YellowQuantum:
2967  {
2968  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
2969  break;
2970  }
2971  case AlphaQuantum:
2972  {
2973  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2974  break;
2975  }
2976  case OpacityQuantum:
2977  {
2978  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
2979  break;
2980  }
2981  case BlackQuantum:
2982  {
2983  SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
2984  break;
2985  }
2986  case IndexQuantum:
2987  {
2988  SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
2989  break;
2990  }
2991  default:
2992  break;
2993  }
2994  p++;
2995  }
2996  q+=GetPixelChannels(image);
2997  }
2998  if (SyncAuthenticPixels(image,exception) == MagickFalse)
2999  break;
3000  }
3001 }
3002 
3003 static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
3004  const char *magick_restrict map,const QuantumType *quantum_map,
3005  const void *pixels,ExceptionInfo *exception)
3006 {
3007  register const float
3008  *magick_restrict p;
3009 
3010  register Quantum
3011  *magick_restrict q;
3012 
3013  register ssize_t
3014  x;
3015 
3016  size_t
3017  length;
3018 
3019  ssize_t
3020  y;
3021 
3022  p=(const float *) pixels;
3023  if (LocaleCompare(map,"BGR") == 0)
3024  {
3025  for (y=0; y < (ssize_t) roi->height; y++)
3026  {
3027  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3028  if (q == (Quantum *) NULL)
3029  break;
3030  for (x=0; x < (ssize_t) roi->width; x++)
3031  {
3032  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3033  p++;
3034  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3035  p++;
3036  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3037  p++;
3038  q+=GetPixelChannels(image);
3039  }
3040  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3041  break;
3042  }
3043  return;
3044  }
3045  if (LocaleCompare(map,"BGRA") == 0)
3046  {
3047  for (y=0; y < (ssize_t) roi->height; y++)
3048  {
3049  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3050  if (q == (Quantum *) NULL)
3051  break;
3052  for (x=0; x < (ssize_t) roi->width; x++)
3053  {
3054  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3055  p++;
3056  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3057  p++;
3058  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3059  p++;
3060  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3061  p++;
3062  q+=GetPixelChannels(image);
3063  }
3064  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3065  break;
3066  }
3067  return;
3068  }
3069  if (LocaleCompare(map,"BGRP") == 0)
3070  {
3071  for (y=0; y < (ssize_t) roi->height; y++)
3072  {
3073  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3074  if (q == (Quantum *) NULL)
3075  break;
3076  for (x=0; x < (ssize_t) roi->width; x++)
3077  {
3078  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3079  p++;
3080  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3081  p++;
3082  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3083  p++;
3084  p++;
3085  q+=GetPixelChannels(image);
3086  }
3087  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3088  break;
3089  }
3090  return;
3091  }
3092  if (LocaleCompare(map,"I") == 0)
3093  {
3094  for (y=0; y < (ssize_t) roi->height; y++)
3095  {
3096  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3097  if (q == (Quantum *) NULL)
3098  break;
3099  for (x=0; x < (ssize_t) roi->width; x++)
3100  {
3101  SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
3102  p++;
3103  q+=GetPixelChannels(image);
3104  }
3105  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3106  break;
3107  }
3108  return;
3109  }
3110  if (LocaleCompare(map,"RGB") == 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  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3120  p++;
3121  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3122  p++;
3123  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3124  p++;
3125  q+=GetPixelChannels(image);
3126  }
3127  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3128  break;
3129  }
3130  return;
3131  }
3132  if (LocaleCompare(map,"RGBA") == 0)
3133  {
3134  for (y=0; y < (ssize_t) roi->height; y++)
3135  {
3136  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3137  if (q == (Quantum *) NULL)
3138  break;
3139  for (x=0; x < (ssize_t) roi->width; x++)
3140  {
3141  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3142  p++;
3143  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3144  p++;
3145  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3146  p++;
3147  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3148  p++;
3149  q+=GetPixelChannels(image);
3150  }
3151  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3152  break;
3153  }
3154  return;
3155  }
3156  if (LocaleCompare(map,"RGBP") == 0)
3157  {
3158  for (y=0; y < (ssize_t) roi->height; y++)
3159  {
3160  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3161  if (q == (Quantum *) NULL)
3162  break;
3163  for (x=0; x < (ssize_t) roi->width; x++)
3164  {
3165  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3166  p++;
3167  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3168  p++;
3169  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3170  p++;
3171  q+=GetPixelChannels(image);
3172  }
3173  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3174  break;
3175  }
3176  return;
3177  }
3178  length=strlen(map);
3179  for (y=0; y < (ssize_t) roi->height; y++)
3180  {
3181  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3182  if (q == (Quantum *) NULL)
3183  break;
3184  for (x=0; x < (ssize_t) roi->width; x++)
3185  {
3186  register ssize_t
3187  i;
3188 
3189  for (i=0; i < (ssize_t) length; i++)
3190  {
3191  switch (quantum_map[i])
3192  {
3193  case RedQuantum:
3194  case CyanQuantum:
3195  {
3196  SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
3197  break;
3198  }
3199  case GreenQuantum:
3200  case MagentaQuantum:
3201  {
3202  SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
3203  break;
3204  }
3205  case BlueQuantum:
3206  case YellowQuantum:
3207  {
3208  SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
3209  break;
3210  }
3211  case AlphaQuantum:
3212  {
3213  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3214  break;
3215  }
3216  case OpacityQuantum:
3217  {
3218  SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
3219  break;
3220  }
3221  case BlackQuantum:
3222  {
3223  SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
3224  break;
3225  }
3226  case IndexQuantum:
3227  {
3228  SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
3229  break;
3230  }
3231  default:
3232  break;
3233  }
3234  p++;
3235  }
3236  q+=GetPixelChannels(image);
3237  }
3238  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3239  break;
3240  }
3241 }
3242 
3243 static void ImportLongPixel(Image *image,const RectangleInfo *roi,
3244  const char *magick_restrict map,const QuantumType *quantum_map,
3245  const void *pixels,ExceptionInfo *exception)
3246 {
3247  register const unsigned int
3248  *magick_restrict p;
3249 
3250  register Quantum
3251  *magick_restrict q;
3252 
3253  register ssize_t
3254  x;
3255 
3256  size_t
3257  length;
3258 
3259  ssize_t
3260  y;
3261 
3262  p=(const unsigned int *) pixels;
3263  if (LocaleCompare(map,"BGR") == 0)
3264  {
3265  for (y=0; y < (ssize_t) roi->height; y++)
3266  {
3267  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3268  if (q == (Quantum *) NULL)
3269  break;
3270  for (x=0; x < (ssize_t) roi->width; x++)
3271  {
3272  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3273  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3274  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3275  q+=GetPixelChannels(image);
3276  }
3277  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3278  break;
3279  }
3280  return;
3281  }
3282  if (LocaleCompare(map,"BGRA") == 0)
3283  {
3284  for (y=0; y < (ssize_t) roi->height; y++)
3285  {
3286  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3287  if (q == (Quantum *) NULL)
3288  break;
3289  for (x=0; x < (ssize_t) roi->width; x++)
3290  {
3291  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3292  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3293  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3294  SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3295  q+=GetPixelChannels(image);
3296  }
3297  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3298  break;
3299  }
3300  return;
3301  }
3302  if (LocaleCompare(map,"BGRP") == 0)
3303  {
3304  for (y=0; y < (ssize_t) roi->height; y++)
3305  {
3306  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3307  if (q == (Quantum *) NULL)
3308  break;
3309  for (x=0; x < (ssize_t) roi->width; x++)
3310  {
3311  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3312  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3313  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3314  p++;
3315  q+=GetPixelChannels(image);
3316  }
3317  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3318  break;
3319  }
3320  return;
3321  }
3322  if (LocaleCompare(map,"I") == 0)
3323  {
3324  for (y=0; y < (ssize_t) roi->height; y++)
3325  {
3326  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3327  if (q == (Quantum *) NULL)
3328  break;
3329  for (x=0; x < (ssize_t) roi->width; x++)
3330  {
3331  SetPixelGray(image,ScaleLongToQuantum(*p++),q);
3332  q+=GetPixelChannels(image);
3333  }
3334  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3335  break;
3336  }
3337  return;
3338  }
3339  if (LocaleCompare(map,"RGB") == 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  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3349  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3350  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3351  q+=GetPixelChannels(image);
3352  }
3353  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3354  break;
3355  }
3356  return;
3357  }
3358  if (LocaleCompare(map,"RGBA") == 0)
3359  {
3360  for (y=0; y < (ssize_t) roi->height; y++)
3361  {
3362  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3363  if (q == (Quantum *) NULL)
3364  break;
3365  for (x=0; x < (ssize_t) roi->width; x++)
3366  {
3367  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3368  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3369  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3370  SetPixelAlpha(image,ScaleLongToQuantum(*p++),q);
3371  q+=GetPixelChannels(image);
3372  }
3373  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3374  break;
3375  }
3376  return;
3377  }
3378  if (LocaleCompare(map,"RGBP") == 0)
3379  {
3380  for (y=0; y < (ssize_t) roi->height; y++)
3381  {
3382  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3383  if (q == (Quantum *) NULL)
3384  break;
3385  for (x=0; x < (ssize_t) roi->width; x++)
3386  {
3387  SetPixelRed(image,ScaleLongToQuantum(*p++),q);
3388  SetPixelGreen(image,ScaleLongToQuantum(*p++),q);
3389  SetPixelBlue(image,ScaleLongToQuantum(*p++),q);
3390  p++;
3391  q+=GetPixelChannels(image);
3392  }
3393  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3394  break;
3395  }
3396  return;
3397  }
3398  length=strlen(map);
3399  for (y=0; y < (ssize_t) roi->height; y++)
3400  {
3401  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3402  if (q == (Quantum *) NULL)
3403  break;
3404  for (x=0; x < (ssize_t) roi->width; x++)
3405  {
3406  register ssize_t
3407  i;
3408 
3409  for (i=0; i < (ssize_t) length; i++)
3410  {
3411  switch (quantum_map[i])
3412  {
3413  case RedQuantum:
3414  case CyanQuantum:
3415  {
3416  SetPixelRed(image,ScaleLongToQuantum(*p),q);
3417  break;
3418  }
3419  case GreenQuantum:
3420  case MagentaQuantum:
3421  {
3422  SetPixelGreen(image,ScaleLongToQuantum(*p),q);
3423  break;
3424  }
3425  case BlueQuantum:
3426  case YellowQuantum:
3427  {
3428  SetPixelBlue(image,ScaleLongToQuantum(*p),q);
3429  break;
3430  }
3431  case AlphaQuantum:
3432  {
3433  SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3434  break;
3435  }
3436  case OpacityQuantum:
3437  {
3438  SetPixelAlpha(image,ScaleLongToQuantum(*p),q);
3439  break;
3440  }
3441  case BlackQuantum:
3442  {
3443  SetPixelBlack(image,ScaleLongToQuantum(*p),q);
3444  break;
3445  }
3446  case IndexQuantum:
3447  {
3448  SetPixelGray(image,ScaleLongToQuantum(*p),q);
3449  break;
3450  }
3451  default:
3452  break;
3453  }
3454  p++;
3455  }
3456  q+=GetPixelChannels(image);
3457  }
3458  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3459  break;
3460  }
3461 }
3462 
3463 static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
3464  const char *magick_restrict map,const QuantumType *quantum_map,
3465  const void *pixels,ExceptionInfo *exception)
3466 {
3467  register const MagickSizeType
3468  *magick_restrict p;
3469 
3470  register Quantum
3471  *magick_restrict q;
3472 
3473  register ssize_t
3474  x;
3475 
3476  size_t
3477  length;
3478 
3479  ssize_t
3480  y;
3481 
3482  p=(const MagickSizeType *) pixels;
3483  if (LocaleCompare(map,"BGR") == 0)
3484  {
3485  for (y=0; y < (ssize_t) roi->height; y++)
3486  {
3487  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3488  if (q == (Quantum *) NULL)
3489  break;
3490  for (x=0; x < (ssize_t) roi->width; x++)
3491  {
3492  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3493  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3494  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3495  q+=GetPixelChannels(image);
3496  }
3497  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3498  break;
3499  }
3500  return;
3501  }
3502  if (LocaleCompare(map,"BGRA") == 0)
3503  {
3504  for (y=0; y < (ssize_t) roi->height; y++)
3505  {
3506  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3507  if (q == (Quantum *) NULL)
3508  break;
3509  for (x=0; x < (ssize_t) roi->width; x++)
3510  {
3511  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3512  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3513  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3514  SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3515  q+=GetPixelChannels(image);
3516  }
3517  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3518  break;
3519  }
3520  return;
3521  }
3522  if (LocaleCompare(map,"BGRP") == 0)
3523  {
3524  for (y=0; y < (ssize_t) roi->height; y++)
3525  {
3526  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3527  if (q == (Quantum *) NULL)
3528  break;
3529  for (x=0; x < (ssize_t) roi->width; x++)
3530  {
3531  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3532  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3533  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3534  p++;
3535  q+=GetPixelChannels(image);
3536  }
3537  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3538  break;
3539  }
3540  return;
3541  }
3542  if (LocaleCompare(map,"I") == 0)
3543  {
3544  for (y=0; y < (ssize_t) roi->height; y++)
3545  {
3546  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3547  if (q == (Quantum *) NULL)
3548  break;
3549  for (x=0; x < (ssize_t) roi->width; x++)
3550  {
3551  SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
3552  q+=GetPixelChannels(image);
3553  }
3554  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3555  break;
3556  }
3557  return;
3558  }
3559  if (LocaleCompare(map,"RGB") == 0)
3560  {
3561  for (y=0; y < (ssize_t) roi->height; y++)
3562  {
3563  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3564  if (q == (Quantum *) NULL)
3565  break;
3566  for (x=0; x < (ssize_t) roi->width; x++)
3567  {
3568  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3569  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3570  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3571  q+=GetPixelChannels(image);
3572  }
3573  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3574  break;
3575  }
3576  return;
3577  }
3578  if (LocaleCompare(map,"RGBA") == 0)
3579  {
3580  for (y=0; y < (ssize_t) roi->height; y++)
3581  {
3582  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3583  if (q == (Quantum *) NULL)
3584  break;
3585  for (x=0; x < (ssize_t) roi->width; x++)
3586  {
3587  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3588  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3589  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3590  SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
3591  q+=GetPixelChannels(image);
3592  }
3593  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3594  break;
3595  }
3596  return;
3597  }
3598  if (LocaleCompare(map,"RGBP") == 0)
3599  {
3600  for (y=0; y < (ssize_t) roi->height; y++)
3601  {
3602  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3603  if (q == (Quantum *) NULL)
3604  break;
3605  for (x=0; x < (ssize_t) roi->width; x++)
3606  {
3607  SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3608  SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3609  SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3610  p++;
3611  q+=GetPixelChannels(image);
3612  }
3613  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3614  break;
3615  }
3616  return;
3617  }
3618  length=strlen(map);
3619  for (y=0; y < (ssize_t) roi->height; y++)
3620  {
3621  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3622  if (q == (Quantum *) NULL)
3623  break;
3624  for (x=0; x < (ssize_t) roi->width; x++)
3625  {
3626  register ssize_t
3627  i;
3628 
3629  for (i=0; i < (ssize_t) length; i++)
3630  {
3631  switch (quantum_map[i])
3632  {
3633  case RedQuantum:
3634  case CyanQuantum:
3635  {
3636  SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
3637  break;
3638  }
3639  case GreenQuantum:
3640  case MagentaQuantum:
3641  {
3642  SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
3643  break;
3644  }
3645  case BlueQuantum:
3646  case YellowQuantum:
3647  {
3648  SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
3649  break;
3650  }
3651  case AlphaQuantum:
3652  {
3653  SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3654  break;
3655  }
3656  case OpacityQuantum:
3657  {
3658  SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
3659  break;
3660  }
3661  case BlackQuantum:
3662  {
3663  SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
3664  break;
3665  }
3666  case IndexQuantum:
3667  {
3668  SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
3669  break;
3670  }
3671  default:
3672  break;
3673  }
3674  p++;
3675  }
3676  q+=GetPixelChannels(image);
3677  }
3678  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3679  break;
3680  }
3681 }
3682 
3683 static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
3684  const char *magick_restrict map,const QuantumType *quantum_map,
3685  const void *pixels,ExceptionInfo *exception)
3686 {
3687  register const Quantum
3688  *magick_restrict p;
3689 
3690  register Quantum
3691  *magick_restrict q;
3692 
3693  register ssize_t
3694  x;
3695 
3696  size_t
3697  length;
3698 
3699  ssize_t
3700  y;
3701 
3702  p=(const Quantum *) pixels;
3703  if (LocaleCompare(map,"BGR") == 0)
3704  {
3705  for (y=0; y < (ssize_t) roi->height; y++)
3706  {
3707  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3708  if (q == (Quantum *) NULL)
3709  break;
3710  for (x=0; x < (ssize_t) roi->width; x++)
3711  {
3712  SetPixelBlue(image,*p++,q);
3713  SetPixelGreen(image,*p++,q);
3714  SetPixelRed(image,*p++,q);
3715  q+=GetPixelChannels(image);
3716  }
3717  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3718  break;
3719  }
3720  return;
3721  }
3722  if (LocaleCompare(map,"BGRA") == 0)
3723  {
3724  for (y=0; y < (ssize_t) roi->height; y++)
3725  {
3726  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3727  if (q == (Quantum *) NULL)
3728  break;
3729  for (x=0; x < (ssize_t) roi->width; x++)
3730  {
3731  SetPixelBlue(image,*p++,q);
3732  SetPixelGreen(image,*p++,q);
3733  SetPixelRed(image,*p++,q);
3734  SetPixelAlpha(image,*p++,q);
3735  q+=GetPixelChannels(image);
3736  }
3737  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3738  break;
3739  }
3740  return;
3741  }
3742  if (LocaleCompare(map,"BGRP") == 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  p++;
3755  q+=GetPixelChannels(image);
3756  }
3757  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3758  break;
3759  }
3760  return;
3761  }
3762  if (LocaleCompare(map,"I") == 0)
3763  {
3764  for (y=0; y < (ssize_t) roi->height; y++)
3765  {
3766  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3767  if (q == (Quantum *) NULL)
3768  break;
3769  for (x=0; x < (ssize_t) roi->width; x++)
3770  {
3771  SetPixelGray(image,*p++,q);
3772  q+=GetPixelChannels(image);
3773  }
3774  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3775  break;
3776  }
3777  return;
3778  }
3779  if (LocaleCompare(map,"RGB") == 0)
3780  {
3781  for (y=0; y < (ssize_t) roi->height; y++)
3782  {
3783  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3784  if (q == (Quantum *) NULL)
3785  break;
3786  for (x=0; x < (ssize_t) roi->width; x++)
3787  {
3788  SetPixelRed(image,*p++,q);
3789  SetPixelGreen(image,*p++,q);
3790  SetPixelBlue(image,*p++,q);
3791  q+=GetPixelChannels(image);
3792  }
3793  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3794  break;
3795  }
3796  return;
3797  }
3798  if (LocaleCompare(map,"RGBA") == 0)
3799  {
3800  for (y=0; y < (ssize_t) roi->height; y++)
3801  {
3802  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3803  if (q == (Quantum *) NULL)
3804  break;
3805  for (x=0; x < (ssize_t) roi->width; x++)
3806  {
3807  SetPixelRed(image,*p++,q);
3808  SetPixelGreen(image,*p++,q);
3809  SetPixelBlue(image,*p++,q);
3810  SetPixelAlpha(image,*p++,q);
3811  q+=GetPixelChannels(image);
3812  }
3813  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3814  break;
3815  }
3816  return;
3817  }
3818  if (LocaleCompare(map,"RGBP") == 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  p++;
3831  q+=GetPixelChannels(image);
3832  }
3833  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3834  break;
3835  }
3836  return;
3837  }
3838  length=strlen(map);
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  register ssize_t
3847  i;
3848 
3849  for (i=0; i < (ssize_t) length; i++)
3850  {
3851  switch (quantum_map[i])
3852  {
3853  case RedQuantum:
3854  case CyanQuantum:
3855  {
3856  SetPixelRed(image,*p,q);
3857  break;
3858  }
3859  case GreenQuantum:
3860  case MagentaQuantum:
3861  {
3862  SetPixelGreen(image,*p,q);
3863  break;
3864  }
3865  case BlueQuantum:
3866  case YellowQuantum:
3867  {
3868  SetPixelBlue(image,*p,q);
3869  break;
3870  }
3871  case AlphaQuantum:
3872  {
3873  SetPixelAlpha(image,*p,q);
3874  break;
3875  }
3876  case OpacityQuantum:
3877  {
3878  SetPixelAlpha(image,*p,q);
3879  break;
3880  }
3881  case BlackQuantum:
3882  {
3883  SetPixelBlack(image,*p,q);
3884  break;
3885  }
3886  case IndexQuantum:
3887  {
3888  SetPixelGray(image,*p,q);
3889  break;
3890  }
3891  default:
3892  break;
3893  }
3894  p++;
3895  }
3896  q+=GetPixelChannels(image);
3897  }
3898  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3899  break;
3900  }
3901 }
3902 
3903 static void ImportShortPixel(Image *image,const RectangleInfo *roi,
3904  const char *magick_restrict map,const QuantumType *quantum_map,
3905  const void *pixels,ExceptionInfo *exception)
3906 {
3907  register const unsigned short
3908  *magick_restrict p;
3909 
3910  register Quantum
3911  *magick_restrict q;
3912 
3913  register ssize_t
3914  x;
3915 
3916  size_t
3917  length;
3918 
3919  ssize_t
3920  y;
3921 
3922  p=(const unsigned short *) pixels;
3923  if (LocaleCompare(map,"BGR") == 0)
3924  {
3925  for (y=0; y < (ssize_t) roi->height; y++)
3926  {
3927  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3928  if (q == (Quantum *) NULL)
3929  break;
3930  for (x=0; x < (ssize_t) roi->width; x++)
3931  {
3932  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3933  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3934  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3935  q+=GetPixelChannels(image);
3936  }
3937  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3938  break;
3939  }
3940  return;
3941  }
3942  if (LocaleCompare(map,"BGRA") == 0)
3943  {
3944  for (y=0; y < (ssize_t) roi->height; y++)
3945  {
3946  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3947  if (q == (Quantum *) NULL)
3948  break;
3949  for (x=0; x < (ssize_t) roi->width; x++)
3950  {
3951  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3952  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3953  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3954  SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
3955  q+=GetPixelChannels(image);
3956  }
3957  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3958  break;
3959  }
3960  return;
3961  }
3962  if (LocaleCompare(map,"BGRP") == 0)
3963  {
3964  for (y=0; y < (ssize_t) roi->height; y++)
3965  {
3966  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
3967  if (q == (Quantum *) NULL)
3968  break;
3969  for (x=0; x < (ssize_t) roi->width; x++)
3970  {
3971  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
3972  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
3973  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
3974  p++;
3975  q+=GetPixelChannels(image);
3976  }
3977  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3978  break;
3979  }
3980  return;
3981  }
3982  if (LocaleCompare(map,"I") == 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  SetPixelGray(image,ScaleShortToQuantum(*p++),q);
3992  q+=GetPixelChannels(image);
3993  }
3994  if (SyncAuthenticPixels(image,exception) == MagickFalse)
3995  break;
3996  }
3997  return;
3998  }
3999  if (LocaleCompare(map,"RGB") == 0)
4000  {
4001  for (y=0; y < (ssize_t) roi->height; y++)
4002  {
4003  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4004  if (q == (Quantum *) NULL)
4005  break;
4006  for (x=0; x < (ssize_t) roi->width; x++)
4007  {
4008  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4009  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4010  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4011  q+=GetPixelChannels(image);
4012  }
4013  if (SyncAuthenticPixels(image,exception) == MagickFalse)
4014  break;
4015  }
4016  return;
4017  }
4018  if (LocaleCompare(map,"RGBA") == 0)
4019  {
4020  for (y=0; y < (ssize_t) roi->height; y++)
4021  {
4022  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4023  if (q == (Quantum *) NULL)
4024  break;
4025  for (x=0; x < (ssize_t) roi->width; x++)
4026  {
4027  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4028  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4029  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4030  SetPixelAlpha(image,ScaleShortToQuantum(*p++),q);
4031  q+=GetPixelChannels(image);
4032  }
4033  if (SyncAuthenticPixels(image,exception) == MagickFalse)
4034  break;
4035  }
4036  return;
4037  }
4038  if (LocaleCompare(map,"RGBP") == 0)
4039  {
4040  for (y=0; y < (ssize_t) roi->height; y++)
4041  {
4042  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4043  if (q == (Quantum *) NULL)
4044  break;
4045  for (x=0; x < (ssize_t) roi->width; x++)
4046  {
4047  SetPixelRed(image,ScaleShortToQuantum(*p++),q);
4048  SetPixelGreen(image,ScaleShortToQuantum(*p++),q);
4049  SetPixelBlue(image,ScaleShortToQuantum(*p++),q);
4050  p++;
4051  q+=GetPixelChannels(image);
4052  }
4053  if (SyncAuthenticPixels(image,exception) == MagickFalse)
4054  break;
4055  }
4056  return;
4057  }
4058  length=strlen(map);
4059  for (y=0; y < (ssize_t) roi->height; y++)
4060  {
4061  q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
4062  if (q == (Quantum *) NULL)
4063  break;
4064  for (x=0; x < (ssize_t) roi->width; x++)
4065  {
4066  register ssize_t
4067  i;
4068 
4069  for (i=0; i < (ssize_t) length; i++)
4070  {
4071  switch (quantum_map[i])
4072  {
4073  case RedQuantum:
4074  case CyanQuantum:
4075  {
4076  SetPixelRed(image,ScaleShortToQuantum(*p),q);
4077  break;
4078  }
4079  case GreenQuantum:
4080  case MagentaQuantum:
4081  {
4082  SetPixelGreen(image,ScaleShortToQuantum(*p),q);
4083  break;
4084  }
4085  case BlueQuantum:
4086  case YellowQuantum:
4087  {
4088  SetPixelBlue(image,ScaleShortToQuantum(*p),q);
4089  break;
4090  }
4091  case AlphaQuantum:
4092  {
4093  SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
4094  break;
4095  }
4096  case OpacityQuantum:
4097  {
4098  SetPixelAlpha(image,ScaleShortToQuantum(*p),q);
4099  break;
4100  }
4101  case BlackQuantum:
4102  {
4103  SetPixelBlack(image,ScaleShortToQuantum(*p),q);
4104  break;
4105  }
4106  case IndexQuantum:
4107  {
4108  SetPixelGray(image,ScaleShortToQuantum(*p),q);
4109  break;
4110  }
4111  default:
4112  break;
4113  }
4114  p++;
4115  }
4116  q+=GetPixelChannels(image);
4117  }
4118  if (SyncAuthenticPixels(image,exception) == MagickFalse)
4119  break;
4120  }
4121 }
4122 
4124  const ssize_t y,const size_t width,const size_t height,const char *map,
4125  const StorageType type,const void *pixels,ExceptionInfo *exception)
4126 {
4127  QuantumType
4128  *quantum_map;
4129 
4131  roi;
4132 
4133  register ssize_t
4134  i;
4135 
4136  size_t
4137  length;
4138 
4139  /*
4140  Allocate image structure.
4141  */
4142  assert(image != (Image *) NULL);
4143  assert(image->signature == MagickCoreSignature);
4144  if (image->debug != MagickFalse)
4145  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
4146  length=strlen(map);
4147  quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
4148  if (quantum_map == (QuantumType *) NULL)
4149  ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4150  image->filename);
4151  for (i=0; i < (ssize_t) length; i++)
4152  {
4153  switch (map[i])
4154  {
4155  case 'a':
4156  case 'A':
4157  {
4158  quantum_map[i]=AlphaQuantum;
4160  break;
4161  }
4162  case 'B':
4163  case 'b':
4164  {
4165  quantum_map[i]=BlueQuantum;
4166  break;
4167  }
4168  case 'C':
4169  case 'c':
4170  {
4171  quantum_map[i]=CyanQuantum;
4172  (void) SetImageColorspace(image,CMYKColorspace,exception);
4173  break;
4174  }
4175  case 'g':
4176  case 'G':
4177  {
4178  quantum_map[i]=GreenQuantum;
4179  break;
4180  }
4181  case 'K':
4182  case 'k':
4183  {
4184  quantum_map[i]=BlackQuantum;
4185  (void) SetImageColorspace(image,CMYKColorspace,exception);
4186  break;
4187  }
4188  case 'I':
4189  case 'i':
4190  {
4191  quantum_map[i]=IndexQuantum;
4192  (void) SetImageColorspace(image,GRAYColorspace,exception);
4193  break;
4194  }
4195  case 'm':
4196  case 'M':
4197  {
4198  quantum_map[i]=MagentaQuantum;
4199  (void) SetImageColorspace(image,CMYKColorspace,exception);
4200  break;
4201  }
4202  case 'O':
4203  case 'o':
4204  {
4205  quantum_map[i]=OpacityQuantum;
4207  break;
4208  }
4209  case 'P':
4210  case 'p':
4211  {
4212  quantum_map[i]=UndefinedQuantum;
4213  break;
4214  }
4215  case 'R':
4216  case 'r':
4217  {
4218  quantum_map[i]=RedQuantum;
4219  break;
4220  }
4221  case 'Y':
4222  case 'y':
4223  {
4224  quantum_map[i]=YellowQuantum;
4225  (void) SetImageColorspace(image,CMYKColorspace,exception);
4226  break;
4227  }
4228  default:
4229  {
4230  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4232  "UnrecognizedPixelMap","`%s'",map);
4233  return(MagickFalse);
4234  }
4235  }
4236  }
4237  if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
4238  return(MagickFalse);
4239  /*
4240  Transfer the pixels from the pixel data to the image.
4241  */
4242  roi.width=width;
4243  roi.height=height;
4244  roi.x=x;
4245  roi.y=y;
4246  switch (type)
4247  {
4248  case CharPixel:
4249  {
4250  ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
4251  break;
4252  }
4253  case DoublePixel:
4254  {
4255  ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
4256  break;
4257  }
4258  case FloatPixel:
4259  {
4260  ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
4261  break;
4262  }
4263  case LongPixel:
4264  {
4265  ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
4266  break;
4267  }
4268  case LongLongPixel:
4269  {
4270  ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
4271  break;
4272  }
4273  case QuantumPixel:
4274  {
4275  ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
4276  break;
4277  }
4278  case ShortPixel:
4279  {
4280  ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
4281  break;
4282  }
4283  default:
4284  {
4285  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4287  "UnrecognizedStorageType","`%d'",type);
4288  break;
4289  }
4290  }
4291  quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4292  return(MagickTrue);
4293 }
4294 
4295 /*
4296 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4297 % %
4298 % %
4299 % %
4300 + I n i t i a l i z e P i x e l C h a n n e l M a p %
4301 % %
4302 % %
4303 % %
4304 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4305 %
4306 % InitializePixelChannelMap() defines the standard pixel component map.
4307 %
4308 % The format of the InitializePixelChannelMap() method is:
4309 %
4310 % void InitializePixelChannelMap(Image *image)
4311 %
4312 % A description of each parameter follows:
4313 %
4314 % o image: the image.
4315 %
4316 */
4318 {
4319  PixelTrait
4320  trait;
4321 
4322  register ssize_t
4323  i;
4324 
4325  ssize_t
4326  n;
4327 
4328  assert(image != (Image *) NULL);
4329  assert(image->signature == MagickCoreSignature);
4331  sizeof(*image->channel_map));
4332  trait=UpdatePixelTrait;
4333  if (image->alpha_trait != UndefinedPixelTrait)
4334  trait=(PixelTrait) (trait | BlendPixelTrait);
4335  n=0;
4336  if (image->colorspace == GRAYColorspace)
4337  {
4340  SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
4341  }
4342  else
4343  {
4344  SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
4347  }
4348  if (image->colorspace == CMYKColorspace)
4350  for (i=0; i < (ssize_t) image->number_meta_channels; i++)
4351  {
4353  n++;
4354  }
4355  if (image->alpha_trait != UndefinedPixelTrait)
4357  if (image->storage_class == PseudoClass)
4359  if (image->read_mask != MagickFalse)
4361  if (image->write_mask != MagickFalse)
4363  image->number_channels=(size_t) n;
4364  (void) SetPixelChannelMask(image,image->channel_mask);
4365 }
4366 
4367 /*
4368 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369 % %
4370 % %
4371 % %
4372 % I n t e r p o l a t e P i x e l C h a n n e l %
4373 % %
4374 % %
4375 % %
4376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4377 %
4378 % InterpolatePixelChannel() applies a pixel interpolation method between a
4379 % floating point coordinate and the pixels surrounding that coordinate. No
4380 % pixel area resampling, or scaling of the result is performed.
4381 %
4382 % Interpolation is restricted to just the specified channel.
4383 %
4384 % The format of the InterpolatePixelChannel method is:
4385 %
4386 % MagickBooleanType InterpolatePixelChannel(const Image *image,
4387 % const CacheView *image_view,const PixelChannel channel,
4388 % const PixelInterpolateMethod method,const double x,const double y,
4389 % double *pixel,ExceptionInfo *exception)
4390 %
4391 % A description of each parameter follows:
4392 %
4393 % o image: the image.
4394 %
4395 % o image_view: the image view.
4396 %
4397 % o channel: the pixel channel to interpolate.
4398 %
4399 % o method: the pixel color interpolation method.
4400 %
4401 % o x,y: A double representing the current (x,y) position of the pixel.
4402 %
4403 % o pixel: return the interpolated pixel here.
4404 %
4405 % o exception: return any errors or warnings in this structure.
4406 %
4407 */
4408 
4409 static inline void CatromWeights(const double x,double (*weights)[4])
4410 {
4411  double
4412  alpha,
4413  beta,
4414  gamma;
4415 
4416  /*
4417  Nicolas Robidoux' 10 flops (4* + 5- + 1+) refactoring of the computation
4418  of the standard four 1D Catmull-Rom weights. The sampling location is
4419  assumed between the second and third input pixel locations, and x is the
4420  position relative to the second input pixel location. Formulas originally
4421  derived for the VIPS (Virtual Image Processing System) library.
4422  */
4423  alpha=(double) 1.0-x;
4424  beta=(double) (-0.5)*x*alpha;
4425  (*weights)[0]=alpha*beta;
4426  (*weights)[3]=x*beta;
4427  /*
4428  The following computation of the inner weights from the outer ones work
4429  for all Keys cubics.
4430  */
4431  gamma=(*weights)[3]-(*weights)[0];
4432  (*weights)[1]=alpha-(*weights)[0]+gamma;
4433  (*weights)[2]=x-(*weights)[3]-gamma;
4434 }
4435 
4436 static inline void SplineWeights(const double x,double (*weights)[4])
4437 {
4438  double
4439  alpha,
4440  beta;
4441 
4442  /*
4443  Nicolas Robidoux' 12 flops (6* + 5- + 1+) refactoring of the computation
4444  of the standard four 1D cubic B-spline smoothing weights. The sampling
4445  location is assumed between the second and third input pixel locations,
4446  and x is the position relative to the second input pixel location.
4447  */
4448  alpha=(double) 1.0-x;
4449  (*weights)[3]=(double) (1.0/6.0)*x*x*x;
4450  (*weights)[0]=(double) (1.0/6.0)*alpha*alpha*alpha;
4451  beta=(*weights)[3]-(*weights)[0];
4452  (*weights)[1]=alpha-(*weights)[0]+beta;
4453  (*weights)[2]=x-(*weights)[3]-beta;
4454 }
4455 
4456 static inline double MeshInterpolate(const PointInfo *delta,const double p,
4457  const double x,const double y)
4458 {
4459  return(delta->x*x+delta->y*y+(1.0-delta->x-delta->y)*p);
4460 }
4461 
4462 /*
4463 static inline ssize_t NearestNeighbor(const double x)
4464 {
4465  if (x >= 0.0)
4466  return((ssize_t) (x+0.5));
4467  return((ssize_t) (x-0.5));
4468 }
4469 */
4470 
4472  const CacheView_ *image_view,const PixelChannel channel,
4473  const PixelInterpolateMethod method,const double x,const double y,
4474  double *pixel,ExceptionInfo *exception)
4475 {
4476  double
4477  alpha[16],
4478  gamma,
4479  pixels[16];
4480 
4482  status;
4483 
4485  interpolate;
4486 
4487  PixelTrait
4488  traits;
4489 
4490  register const Quantum
4491  *p;
4492 
4493  register ssize_t
4494  i;
4495 
4496  ssize_t
4497  x_offset,
4498  y_offset;
4499 
4500  assert(image != (Image *) NULL);
4501  assert(image->signature == MagickCoreSignature);
4502  assert(image_view != (CacheView *) NULL);
4503  status=MagickTrue;
4504  *pixel=0.0;
4505  traits=GetPixelChannelTraits(image,channel);
4506  x_offset=(ssize_t) floor(x);
4507  y_offset=(ssize_t) floor(y);
4508  interpolate=method;
4509  if (interpolate == UndefinedInterpolatePixel)
4510  interpolate=image->interpolate;
4511  switch (interpolate)
4512  {
4513  case AverageInterpolatePixel: /* nearest 4 neighbours */
4514  case Average9InterpolatePixel: /* nearest 9 neighbours */
4515  case Average16InterpolatePixel: /* nearest 16 neighbours */
4516  {
4517  ssize_t
4518  count;
4519 
4520  count=2; /* size of the area to average - default nearest 4 */
4521  if (interpolate == Average9InterpolatePixel)
4522  {
4523  count=3;
4524  x_offset=(ssize_t) (floor(x+0.5)-1);
4525  y_offset=(ssize_t) (floor(y+0.5)-1);
4526  }
4527  else
4528  if (interpolate == Average16InterpolatePixel)
4529  {
4530  count=4;
4531  x_offset--;
4532  y_offset--;
4533  }
4534  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
4535  (size_t) count,exception);
4536  if (p == (const Quantum *) NULL)
4537  {
4538  status=MagickFalse;
4539  break;
4540  }
4541  count*=count; /* Number of pixels to average */
4542  if ((traits & BlendPixelTrait) == 0)
4543  for (i=0; i < (ssize_t) count; i++)
4544  {
4545  alpha[i]=1.0;
4546  pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4547  }
4548  else
4549  for (i=0; i < (ssize_t) count; i++)
4550  {
4551  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4552  GetPixelChannels(image));
4553  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4554  }
4555  for (i=0; i < (ssize_t) count; i++)
4556  {
4557  gamma=PerceptibleReciprocal(alpha[i])/count;
4558  *pixel+=gamma*pixels[i];
4559  }
4560  break;
4561  }
4563  default:
4564  {
4565  PointInfo
4566  delta,
4567  epsilon;
4568 
4569  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4570  if (p == (const Quantum *) NULL)
4571  {
4572  status=MagickFalse;
4573  break;
4574  }
4575  if ((traits & BlendPixelTrait) == 0)
4576  for (i=0; i < 4; i++)
4577  {
4578  alpha[i]=1.0;
4579  pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4580  }
4581  else
4582  for (i=0; i < 4; i++)
4583  {
4584  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4585  GetPixelChannels(image));
4586  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4587  }
4588  delta.x=x-x_offset;
4589  delta.y=y-y_offset;
4590  epsilon.x=1.0-delta.x;
4591  epsilon.y=1.0-delta.y;
4592  gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
4593  (epsilon.x*alpha[2]+delta.x*alpha[3])));
4594  gamma=PerceptibleReciprocal(gamma);
4595  *pixel=gamma*(epsilon.y*(epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*
4596  (epsilon.x*pixels[2]+delta.x*pixels[3]));
4597  break;
4598  }
4599  case BlendInterpolatePixel:
4600  {
4601  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4602  if (p == (const Quantum *) NULL)
4603  {
4604  status=MagickFalse;
4605  break;
4606  }
4607  if ((traits & BlendPixelTrait) == 0)
4608  for (i=0; i < 4; i++)
4609  {
4610  alpha[i]=1.0;
4611  pixels[i]=(MagickRealType) p[i*GetPixelChannels(image)+channel];
4612  }
4613  else
4614  for (i=0; i < 4; i++)
4615  {
4616  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4617  GetPixelChannels(image));
4618  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4619  }
4620  gamma=1.0; /* number of pixels blended together (its variable) */
4621  for (i=0; i <= 1L; i++) {
4622  if ((y-y_offset) >= 0.75)
4623  {
4624  alpha[i]=alpha[i+2]; /* take right pixels */
4625  pixels[i]=pixels[i+2];
4626  }
4627  else
4628  if ((y-y_offset) > 0.25)
4629  {
4630  gamma=2.0; /* blend both pixels in row */
4631  alpha[i]+=alpha[i+2]; /* add up alpha weights */
4632  pixels[i]+=pixels[i+2];
4633  }
4634  }
4635  if ((x-x_offset) >= 0.75)
4636  {
4637  alpha[0]=alpha[1]; /* take bottom row blend */
4638  pixels[0]=pixels[1];
4639  }
4640  else
4641  if ((x-x_offset) > 0.25)
4642  {
4643  gamma*=2.0; /* blend both rows */
4644  alpha[0]+=alpha[1]; /* add up alpha weights */
4645  pixels[0]+=pixels[1];
4646  }
4647  if (channel != AlphaPixelChannel)
4648  gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
4649  else
4650  gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
4651  *pixel=gamma*pixels[0];
4652  break;
4653  }
4655  {
4656  double
4657  cx[4],
4658  cy[4];
4659 
4660  p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4661  exception);
4662  if (p == (const Quantum *) NULL)
4663  {
4664  status=MagickFalse;
4665  break;
4666  }
4667  if ((traits & BlendPixelTrait) == 0)
4668  for (i=0; i < 16; i++)
4669  {
4670  alpha[i]=1.0;
4671  pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4672  }
4673  else
4674  for (i=0; i < 16; i++)
4675  {
4676  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4677  GetPixelChannels(image));
4678  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4679  }
4680  CatromWeights((double) (x-x_offset),&cx);
4681  CatromWeights((double) (y-y_offset),&cy);
4682  gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4683  PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4684  alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4685  alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4686  alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4687  cx[2]*alpha[14]+cx[3]*alpha[15])));
4688  *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4689  cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4690  pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4691  cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4692  pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4693  break;
4694  }
4696  {
4697  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4698  if (p == (const Quantum *) NULL)
4699  {
4700  status=MagickFalse;
4701  break;
4702  }
4703  *pixel=(double) GetPixelChannel(image,channel,p);
4704  break;
4705  }
4707  {
4708  x_offset=(ssize_t) floor(x+0.5);
4709  y_offset=(ssize_t) floor(y+0.5);
4710  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
4711  if (p == (const Quantum *) NULL)
4712  {
4713  status=MagickFalse;
4714  break;
4715  }
4716  *pixel=(double) GetPixelChannel(image,channel,p);
4717  break;
4718  }
4719  case MeshInterpolatePixel:
4720  {
4721  PointInfo
4722  delta,
4723  luminance;
4724 
4725  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
4726  if (p == (const Quantum *) NULL)
4727  {
4728  status=MagickFalse;
4729  break;
4730  }
4731  if ((traits & BlendPixelTrait) == 0)
4732  for (i=0; i < 4; i++)
4733  {
4734  alpha[i]=1.0;
4735  pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4736  }
4737  else
4738  for (i=0; i < 4; i++)
4739  {
4740  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4741  GetPixelChannels(image));
4742  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4743  }
4744  delta.x=x-x_offset;
4745  delta.y=y-y_offset;
4746  luminance.x=GetPixelLuma(image,p)-(double)
4747  GetPixelLuma(image,p+3*GetPixelChannels(image));
4748  luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
4749  GetPixelLuma(image,p+2*GetPixelChannels(image));
4750  if (fabs(luminance.x) < fabs(luminance.y))
4751  {
4752  /*
4753  Diagonal 0-3 NW-SE.
4754  */
4755  if (delta.x <= delta.y)
4756  {
4757  /*
4758  Bottom-left triangle (pixel: 2, diagonal: 0-3).
4759  */
4760  delta.y=1.0-delta.y;
4761  gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
4762  gamma=PerceptibleReciprocal(gamma);
4763  *pixel=gamma*MeshInterpolate(&delta,pixels[2],pixels[3],
4764  pixels[0]);
4765  }
4766  else
4767  {
4768  /*
4769  Top-right triangle (pixel: 1, diagonal: 0-3).
4770  */
4771  delta.x=1.0-delta.x;
4772  gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
4773  gamma=PerceptibleReciprocal(gamma);
4774  *pixel=gamma*MeshInterpolate(&delta,pixels[1],pixels[0],
4775  pixels[3]);
4776  }
4777  }
4778  else
4779  {
4780  /*
4781  Diagonal 1-2 NE-SW.
4782  */
4783  if (delta.x <= (1.0-delta.y))
4784  {
4785  /*
4786  Top-left triangle (pixel: 0, diagonal: 1-2).
4787  */
4788  gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
4789  gamma=PerceptibleReciprocal(gamma);
4790  *pixel=gamma*MeshInterpolate(&delta,pixels[0],pixels[1],
4791  pixels[2]);
4792  }
4793  else
4794  {
4795  /*
4796  Bottom-right triangle (pixel: 3, diagonal: 1-2).
4797  */
4798  delta.x=1.0-delta.x;
4799  delta.y=1.0-delta.y;
4800  gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
4801  gamma=PerceptibleReciprocal(gamma);
4802  *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4803  pixels[1]);
4804  }
4805  }
4806  break;
4807  }
4809  {
4810  double
4811  cx[4],
4812  cy[4];
4813 
4814  p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
4815  exception);
4816  if (p == (const Quantum *) NULL)
4817  {
4818  status=MagickFalse;
4819  break;
4820  }
4821  if ((traits & BlendPixelTrait) == 0)
4822  for (i=0; i < 16; i++)
4823  {
4824  alpha[i]=1.0;
4825  pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
4826  }
4827  else
4828  for (i=0; i < 16; i++)
4829  {
4830  alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4831  GetPixelChannels(image));
4832  pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4833  }
4834  SplineWeights((double) (x-x_offset),&cx);
4835  SplineWeights((double) (y-y_offset),&cy);
4836  gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
4837  PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
4838  alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
4839  alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
4840  alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
4841  cx[2]*alpha[14]+cx[3]*alpha[15])));
4842  *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
4843  cx[3]*pixels[3])+cy[1]*(cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*
4844  pixels[6]+cx[3]*pixels[7])+cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+
4845  cx[2]*pixels[10]+cx[3]*pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*
4846  pixels[13]+cx[2]*pixels[14]+cx[3]*pixels[15]));
4847  break;
4848  }
4849  }
4850  return(status);
4851 }
4852 
4853 /*
4854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4855 % %
4856 % %
4857 % %
4858 % I n t e r p o l a t e P i x e l C h a n n e l s %
4859 % %
4860 % %
4861 % %
4862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4863 %
4864 % InterpolatePixelChannels() applies a pixel interpolation method between a
4865 % floating point coordinate and the pixels surrounding that coordinate. No
4866 % pixel area resampling, or scaling of the result is performed.
4867 %
4868 % Interpolation is restricted to just the current channel setting of the
4869 % destination image into which the color is to be stored
4870 %
4871 % The format of the InterpolatePixelChannels method is:
4872 %
4873 % MagickBooleanType InterpolatePixelChannels(const Image *source,
4874 % const CacheView *source_view,const Image *destination,
4875 % const PixelInterpolateMethod method,const double x,const double y,
4876 % Quantum *pixel,ExceptionInfo *exception)
4877 %
4878 % A description of each parameter follows:
4879 %
4880 % o source: the source.
4881 %
4882 % o source_view: the source view.
4883 %
4884 % o destination: the destination image, for the interpolated color
4885 %
4886 % o method: the pixel color interpolation method.
4887 %
4888 % o x,y: A double representing the current (x,y) position of the pixel.
4889 %
4890 % o pixel: return the interpolated pixel here.
4891 %
4892 % o exception: return any errors or warnings in this structure.
4893 %
4894 */
4896  const CacheView_ *source_view,const Image *destination,
4897  const PixelInterpolateMethod method,const double x,const double y,
4898  Quantum *pixel,ExceptionInfo *exception)
4899 {
4901  status;
4902 
4903  double
4904  alpha[16],
4905  gamma,
4906  pixels[16];
4907 
4908  register const Quantum
4909  *p;
4910 
4911  register ssize_t
4912  i;
4913 
4914  ssize_t
4915  x_offset,
4916  y_offset;
4917 
4919  interpolate;
4920 
4921  assert(source != (Image *) NULL);
4922  assert(source->signature == MagickCoreSignature);
4923  assert(source_view != (CacheView *) NULL);
4924  status=MagickTrue;
4925  x_offset=(ssize_t) floor(x);
4926  y_offset=(ssize_t) floor(y);
4927  interpolate=method;
4928  if (interpolate == UndefinedInterpolatePixel)
4929  interpolate=source->interpolate;
4930  switch (interpolate)
4931  {
4932  case AverageInterpolatePixel: /* nearest 4 neighbours */
4933  case Average9InterpolatePixel: /* nearest 9 neighbours */
4934  case Average16InterpolatePixel: /* nearest 16 neighbours */
4935  {
4936  ssize_t
4937  count;
4938 
4939  count=2; /* size of the area to average - default nearest 4 */
4940  if (interpolate == Average9InterpolatePixel)
4941  {
4942  count=3;
4943  x_offset=(ssize_t) (floor(x+0.5)-1);
4944  y_offset=(ssize_t) (floor(y+0.5)-1);
4945  }
4946  else
4947  if (interpolate == Average16InterpolatePixel)
4948  {
4949  count=4;
4950  x_offset--;
4951  y_offset--;
4952  }
4953  p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count,
4954  (size_t) count,exception);
4955  if (p == (const Quantum *) NULL)
4956  {
4957  status=MagickFalse;
4958  break;
4959  }
4960  count*=count; /* Number of pixels to average */
4961  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
4962  {
4963  double
4964  sum;
4965 
4966  register ssize_t
4967  j;
4968 
4969  PixelChannel channel = GetPixelChannelChannel(source,i);
4970  PixelTrait traits = GetPixelChannelTraits(source,channel);
4971  PixelTrait destination_traits=GetPixelChannelTraits(destination,
4972  channel);
4973  if ((traits == UndefinedPixelTrait) ||
4974  (destination_traits == UndefinedPixelTrait))
4975  continue;
4976  for (j=0; j < (ssize_t) count; j++)
4977  pixels[j]=(double) p[j*GetPixelChannels(source)+i];
4978  sum=0.0;
4979  if ((traits & BlendPixelTrait) == 0)
4980  {
4981  for (j=0; j < (ssize_t) count; j++)
4982  sum+=pixels[j];
4983  sum/=count;
4984  SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4985  continue;
4986  }
4987  for (j=0; j < (ssize_t) count; j++)
4988  {
4989  alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4990  GetPixelChannels(source));
4991  pixels[j]*=alpha[j];
4992  gamma=PerceptibleReciprocal(alpha[j]);
4993  sum+=gamma*pixels[j];
4994  }
4995  sum/=count;
4996  SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
4997  }
4998  break;
4999  }
5001  default:
5002  {
5003  p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5004  if (p == (const Quantum *) NULL)
5005  {
5006  status=MagickFalse;
5007  break;
5008  }
5009  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5010  {
5011  PointInfo
5012  delta,
5013  epsilon;
5014 
5015  PixelChannel channel = GetPixelChannelChannel(source,i);
5016  PixelTrait traits = GetPixelChannelTraits(source,channel);
5017  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5018  channel);
5019  if ((traits == UndefinedPixelTrait) ||
5020  (destination_traits == UndefinedPixelTrait))
5021  continue;
5022  delta.x=x-x_offset;
5023  delta.y=y-y_offset;
5024  epsilon.x=1.0-delta.x;
5025  epsilon.y=1.0-delta.y;
5026  pixels[0]=(double) p[i];
5027  pixels[1]=(double) p[GetPixelChannels(source)+i];
5028  pixels[2]=(double) p[2*GetPixelChannels(source)+i];
5029  pixels[3]=(double) p[3*GetPixelChannels(source)+i];
5030  if ((traits & BlendPixelTrait) == 0)
5031  {
5032  gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5033  gamma=PerceptibleReciprocal(gamma);
5034  SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5035  (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*
5036  pixels[2]+delta.x*pixels[3]))),pixel);
5037  continue;
5038  }
5039  alpha[0]=QuantumScale*GetPixelAlpha(source,p);
5040  alpha[1]=QuantumScale*GetPixelAlpha(source,p+GetPixelChannels(source));
5041  alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
5042  GetPixelChannels(source));
5043  alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
5044  GetPixelChannels(source));
5045  pixels[0]*=alpha[0];
5046  pixels[1]*=alpha[1];
5047  pixels[2]*=alpha[2];
5048  pixels[3]*=alpha[3];
5049  gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5050  (epsilon.x*alpha[2]+delta.x*alpha[3])));
5051  gamma=PerceptibleReciprocal(gamma);
5052  SetPixelChannel(destination,channel,ClampToQuantum(gamma*(epsilon.y*
5053  (epsilon.x*pixels[0]+delta.x*pixels[1])+delta.y*(epsilon.x*pixels[2]+
5054  delta.x*pixels[3]))),pixel);
5055  }
5056  break;
5057  }
5058  case BlendInterpolatePixel:
5059  {
5060  p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5061  if (p == (const Quantum *) NULL)
5062  {
5063  status=MagickFalse;
5064  break;
5065  }
5066  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5067  {
5068  register ssize_t
5069  j;
5070 
5071  PixelChannel channel = GetPixelChannelChannel(source,i);
5072  PixelTrait traits = GetPixelChannelTraits(source,channel);
5073  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5074  channel);
5075  if ((traits == UndefinedPixelTrait) ||
5076  (destination_traits == UndefinedPixelTrait))
5077  continue;
5078  if (source->alpha_trait != BlendPixelTrait)
5079  for (j=0; j < 4; j++)
5080  {
5081  alpha[j]=1.0;
5082  pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5083  }
5084  else
5085  for (j=0; j < 4; j++)
5086  {
5087  alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5088  GetPixelChannels(source));
5089  pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5090  if (channel != AlphaPixelChannel)
5091  pixels[j]*=alpha[j];
5092  }
5093  gamma=1.0; /* number of pixels blended together (its variable) */
5094  for (j=0; j <= 1L; j++)
5095  {
5096  if ((y-y_offset) >= 0.75)
5097  {
5098  alpha[j]=alpha[j+2]; /* take right pixels */
5099  pixels[j]=pixels[j+2];
5100  }
5101  else
5102  if ((y-y_offset) > 0.25)
5103  {
5104  gamma=2.0; /* blend both pixels in row */
5105  alpha[j]+=alpha[j+2]; /* add up alpha weights */
5106  pixels[j]+=pixels[j+2];
5107  }
5108  }
5109  if ((x-x_offset) >= 0.75)
5110  {
5111  alpha[0]=alpha[1]; /* take bottom row blend */
5112  pixels[0]=pixels[1];
5113  }
5114  else
5115  if ((x-x_offset) > 0.25)
5116  {
5117  gamma*=2.0; /* blend both rows */
5118  alpha[0]+=alpha[1]; /* add up alpha weights */
5119  pixels[0]+=pixels[1];
5120  }
5121  if (channel != AlphaPixelChannel)
5122  gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
5123  else
5124  gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
5125  SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
5126  pixel);
5127  }
5128  break;
5129  }
5131  {
5132  double
5133  cx[4],
5134  cy[4];
5135 
5136  p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5137  exception);
5138  if (p == (const Quantum *) NULL)
5139  {
5140  status=MagickFalse;
5141  break;
5142  }
5143  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5144  {
5145  register ssize_t
5146  j;
5147 
5148  PixelChannel channel = GetPixelChannelChannel(source,i);
5149  PixelTrait traits = GetPixelChannelTraits(source,channel);
5150  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5151  channel);
5152  if ((traits == UndefinedPixelTrait) ||
5153  (destination_traits == UndefinedPixelTrait))
5154  continue;
5155  if ((traits & BlendPixelTrait) == 0)
5156  for (j=0; j < 16; j++)
5157  {
5158  alpha[j]=1.0;
5159  pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5160  }
5161  else
5162  for (j=0; j < 16; j++)
5163  {
5164  alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5165  GetPixelChannels(source));
5166  pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5167  }
5168  CatromWeights((double) (x-x_offset),&cx);
5169  CatromWeights((double) (y-y_offset),&cy);
5170  gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5171  PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5172  alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5173  alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5174  alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5175  cx[2]*alpha[14]+cx[3]*alpha[15])));
5176  SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5177  pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5178  (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5179  cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5180  pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5181  pixels[14]+cx[3]*pixels[15]))),pixel);
5182  }
5183  break;
5184  }
5186  {
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  }
5207  {
5208  x_offset=(ssize_t) floor(x+0.5);
5209  y_offset=(ssize_t) floor(y+0.5);
5210  p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,1,1,exception);
5211  if (p == (const Quantum *) NULL)
5212  {
5213  status=MagickFalse;
5214  break;
5215  }
5216  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5217  {
5218  PixelChannel channel = GetPixelChannelChannel(source,i);
5219  PixelTrait traits = GetPixelChannelTraits(source,channel);
5220  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5221  channel);
5222  if ((traits == UndefinedPixelTrait) ||
5223  (destination_traits == UndefinedPixelTrait))
5224  continue;
5225  SetPixelChannel(destination,channel,p[i],pixel);
5226  }
5227  break;
5228  }
5229  case MeshInterpolatePixel:
5230  {
5231  p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,2,2,exception);
5232  if (p == (const Quantum *) NULL)
5233  {
5234  status=MagickFalse;
5235  break;
5236  }
5237  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5238  {
5239  PointInfo
5240  delta,
5241  luminance;
5242 
5243  PixelChannel channel = GetPixelChannelChannel(source,i);
5244  PixelTrait traits = GetPixelChannelTraits(source,channel);
5245  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5246  channel);
5247  if ((traits == UndefinedPixelTrait) ||
5248  (destination_traits == UndefinedPixelTrait))
5249  continue;
5250  pixels[0]=(double) p[i];
5251  pixels[1]=(double) p[GetPixelChannels(source)+i];
5252  pixels[2]=(double) p[2*GetPixelChannels(source)+i];
5253  pixels[3]=(double) p[3*GetPixelChannels(source)+i];
5254  if ((traits & BlendPixelTrait) == 0)
5255  {
5256  alpha[0]=1.0;
5257  alpha[1]=1.0;
5258  alpha[2]=1.0;
5259  alpha[3]=1.0;
5260  }
5261  else
5262  {
5263  alpha[0]=QuantumScale*GetPixelAlpha(source,p);
5264  alpha[1]=QuantumScale*GetPixelAlpha(source,p+
5265  GetPixelChannels(source));
5266  alpha[2]=QuantumScale*GetPixelAlpha(source,p+2*
5267  GetPixelChannels(source));
5268  alpha[3]=QuantumScale*GetPixelAlpha(source,p+3*
5269  GetPixelChannels(source));
5270  }
5271  delta.x=x-x_offset;
5272  delta.y=y-y_offset;
5273  luminance.x=fabs((double) (GetPixelLuma(source,p)-
5274  GetPixelLuma(source,p+3*GetPixelChannels(source))));
5275  luminance.y=fabs((double) (GetPixelLuma(source,p+
5276  GetPixelChannels(source))-GetPixelLuma(source,p+2*
5277  GetPixelChannels(source))));
5278  if (luminance.x < luminance.y)
5279  {
5280  /*
5281  Diagonal 0-3 NW-SE.
5282  */
5283  if (delta.x <= delta.y)
5284  {
5285  /*
5286  Bottom-left triangle (pixel: 2, diagonal: 0-3).
5287  */
5288  delta.y=1.0-delta.y;
5289  gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5290  gamma=PerceptibleReciprocal(gamma);
5291  SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5292  MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
5293  }
5294  else
5295  {
5296  /*
5297  Top-right triangle (pixel: 1, diagonal: 0-3).
5298  */
5299  delta.x=1.0-delta.x;
5300  gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5301  gamma=PerceptibleReciprocal(gamma);
5302  SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5303  MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
5304  }
5305  }
5306  else
5307  {
5308  /*
5309  Diagonal 1-2 NE-SW.
5310  */
5311  if (delta.x <= (1.0-delta.y))
5312  {
5313  /*
5314  Top-left triangle (pixel: 0, diagonal: 1-2).
5315  */
5316  gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5317  gamma=PerceptibleReciprocal(gamma);
5318  SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5319  MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
5320  }
5321  else
5322  {
5323  /*
5324  Bottom-right triangle (pixel: 3, diagonal: 1-2).
5325  */
5326  delta.x=1.0-delta.x;
5327  delta.y=1.0-delta.y;
5328  gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
5329  gamma=PerceptibleReciprocal(gamma);
5330  SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5331  MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
5332  }
5333  }
5334  }
5335  break;
5336  }
5338  {
5339  double
5340  cx[4],
5341  cy[4];
5342 
5343  p=GetCacheViewVirtualPixels(source_view,x_offset-1,y_offset-1,4,4,
5344  exception);
5345  if (p == (const Quantum *) NULL)
5346  {
5347  status=MagickFalse;
5348  break;
5349  }
5350  for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
5351  {
5352  register ssize_t
5353  j;
5354 
5355  PixelChannel channel = GetPixelChannelChannel(source,i);
5356  PixelTrait traits = GetPixelChannelTraits(source,channel);
5357  PixelTrait destination_traits=GetPixelChannelTraits(destination,
5358  channel);
5359  if ((traits == UndefinedPixelTrait) ||
5360  (destination_traits == UndefinedPixelTrait))
5361  continue;
5362  if ((traits & BlendPixelTrait) == 0)
5363  for (j=0; j < 16; j++)
5364  {
5365  alpha[j]=1.0;
5366  pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5367  }
5368  else
5369  for (j=0; j < 16; j++)
5370  {
5371  alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5372  GetPixelChannels(source));
5373  pixels[j]=alpha[j]*p[j*GetPixelChannels(source)+i];
5374  }
5375  SplineWeights((double) (x-x_offset),&cx);
5376  SplineWeights((double) (y-y_offset),&cy);
5377  gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
5378  PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
5379  alpha[2]+cx[3]*alpha[3])+cy[1]*(cx[0]*alpha[4]+cx[1]*alpha[5]+cx[2]*
5380  alpha[6]+cx[3]*alpha[7])+cy[2]*(cx[0]*alpha[8]+cx[1]*alpha[9]+cx[2]*
5381  alpha[10]+cx[3]*alpha[11])+cy[3]*(cx[0]*alpha[12]+cx[1]*alpha[13]+
5382  cx[2]*alpha[14]+cx[3]*alpha[15])));
5383  SetPixelChannel(destination,channel,ClampToQuantum(gamma*(cy[0]*(cx[0]*
5384  pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+cx[3]*pixels[3])+cy[1]*
5385  (cx[0]*pixels[4]+cx[1]*pixels[5]+cx[2]*pixels[6]+cx[3]*pixels[7])+
5386  cy[2]*(cx[0]*pixels[8]+cx[1]*pixels[9]+cx[2]*pixels[10]+cx[3]*
5387  pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5388  pixels[14]+cx[3]*pixels[15]))),pixel);
5389  }
5390  break;
5391  }
5392  }
5393  return(status);
5394 }
5395 
5396 /*
5397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5398 % %
5399 % %
5400 % %
5401 % I n t e r p o l a t e P i x e l I n f o %
5402 % %
5403 % %
5404 % %
5405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5406 %
5407 % InterpolatePixelInfo() applies a pixel interpolation method between a
5408 % floating point coordinate and the pixels surrounding that coordinate. No
5409 % pixel area resampling, or scaling of the result is performed.
5410 %
5411 % Interpolation is restricted to just RGBKA channels.
5412 %
5413 % The format of the InterpolatePixelInfo method is:
5414 %
5415 % MagickBooleanType InterpolatePixelInfo(const Image *image,
5416 % const CacheView *image_view,const PixelInterpolateMethod method,
5417 % const double x,const double y,PixelInfo *pixel,
5418 % ExceptionInfo *exception)
5419 %
5420 % A description of each parameter follows:
5421 %
5422 % o image: the image.
5423 %
5424 % o image_view: the image view.
5425 %
5426 % o method: the pixel color interpolation method.
5427 %
5428 % o x,y: A double representing the current (x,y) position of the pixel.
5429 %
5430 % o pixel: return the interpolated pixel here.
5431 %
5432 % o exception: return any errors or warnings in this structure.
5433 %
5434 */
5435 
5436 static inline void AlphaBlendPixelInfo(const Image *image,
5437  const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
5438 {
5439  if (image->alpha_trait == UndefinedPixelTrait)
5440  {
5441  *alpha=1.0;
5442  pixel_info->red=(double) GetPixelRed(image,pixel);
5443  pixel_info->green=(double) GetPixelGreen(image,pixel);
5444  pixel_info->blue=(double) GetPixelBlue(image,pixel);
5445  pixel_info->black=0.0;
5446  if (image->colorspace == CMYKColorspace)
5447  pixel_info->black=(double) GetPixelBlack(image,pixel);
5448  pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5449  return;
5450  }
5451  *alpha=QuantumScale*GetPixelAlpha(image,pixel);
5452  pixel_info->red=(*alpha*GetPixelRed(image,pixel));
5453  pixel_info->green=(*alpha*GetPixelGreen(image,pixel));
5454  pixel_info->blue=(*alpha*GetPixelBlue(image,pixel));
5455  pixel_info->black=0.0;
5456  if (image->colorspace == CMYKColorspace)
5457  pixel_info->black=(*alpha*GetPixelBlack(image,pixel));
5458  pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
5459 }
5460 
5462  const CacheView_ *image_view,const PixelInterpolateMethod method,
5463  const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5464 {
5466  status;
5467 
5468  double
5469  alpha[16],
5470  gamma;
5471 
5472  PixelInfo
5473  pixels[16];
5474 
5475  register const Quantum
5476  *p;
5477 
5478  register ssize_t
5479  i;
5480 
5481  ssize_t
5482  x_offset,
5483  y_offset;
5484 
5486  interpolate;
5487 
5488  assert(image != (Image *) NULL);
5489  assert(image->signature == MagickCoreSignature);
5490  assert(image_view != (CacheView *) NULL);
5491  status=MagickTrue;
5492  x_offset=(ssize_t) floor(x);
5493  y_offset=(ssize_t) floor(y);
5494  interpolate=method;
5495  if (interpolate == UndefinedInterpolatePixel)
5496  interpolate=image->interpolate;
5497  (void) ResetMagickMemory(&pixels,0,sizeof(pixels));
5498  switch (interpolate)
5499  {
5500  case AverageInterpolatePixel: /* nearest 4 neighbours */
5501  case Average9InterpolatePixel: /* nearest 9 neighbours */
5502  case Average16InterpolatePixel: /* nearest 16 neighbours */
5503  {
5504  ssize_t
5505  count;
5506 
5507  count=2; /* size of the area to average - default nearest 4 */
5508  if (interpolate == Average9InterpolatePixel)
5509  {
5510  count=3;
5511  x_offset=(ssize_t) (floor(x+0.5)-1);
5512  y_offset=(ssize_t) (floor(y+0.5)-1);
5513  }
5514  else if (interpolate == Average16InterpolatePixel)
5515  {
5516  count=4;
5517  x_offset--;
5518  y_offset--;
5519  }
5520  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
5521  (size_t) count,exception);
5522  if (p == (const Quantum *) NULL)
5523  {
5524  status=MagickFalse;
5525  break;
5526  }
5527  pixel->red=0.0;
5528  pixel->green=0.0;
5529  pixel->blue=0.0;
5530  pixel->black=0.0;
5531  pixel->alpha=0.0;
5532  count*=count; /* number of pixels - square of size */
5533  for (i=0; i < (ssize_t) count; i++)
5534  {
5535  AlphaBlendPixelInfo(image,p,pixels,alpha);
5536  gamma=PerceptibleReciprocal(alpha[0]);
5537  pixel->red+=gamma*pixels[0].red;
5538  pixel->green+=gamma*pixels[0].green;
5539  pixel->blue+=gamma*pixels[0].blue;
5540  pixel->black+=gamma*pixels[0].black;
5541  pixel->alpha+=pixels[0].alpha;
5542  p += GetPixelChannels(image);
5543  }
5544  gamma=1.0/count; /* average weighting of each pixel in area */
5545  pixel->red*=gamma;
5546  pixel->green*=gamma;
5547  pixel->blue*=gamma;
5548  pixel->black*=gamma;
5549  pixel->alpha*=gamma;
5550  break;
5551  }
5553  {
5554  *pixel=image->background_color; /* Copy PixelInfo Structure */
5555  break;
5556  }
5558  default:
5559  {
5560  PointInfo
5561  delta,
5562  epsilon;
5563 
5564  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5565  if (p == (const Quantum *) NULL)
5566  {
5567  status=MagickFalse;
5568  break;
5569  }
5570  for (i=0; i < 4L; i++)
5571  AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5572  delta.x=x-x_offset;
5573  delta.y=y-y_offset;
5574  epsilon.x=1.0-delta.x;
5575  epsilon.y=1.0-delta.y;
5576  gamma=((epsilon.y*(epsilon.x*alpha[0]+delta.x*alpha[1])+delta.y*
5577  (epsilon.x*alpha[2]+delta.x*alpha[3])));
5578  gamma=PerceptibleReciprocal(gamma);
5579  pixel->red=gamma*(epsilon.y*(epsilon.x*pixels[0].red+delta.x*
5580  pixels[1].red)+delta.y*(epsilon.x*pixels[2].red+delta.x*pixels[3].red));
5581  pixel->green=gamma*(epsilon.y*(epsilon.x*pixels[0].green+delta.x*
5582  pixels[1].green)+delta.y*(epsilon.x*pixels[2].green+delta.x*
5583  pixels[3].green));
5584  pixel->blue=gamma*(epsilon.y*(epsilon.x*pixels[0].blue+delta.x*
5585  pixels[1].blue)+delta.y*(epsilon.x*pixels[2].blue+delta.x*
5586  pixels[3].blue));
5587  if (image->colorspace == CMYKColorspace)
5588  pixel->black=gamma*(epsilon.y*(epsilon.x*pixels[0].black+delta.x*
5589  pixels[1].black)+delta.y*(epsilon.x*pixels[2].black+delta.x*
5590  pixels[3].black));
5591  gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
5592  gamma=PerceptibleReciprocal(gamma);
5593  pixel->alpha=gamma*(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
5594  pixels[1].alpha)+delta.y*(epsilon.x*pixels[2].alpha+delta.x*
5595  pixels[3].alpha));
5596  break;
5597  }
5598  case BlendInterpolatePixel:
5599  {
5600  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5601  if (p == (const Quantum *) NULL)
5602  {
5603  status=MagickFalse;
5604  break;
5605  }
5606  for (i=0; i < 4L; i++)
5607  {
5608  GetPixelInfoPixel(image,p+i*GetPixelChannels(image),pixels+i);
5609  AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5610  }
5611  gamma=1.0; /* number of pixels blended together (its variable) */
5612  for (i=0; i <= 1L; i++)
5613  {
5614  if ((y-y_offset) >= 0.75)
5615  {
5616  alpha[i]=alpha[i+2]; /* take right pixels */
5617  pixels[i]=pixels[i+2];
5618  }
5619  else
5620  if ((y-y_offset) > 0.25)
5621  {
5622  gamma=2.0; /* blend both pixels in row */
5623  alpha[i]+=alpha[i+2]; /* add up alpha weights */
5624  pixels[i].red+=pixels[i+2].red;
5625  pixels[i].green+=pixels[i+2].green;
5626  pixels[i].blue+=pixels[i+2].blue;
5627  pixels[i].black+=pixels[i+2].black;
5628  pixels[i].alpha+=pixels[i+2].alpha;
5629  }
5630  }
5631  if ((x-x_offset) >= 0.75)
5632  {
5633  alpha[0]=alpha[1];
5634  pixels[0]=pixels[1];
5635  }
5636  else
5637  if ((x-x_offset) > 0.25)
5638  {
5639  gamma*=2.0; /* blend both rows */
5640  alpha[0]+= alpha[1]; /* add up alpha weights */
5641  pixels[0].red+=pixels[1].red;
5642  pixels[0].green+=pixels[1].green;
5643  pixels[0].blue+=pixels[1].blue;
5644  pixels[0].black+=pixels[1].black;
5645  pixels[0].alpha+=pixels[1].alpha;
5646  }
5647  gamma=1.0/gamma;
5648  alpha[0]=PerceptibleReciprocal(alpha[0]);
5649  pixel->red=alpha[0]*pixels[0].red;
5650  pixel->green=alpha[0]*pixels[0].green; /* divide by sum of alpha */
5651  pixel->blue=alpha[0]*pixels[0].blue;
5652  pixel->black=alpha[0]*pixels[0].black;
5653  pixel->alpha=gamma*pixels[0].alpha; /* divide by number of pixels */
5654  break;
5655  }
5657  {
5658  double
5659  cx[4],
5660  cy[4];
5661 
5662  p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5663  exception);
5664  if (p == (const Quantum *) NULL)
5665  {
5666  status=MagickFalse;
5667  break;
5668  }
5669  for (i=0; i < 16L; i++)
5670  AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
5671  CatromWeights((double) (x-x_offset),&cx);
5672  CatromWeights((double) (y-y_offset),&cy);
5673  pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5674  pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5675  pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5676  pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5677  pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5678  pixels[14].red+cx[3]*pixels[15].red));
5679  pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5680  pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5681  cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5682  cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5683  pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*
5684  pixels[12].green+cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*
5685  pixels[15].green));
5686  pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5687  pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5688  pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5689  pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5690  pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5691  cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
5692  if (image->colorspace == CMYKColorspace)
5693  pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5694  pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5695  cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5696  cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5697  pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5698  pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5699  pixels[15].black));
5700  pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5701  pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5702  cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5703  cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5704  pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5705  cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
5706  break;
5707  }
5709  {
5710  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
5711  if (p == (const Quantum *) NULL)
5712  {
5713  status=MagickFalse;
5714  break;
5715  }
5716  GetPixelInfoPixel(image,p,pixel);
5717  break;
5718  }
5719  case MeshInterpolatePixel:
5720  {
5721  PointInfo
5722  delta,
5723  luminance;
5724 
5725  p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
5726  if (p == (const Quantum *) NULL)
5727  {
5728  status=MagickFalse;
5729  break;
5730  }
5731  delta.x=x-x_offset;
5732  delta.y=y-y_offset;
5733  luminance.x=GetPixelLuma(image,p)-(double)
5734  GetPixelLuma(image,p+3*GetPixelChannels(image));
5735  luminance.y=GetPixelLuma(image,p+GetPixelChannels(image))-(double)
5736  GetPixelLuma(image,p+2*GetPixelChannels(image));
5737  AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
5738  AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
5739  AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5740  AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
5741  if (fabs(luminance.x) < fabs(luminance.y))
5742  {
5743  /*
5744  Diagonal 0-3 NW-SE.
5745  */
5746  if (delta.x <= delta.y)
5747  {
5748  /*
5749  Bottom-left triangle (pixel: 2, diagonal: 0-3).
5750  */
5751  delta.y=1.0-delta.y;
5752  gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
5753  gamma=PerceptibleReciprocal(gamma);
5754  pixel->red=gamma*MeshInterpolate(&delta,pixels[2].red,
5755  pixels[3].red,pixels[0].red);
5756  pixel->green=gamma*MeshInterpolate(&delta,pixels[2].green,
5757  pixels[3].green,pixels[0].green);
5758  pixel->blue=gamma*MeshInterpolate(&delta,pixels[2].blue,
5759  pixels[3].blue,pixels[0].blue);
5760  if (image->colorspace == CMYKColorspace)
5761  pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5762  pixels[3].black,pixels[0].black);
5763  gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5764  pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5765  pixels[3].alpha,pixels[0].alpha);
5766  }
5767  else
5768  {
5769  /*
5770  Top-right triangle (pixel:1 , diagonal: 0-3).
5771  */
5772  delta.x=1.0-delta.x;
5773  gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
5774  gamma=PerceptibleReciprocal(gamma);
5775  pixel->red=gamma*MeshInterpolate(&delta,pixels[1].red,
5776  pixels[0].red,pixels[3].red);
5777  pixel->green=gamma*MeshInterpolate(&delta,pixels[1].green,
5778  pixels[0].green,pixels[3].green);
5779  pixel->blue=gamma*MeshInterpolate(&delta,pixels[1].blue,
5780  pixels[0].blue,pixels[3].blue);
5781  if (image->colorspace == CMYKColorspace)
5782  pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5783  pixels[0].black,pixels[3].black);
5784  gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
5785  pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5786  pixels[0].alpha,pixels[3].alpha);
5787  }
5788  }
5789  else
5790  {
5791  /*
5792  Diagonal 1-2 NE-SW.
5793  */
5794  if (delta.x <= (1.0-delta.y))
5795  {
5796  /*
5797  Top-left triangle (pixel: 0, diagonal: 1-2).
5798  */
5799  gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
5800  gamma=PerceptibleReciprocal(gamma);
5801  pixel->red=gamma*MeshInterpolate(&delta,pixels[0].red,
5802  pixels[1].red,pixels[2].red);
5803  pixel->green=gamma*MeshInterpolate(&delta,pixels[0].green,
5804  pixels[1].green,pixels[2].green);
5805  pixel->blue=gamma*MeshInterpolate(&delta,pixels[0].blue,
5806  pixels[1].blue,pixels[2].blue);
5807  if (image->colorspace == CMYKColorspace)
5808  pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5809  pixels[1].black,pixels[2].black);
5810  gam