blob: 74231dfca0d9eea4016b244c8dc83bf7c78f4329 [file] [log] [blame]
cristy4c08aed2011-07-01 19:47:50 +00001/*
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 %
cristyde984cd2013-12-01 14:49:27 +000015% Cristy %
cristy4c08aed2011-07-01 19:47:50 +000016% October 1998 %
17% %
18% %
Cristyf6ff9ea2016-12-05 09:53:35 -050019% Copyright 1999-2017 ImageMagick Studio LLC, a non-profit organization %
cristy4c08aed2011-07-01 19:47:50 +000020% 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% %
Cristyf19d4142017-04-24 11:34:30 -040025% https://www.imagemagick.org/script/license.php %
cristy4c08aed2011-07-01 19:47:50 +000026% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
41#include "MagickCore/studio.h"
42#include "MagickCore/property.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
cristy322d07d2012-03-18 21:17:23 +000045#include "MagickCore/cache-private.h"
cristy4c08aed2011-07-01 19:47:50 +000046#include "MagickCore/color-private.h"
cristy1f075552014-11-04 00:03:27 +000047#include "MagickCore/colorspace-private.h"
cristy4c08aed2011-07-01 19:47:50 +000048#include "MagickCore/draw.h"
49#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/cache.h"
52#include "MagickCore/constitute.h"
53#include "MagickCore/delegate.h"
54#include "MagickCore/geometry.h"
55#include "MagickCore/image-private.h"
56#include "MagickCore/list.h"
57#include "MagickCore/magick.h"
58#include "MagickCore/memory_.h"
dirkb93e6eb2015-12-14 22:41:22 +010059#include "MagickCore/memory-private.h"
cristy4c08aed2011-07-01 19:47:50 +000060#include "MagickCore/monitor.h"
61#include "MagickCore/option.h"
62#include "MagickCore/pixel.h"
63#include "MagickCore/pixel-accessor.h"
cristy380a11c2012-06-02 15:15:22 +000064#include "MagickCore/pixel-private.h"
cristy4c08aed2011-07-01 19:47:50 +000065#include "MagickCore/quantum.h"
66#include "MagickCore/quantum-private.h"
67#include "MagickCore/resource_.h"
68#include "MagickCore/semaphore.h"
69#include "MagickCore/statistic.h"
70#include "MagickCore/stream.h"
71#include "MagickCore/string_.h"
72#include "MagickCore/transform.h"
73#include "MagickCore/utility.h"
74
cristy146a62b2011-10-23 23:40:46 +000075/*
cristy4c08aed2011-07-01 19:47:50 +000076%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77% %
78% %
79% %
cristyed231572011-07-14 02:18:59 +000080+ A c q u i r e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +000081% %
82% %
83% %
84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85%
cristyed231572011-07-14 02:18:59 +000086% AcquirePixelChannelMap() acquires a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +000087%
cristyed231572011-07-14 02:18:59 +000088% The format of the AcquirePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +000089%
cristybd5a96c2011-08-21 00:04:26 +000090% PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +000091%
92*/
cristybd5a96c2011-08-21 00:04:26 +000093MagickExport PixelChannelMap *AcquirePixelChannelMap(void)
cristy4c08aed2011-07-01 19:47:50 +000094{
cristyed231572011-07-14 02:18:59 +000095 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +000096 *channel_map;
cristy4c08aed2011-07-01 19:47:50 +000097
98 register ssize_t
99 i;
100
cristybd5a96c2011-08-21 00:04:26 +0000101 channel_map=(PixelChannelMap *) AcquireQuantumMemory(MaxPixelChannels,
102 sizeof(*channel_map));
103 if (channel_map == (PixelChannelMap *) NULL)
cristy4c08aed2011-07-01 19:47:50 +0000104 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
cristybd5a96c2011-08-21 00:04:26 +0000105 (void) ResetMagickMemory(channel_map,0,MaxPixelChannels*sizeof(*channel_map));
106 for (i=0; i < MaxPixelChannels; i++)
107 channel_map[i].channel=(PixelChannel) i;
cristyed231572011-07-14 02:18:59 +0000108 return(channel_map);
cristy4c08aed2011-07-01 19:47:50 +0000109}
110
111/*
112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
113% %
114% %
115% %
cristyed231572011-07-14 02:18:59 +0000116+ C l o n e P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000117% %
118% %
119% %
120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121%
cristyed231572011-07-14 02:18:59 +0000122% ClonePixelChannelMap() clones a pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000123%
cristyed231572011-07-14 02:18:59 +0000124% The format of the ClonePixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000125%
cristybd5a96c2011-08-21 00:04:26 +0000126% PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000127%
128% A description of each parameter follows:
129%
cristyed231572011-07-14 02:18:59 +0000130% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000131%
132*/
cristybd5a96c2011-08-21 00:04:26 +0000133MagickExport PixelChannelMap *ClonePixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000134{
cristyed231572011-07-14 02:18:59 +0000135 PixelChannelMap
cristybd5a96c2011-08-21 00:04:26 +0000136 *clone_map;
cristy4c08aed2011-07-01 19:47:50 +0000137
cristybd5a96c2011-08-21 00:04:26 +0000138 assert(channel_map != (PixelChannelMap *) NULL);
cristyed231572011-07-14 02:18:59 +0000139 clone_map=AcquirePixelChannelMap();
cristybd5a96c2011-08-21 00:04:26 +0000140 if (clone_map == (PixelChannelMap *) NULL)
141 return((PixelChannelMap *) NULL);
142 (void) CopyMagickMemory(clone_map,channel_map,MaxPixelChannels*
143 sizeof(*channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000144 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%
cristy1f075552014-11-04 00:03:27 +0000163% PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +0000164%
165% A description of each parameter follows:
166%
cristy1f075552014-11-04 00:03:27 +0000167% o pixel: the pixel info.
cristy4c08aed2011-07-01 19:47:50 +0000168%
169*/
170MagickExport PixelInfo *ClonePixelInfo(const PixelInfo *pixel)
171{
172 PixelInfo
173 *pixel_info;
174
Cristy86bbc262017-04-02 10:07:42 -0400175 pixel_info=(PixelInfo *) AcquireQuantumMemory(1,sizeof(*pixel_info));
cristy4c08aed2011-07-01 19:47:50 +0000176 if (pixel_info == (PixelInfo *) NULL)
177 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
178 *pixel_info=(*pixel);
179 return(pixel_info);
180}
181
182/*
183%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184% %
185% %
186% %
cristy1f075552014-11-04 00:03:27 +0000187+ 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%
cristy41029e12014-11-04 22:10:22 +0000198% void *ConformPixelInfo((Image *image,const PixelInfo *source,
199% PixelInfo *destination,ExceptionInfo *exception)
cristy1f075552014-11-04 00:03:27 +0000200%
201% A description of each parameter follows:
202%
cristy1f075552014-11-04 00:03:27 +0000203% o image: the image.
204%
dirkbfdd5bc2014-11-04 19:47:44 +0000205% o source: the source pixel info.
206%
207% o destination: the destination pixel info.
208%
cristy1f075552014-11-04 00:03:27 +0000209% o exception: return any errors or warnings in this structure.
210%
211*/
dirkbfdd5bc2014-11-04 19:47:44 +0000212MagickExport void ConformPixelInfo(Image *image,const PixelInfo *source,
213 PixelInfo *destination,ExceptionInfo *exception)
cristy1f075552014-11-04 00:03:27 +0000214{
215 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000216 assert(image->signature == MagickCoreSignature);
dirkbfdd5bc2014-11-04 19:47:44 +0000217 assert(destination != (const PixelInfo *) NULL);
dirkbfdd5bc2014-11-04 19:47:44 +0000218 *destination=(*source);
cristy1f075552014-11-04 00:03:27 +0000219 if (image->colorspace == CMYKColorspace)
220 {
dirkbfdd5bc2014-11-04 19:47:44 +0000221 if (IssRGBCompatibleColorspace(destination->colorspace))
222 ConvertRGBToCMYK(destination);
cristy1f075552014-11-04 00:03:27 +0000223 }
224 else
dirkbfdd5bc2014-11-04 19:47:44 +0000225 if (destination->colorspace == CMYKColorspace)
cristy1f075552014-11-04 00:03:27 +0000226 {
227 if (IssRGBCompatibleColorspace(image->colorspace))
dirkbfdd5bc2014-11-04 19:47:44 +0000228 ConvertCMYKToRGB(destination);
cristy1f075552014-11-04 00:03:27 +0000229 }
dirkbfdd5bc2014-11-04 19:47:44 +0000230 if ((IsPixelInfoGray(&image->background_color) == MagickFalse) &&
231 (IsGrayColorspace(image->colorspace) != MagickFalse))
232 (void) TransformImageColorspace(image,sRGBColorspace,exception);
cristy17f11b02014-12-20 19:37:04 +0000233 if ((destination->alpha_trait != UndefinedPixelTrait) &&
234 (image->alpha_trait == UndefinedPixelTrait))
cristy1f075552014-11-04 00:03:27 +0000235 (void) SetImageAlpha(image,OpaqueAlpha,exception);
236}
237
238/*
239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
240% %
241% %
242% %
cristyc8aff842012-12-24 16:59:46 +0000243% 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%
cristy35060592013-04-17 14:10:20 +0000251% The format of the DecodePixelGamma method is:
cristyc8aff842012-12-24 16:59:46 +0000252%
253% double DecodePixelGamma(const MagickRealType pixel)
254%
255% A description of each parameter follows:
256%
257% o pixel: the pixel.
258%
259*/
cristyc29824a2013-04-17 21:52:56 +0000260
261static inline double DecodeGamma(const double x)
262{
263 div_t
264 quotient;
265
266 double
267 p,
268 term[9];
269
270 int
271 exponent;
272
273 static const double coefficient[] = /* terms for x^(7/5), x=1.5 */
274 {
275 1.7917488588043277509,
276 0.82045614371976854984,
277 0.027694100686325412819,
278 -0.00094244335181762134018,
279 0.000064355540911469709545,
280 -5.7224404636060757485e-06,
281 5.8767669437311184313e-07,
282 -6.6139920053589721168e-08,
283 7.9323242696227458163e-09
284 };
285
286 static const double powers_of_two[] = /* (2^x)^(7/5) */
287 {
288 1.0,
289 2.6390158215457883983,
290 6.9644045063689921093,
291 1.8379173679952558018e+01,
292 4.8502930128332728543e+01
293 };
294
295 /*
296 Compute x^2.4 == x*x^(7/5) == pow(x,2.4).
297 */
298 term[0]=1.0;
299 term[1]=4.0*frexp(x,&exponent)-3.0;
300 term[2]=2.0*term[1]*term[1]-term[0];
301 term[3]=2.0*term[1]*term[2]-term[1];
302 term[4]=2.0*term[1]*term[3]-term[2];
303 term[5]=2.0*term[1]*term[4]-term[3];
304 term[6]=2.0*term[1]*term[5]-term[4];
305 term[7]=2.0*term[1]*term[6]-term[5];
306 term[8]=2.0*term[1]*term[7]-term[6];
307 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
308 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
309 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
310 quotient=div(exponent-1,5);
311 if (quotient.rem < 0)
312 {
313 quotient.quot-=1;
314 quotient.rem+=5;
315 }
316 return(x*ldexp(powers_of_two[quotient.rem]*p,7*quotient.quot));
317}
318
cristyc8aff842012-12-24 16:59:46 +0000319MagickExport MagickRealType DecodePixelGamma(const MagickRealType pixel)
320{
321 if (pixel <= (0.0404482362771076*QuantumRange))
322 return(pixel/12.92f);
cristyc29824a2013-04-17 21:52:56 +0000323 return((MagickRealType) (QuantumRange*DecodeGamma((double) (QuantumScale*
324 pixel+0.055)/1.055)));
cristyc8aff842012-12-24 16:59:46 +0000325}
326
327/*
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329% %
330% %
331% %
cristyed231572011-07-14 02:18:59 +0000332+ D e s t r o y P i x e l C h a n n e l M a p %
cristy4c08aed2011-07-01 19:47:50 +0000333% %
334% %
335% %
336%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337%
cristyed231572011-07-14 02:18:59 +0000338% DestroyPixelChannelMap() deallocates memory associated with the pixel
339% channel map.
cristy4c08aed2011-07-01 19:47:50 +0000340%
cristyed231572011-07-14 02:18:59 +0000341% The format of the DestroyPixelChannelMap() method is:
cristy4c08aed2011-07-01 19:47:50 +0000342%
cristybd5a96c2011-08-21 00:04:26 +0000343% PixelChannelMap *DestroyPixelChannelMap(PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000344%
345% A description of each parameter follows:
346%
cristyed231572011-07-14 02:18:59 +0000347% o channel_map: the pixel component map.
cristy4c08aed2011-07-01 19:47:50 +0000348%
349*/
cristybd5a96c2011-08-21 00:04:26 +0000350MagickExport PixelChannelMap *DestroyPixelChannelMap(
351 PixelChannelMap *channel_map)
cristy4c08aed2011-07-01 19:47:50 +0000352{
cristybd5a96c2011-08-21 00:04:26 +0000353 assert(channel_map != (PixelChannelMap *) NULL);
354 channel_map=(PixelChannelMap *) RelinquishMagickMemory(channel_map);
355 return((PixelChannelMap *) RelinquishMagickMemory(channel_map));
cristy4c08aed2011-07-01 19:47:50 +0000356}
357
358/*
359%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
360% %
361% %
362% %
cristyc8aff842012-12-24 16:59:46 +0000363+ 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%
cristy35060592013-04-17 14:10:20 +0000371% The format of the EncodePixelGamma method is:
cristyc8aff842012-12-24 16:59:46 +0000372%
373% MagickRealType EncodePixelGamma(const double MagickRealType)
374%
375% A description of each parameter follows:
376%
377% o pixel: the pixel.
378%
379*/
cristyc29824a2013-04-17 21:52:56 +0000380
381static inline double EncodeGamma(const double x)
382{
383 div_t
384 quotient;
385
386 double
387 p,
388 term[9];
389
390 int
391 exponent;
392
393 static const double coefficient[] = /* Chebychevi poly: x^(5/12), x=1.5 */
394 {
395 1.1758200232996901923,
396 0.16665763094889061230,
397 -0.0083154894939042125035,
398 0.00075187976780420279038,
399 -0.000083240178519391795367,
400 0.000010229209410070008679,
401 -1.3400466409860246e-06,
402 1.8333422241635376682e-07,
403 -2.5878596761348859722e-08
404 };
405
406 static const double powers_of_two[] = /* (2^N)^(5/12) */
407 {
408 1.0,
409 1.3348398541700343678,
410 1.7817974362806785482,
411 2.3784142300054420538,
412 3.1748021039363991669,
413 4.2378523774371812394,
414 5.6568542494923805819,
415 7.5509945014535482244,
416 1.0079368399158985525e1,
417 1.3454342644059433809e1,
418 1.7959392772949968275e1,
419 2.3972913230026907883e1
420 };
421
422 /*
423 Compute x^(1/2.4) == x^(5/12) == pow(x,1.0/2.4).
424 */
425 term[0]=1.0;
426 term[1]=4.0*frexp(x,&exponent)-3.0;
427 term[2]=2.0*term[1]*term[1]-term[0];
428 term[3]=2.0*term[1]*term[2]-term[1];
429 term[4]=2.0*term[1]*term[3]-term[2];
430 term[5]=2.0*term[1]*term[4]-term[3];
431 term[6]=2.0*term[1]*term[5]-term[4];
432 term[7]=2.0*term[1]*term[6]-term[5];
433 term[8]=2.0*term[1]*term[7]-term[6];
434 p=coefficient[0]*term[0]+coefficient[1]*term[1]+coefficient[2]*term[2]+
435 coefficient[3]*term[3]+coefficient[4]*term[4]+coefficient[5]*term[5]+
436 coefficient[6]*term[6]+coefficient[7]*term[7]+coefficient[8]*term[8];
437 quotient=div(exponent-1,12);
438 if (quotient.rem < 0)
439 {
440 quotient.quot-=1;
441 quotient.rem+=12;
442 }
443 return(ldexp(powers_of_two[quotient.rem]*p,5*quotient.quot));
444}
445
cristyc8aff842012-12-24 16:59:46 +0000446MagickExport MagickRealType EncodePixelGamma(const MagickRealType pixel)
447{
448 if (pixel <= (0.0031306684425005883*QuantumRange))
449 return(12.92f*pixel);
cristyc29824a2013-04-17 21:52:56 +0000450 return((MagickRealType) QuantumRange*(1.055*EncodeGamma((double) QuantumScale*
cristy2a13aa62013-04-18 19:15:28 +0000451 pixel)-0.055));
cristyc8aff842012-12-24 16:59:46 +0000452}
453
454/*
455%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
456% %
457% %
458% %
cristy4c08aed2011-07-01 19:47:50 +0000459% 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
cristyb5a45a32012-01-10 13:31:13 +0000467% encountered. The data is returned as char, short int, Quantum, unsigned int,
cristycafe0412012-01-10 13:29:58 +0000468% unsigned long long, float, or double in the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +0000469%
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%
cristycafe0412012-01-10 13:29:58 +0000477% 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,
cristy46f4be22012-01-07 00:26:39 +0000480% ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +0000481%
482% A description of each parameter follows:
483%
484% o image: the image.
485%
cristycafe0412012-01-10 13:29:58 +0000486% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +0000487% 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
cristy6c9e1682012-01-07 21:37:44 +0000497% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +0000498% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +0000499% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +0000500%
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*/
cristye5370942012-01-06 03:49:31 +0000508
dirk39fee9a2016-01-09 12:09:47 +0100509static void ExportCharPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +0100510 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000511 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000512{
513 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100514 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +0000515
516 register ssize_t
517 x;
518
519 register unsigned char
dirk05d2ff72015-11-18 23:13:43 +0100520 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +0000521
cristy14d71292012-05-20 16:48:13 +0000522 size_t
523 length;
524
cristye5370942012-01-06 03:49:31 +0000525 ssize_t
526 y;
527
cristy46f4be22012-01-07 00:26:39 +0000528 q=(unsigned char *) pixels;
cristye5370942012-01-06 03:49:31 +0000529 if (LocaleCompare(map,"BGR") == 0)
530 {
cristycafe0412012-01-10 13:29:58 +0000531 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000532 {
cristycafe0412012-01-10 13:29:58 +0000533 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000534 if (p == (const Quantum *) NULL)
535 break;
cristycafe0412012-01-10 13:29:58 +0000536 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000537 {
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 {
cristycafe0412012-01-10 13:29:58 +0000548 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000549 {
cristycafe0412012-01-10 13:29:58 +0000550 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000551 if (p == (const Quantum *) NULL)
552 break;
cristycafe0412012-01-10 13:29:58 +0000553 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000554 {
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 {
cristycafe0412012-01-10 13:29:58 +0000566 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000567 {
cristycafe0412012-01-10 13:29:58 +0000568 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000569 if (p == (const Quantum *) NULL)
570 break;
cristycafe0412012-01-10 13:29:58 +0000571 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000572 {
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 {
cristycafe0412012-01-10 13:29:58 +0000584 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000585 {
cristycafe0412012-01-10 13:29:58 +0000586 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000587 if (p == (const Quantum *) NULL)
588 break;
cristycafe0412012-01-10 13:29:58 +0000589 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000590 {
cristy70e9f682013-03-12 22:31:22 +0000591 *q++=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +0000592 p+=GetPixelChannels(image);
593 }
594 }
595 return;
596 }
597 if (LocaleCompare(map,"RGB") == 0)
598 {
cristycafe0412012-01-10 13:29:58 +0000599 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000600 {
cristycafe0412012-01-10 13:29:58 +0000601 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000602 if (p == (const Quantum *) NULL)
603 break;
cristycafe0412012-01-10 13:29:58 +0000604 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000605 {
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 {
cristycafe0412012-01-10 13:29:58 +0000616 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000617 {
cristycafe0412012-01-10 13:29:58 +0000618 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000619 if (p == (const Quantum *) NULL)
620 break;
cristycafe0412012-01-10 13:29:58 +0000621 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000622 {
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 {
cristycafe0412012-01-10 13:29:58 +0000634 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000635 {
cristycafe0412012-01-10 13:29:58 +0000636 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000637 if (p == (const Quantum *) NULL)
638 break;
cristycafe0412012-01-10 13:29:58 +0000639 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000640 {
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 }
cristy14d71292012-05-20 16:48:13 +0000650 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000651 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000652 {
cristycafe0412012-01-10 13:29:58 +0000653 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000654 if (p == (const Quantum *) NULL)
655 break;
cristycafe0412012-01-10 13:29:58 +0000656 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000657 {
658 register ssize_t
659 i;
660
cristy14d71292012-05-20 16:48:13 +0000661 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000662 {
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 {
cristy70e9f682013-03-12 22:31:22 +0000702 *q=ScaleQuantumToChar(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +0000703 break;
704 }
705 default:
706 break;
707 }
708 q++;
709 }
710 p+=GetPixelChannels(image);
711 }
712 }
713}
714
dirk39fee9a2016-01-09 12:09:47 +0100715static void ExportDoublePixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +0100716 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000717 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000718{
719 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100720 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +0000721
722 register double
dirk05d2ff72015-11-18 23:13:43 +0100723 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +0000724
725 register ssize_t
726 x;
727
cristy14d71292012-05-20 16:48:13 +0000728 size_t
729 length;
730
cristye5370942012-01-06 03:49:31 +0000731 ssize_t
732 y;
733
734 q=(double *) pixels;
735 if (LocaleCompare(map,"BGR") == 0)
736 {
cristycafe0412012-01-10 13:29:58 +0000737 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000738 {
cristycafe0412012-01-10 13:29:58 +0000739 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000740 if (p == (const Quantum *) NULL)
741 break;
cristycafe0412012-01-10 13:29:58 +0000742 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000743 {
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 {
cristycafe0412012-01-10 13:29:58 +0000754 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000755 {
cristycafe0412012-01-10 13:29:58 +0000756 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000757 if (p == (const Quantum *) NULL)
758 break;
cristycafe0412012-01-10 13:29:58 +0000759 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000760 {
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 {
cristycafe0412012-01-10 13:29:58 +0000772 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000773 {
cristycafe0412012-01-10 13:29:58 +0000774 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000775 if (p == (const Quantum *) NULL)
776 break;
cristycafe0412012-01-10 13:29:58 +0000777 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000778 {
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 {
cristycafe0412012-01-10 13:29:58 +0000790 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000791 {
cristycafe0412012-01-10 13:29:58 +0000792 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000793 if (p == (const Quantum *) NULL)
794 break;
cristycafe0412012-01-10 13:29:58 +0000795 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000796 {
797 *q++=(double) (QuantumScale*GetPixelIntensity(image,p));
798 p+=GetPixelChannels(image);
799 }
800 }
801 return;
802 }
803 if (LocaleCompare(map,"RGB") == 0)
804 {
cristycafe0412012-01-10 13:29:58 +0000805 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000806 {
cristycafe0412012-01-10 13:29:58 +0000807 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000808 if (p == (const Quantum *) NULL)
809 break;
cristycafe0412012-01-10 13:29:58 +0000810 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000811 {
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 {
cristycafe0412012-01-10 13:29:58 +0000822 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000823 {
cristycafe0412012-01-10 13:29:58 +0000824 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000825 if (p == (const Quantum *) NULL)
826 break;
cristycafe0412012-01-10 13:29:58 +0000827 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000828 {
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 {
cristycafe0412012-01-10 13:29:58 +0000840 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000841 {
cristycafe0412012-01-10 13:29:58 +0000842 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000843 if (p == (const Quantum *) NULL)
844 break;
cristycafe0412012-01-10 13:29:58 +0000845 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000846 {
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 }
cristy14d71292012-05-20 16:48:13 +0000856 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +0000857 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000858 {
cristycafe0412012-01-10 13:29:58 +0000859 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000860 if (p == (const Quantum *) NULL)
861 break;
cristycafe0412012-01-10 13:29:58 +0000862 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000863 {
864 register ssize_t
865 i;
866
cristy14d71292012-05-20 16:48:13 +0000867 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +0000868 {
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
dirk39fee9a2016-01-09 12:09:47 +0100922static void ExportFloatPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +0100923 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +0000924 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +0000925{
926 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +0100927 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +0000928
929 register float
dirk05d2ff72015-11-18 23:13:43 +0100930 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +0000931
932 register ssize_t
933 x;
934
cristy14d71292012-05-20 16:48:13 +0000935 size_t
936 length;
937
cristye5370942012-01-06 03:49:31 +0000938 ssize_t
939 y;
940
941 q=(float *) pixels;
942 if (LocaleCompare(map,"BGR") == 0)
943 {
cristycafe0412012-01-10 13:29:58 +0000944 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000945 {
cristycafe0412012-01-10 13:29:58 +0000946 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000947 if (p == (const Quantum *) NULL)
948 break;
cristycafe0412012-01-10 13:29:58 +0000949 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000950 {
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 {
cristycafe0412012-01-10 13:29:58 +0000961 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000962 {
cristycafe0412012-01-10 13:29:58 +0000963 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000964 if (p == (const Quantum *) NULL)
965 break;
cristycafe0412012-01-10 13:29:58 +0000966 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000967 {
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 {
cristycafe0412012-01-10 13:29:58 +0000979 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000980 {
cristycafe0412012-01-10 13:29:58 +0000981 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +0000982 if (p == (const Quantum *) NULL)
983 break;
cristycafe0412012-01-10 13:29:58 +0000984 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +0000985 {
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 {
cristycafe0412012-01-10 13:29:58 +0000997 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +0000998 {
cristycafe0412012-01-10 13:29:58 +0000999 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001000 if (p == (const Quantum *) NULL)
1001 break;
cristycafe0412012-01-10 13:29:58 +00001002 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001003 {
1004 *q++=(float) (QuantumScale*GetPixelIntensity(image,p));
1005 p+=GetPixelChannels(image);
1006 }
1007 }
1008 return;
1009 }
1010 if (LocaleCompare(map,"RGB") == 0)
1011 {
cristycafe0412012-01-10 13:29:58 +00001012 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001013 {
cristycafe0412012-01-10 13:29:58 +00001014 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001015 if (p == (const Quantum *) NULL)
1016 break;
cristycafe0412012-01-10 13:29:58 +00001017 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001018 {
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 {
cristycafe0412012-01-10 13:29:58 +00001029 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001030 {
cristycafe0412012-01-10 13:29:58 +00001031 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001032 if (p == (const Quantum *) NULL)
1033 break;
cristycafe0412012-01-10 13:29:58 +00001034 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001035 {
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 {
cristycafe0412012-01-10 13:29:58 +00001047 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001048 {
cristycafe0412012-01-10 13:29:58 +00001049 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001050 if (p == (const Quantum *) NULL)
1051 break;
cristycafe0412012-01-10 13:29:58 +00001052 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001053 {
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 }
cristy14d71292012-05-20 16:48:13 +00001063 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001064 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001065 {
cristycafe0412012-01-10 13:29:58 +00001066 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001067 if (p == (const Quantum *) NULL)
1068 break;
cristycafe0412012-01-10 13:29:58 +00001069 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001070 {
1071 register ssize_t
1072 i;
1073
cristy14d71292012-05-20 16:48:13 +00001074 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001075 {
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
dirk39fee9a2016-01-09 12:09:47 +01001128static void ExportLongPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01001129 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +00001130 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001131{
1132 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001133 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00001134
1135 register ssize_t
1136 x;
1137
1138 register unsigned int
dirk05d2ff72015-11-18 23:13:43 +01001139 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00001140
cristy14d71292012-05-20 16:48:13 +00001141 size_t
1142 length;
1143
cristye5370942012-01-06 03:49:31 +00001144 ssize_t
1145 y;
1146
1147 q=(unsigned int *) pixels;
1148 if (LocaleCompare(map,"BGR") == 0)
1149 {
cristycafe0412012-01-10 13:29:58 +00001150 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001151 {
cristycafe0412012-01-10 13:29:58 +00001152 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001153 if (p == (const Quantum *) NULL)
1154 break;
cristycafe0412012-01-10 13:29:58 +00001155 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001156 {
cristy6c9e1682012-01-07 21:37:44 +00001157 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1158 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1159 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001160 p+=GetPixelChannels(image);
1161 }
1162 }
1163 return;
1164 }
1165 if (LocaleCompare(map,"BGRA") == 0)
1166 {
cristycafe0412012-01-10 13:29:58 +00001167 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001168 {
cristycafe0412012-01-10 13:29:58 +00001169 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001170 if (p == (const Quantum *) NULL)
1171 break;
cristycafe0412012-01-10 13:29:58 +00001172 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001173 {
cristy6c9e1682012-01-07 21:37:44 +00001174 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1175 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1176 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1177 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001178 p+=GetPixelChannels(image);
1179 }
1180 }
1181 return;
1182 }
1183 if (LocaleCompare(map,"BGRP") == 0)
1184 {
cristycafe0412012-01-10 13:29:58 +00001185 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001186 {
cristycafe0412012-01-10 13:29:58 +00001187 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001188 if (p == (const Quantum *) NULL)
1189 break;
cristycafe0412012-01-10 13:29:58 +00001190 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001191 {
cristy6c9e1682012-01-07 21:37:44 +00001192 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1193 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1194 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1195 *q++=0;
cristye5370942012-01-06 03:49:31 +00001196 p+=GetPixelChannels(image);
1197 }
1198 }
1199 return;
1200 }
1201 if (LocaleCompare(map,"I") == 0)
1202 {
cristycafe0412012-01-10 13:29:58 +00001203 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001204 {
cristycafe0412012-01-10 13:29:58 +00001205 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001206 if (p == (const Quantum *) NULL)
1207 break;
cristycafe0412012-01-10 13:29:58 +00001208 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001209 {
cristy70e9f682013-03-12 22:31:22 +00001210 *q++=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001211 p+=GetPixelChannels(image);
1212 }
1213 }
1214 return;
1215 }
1216 if (LocaleCompare(map,"RGB") == 0)
1217 {
cristycafe0412012-01-10 13:29:58 +00001218 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001219 {
cristycafe0412012-01-10 13:29:58 +00001220 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001221 if (p == (const Quantum *) NULL)
1222 break;
cristycafe0412012-01-10 13:29:58 +00001223 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001224 {
cristy6c9e1682012-01-07 21:37:44 +00001225 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1226 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1227 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001228 p+=GetPixelChannels(image);
1229 }
1230 }
1231 return;
1232 }
1233 if (LocaleCompare(map,"RGBA") == 0)
1234 {
cristycafe0412012-01-10 13:29:58 +00001235 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001236 {
cristycafe0412012-01-10 13:29:58 +00001237 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001238 if (p == (const Quantum *) NULL)
1239 break;
cristycafe0412012-01-10 13:29:58 +00001240 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001241 {
cristy6c9e1682012-01-07 21:37:44 +00001242 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1243 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1244 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1245 *q++=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001246 p+=GetPixelChannels(image);
1247 }
1248 }
1249 return;
1250 }
1251 if (LocaleCompare(map,"RGBP") == 0)
1252 {
cristycafe0412012-01-10 13:29:58 +00001253 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001254 {
cristycafe0412012-01-10 13:29:58 +00001255 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001256 if (p == (const Quantum *) NULL)
1257 break;
cristycafe0412012-01-10 13:29:58 +00001258 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001259 {
cristy6c9e1682012-01-07 21:37:44 +00001260 *q++=ScaleQuantumToLong(GetPixelRed(image,p));
1261 *q++=ScaleQuantumToLong(GetPixelGreen(image,p));
1262 *q++=ScaleQuantumToLong(GetPixelBlue(image,p));
1263 *q++=0;
cristye5370942012-01-06 03:49:31 +00001264 p+=GetPixelChannels(image);
1265 }
1266 }
1267 return;
1268 }
cristy14d71292012-05-20 16:48:13 +00001269 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001270 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001271 {
cristycafe0412012-01-10 13:29:58 +00001272 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001273 if (p == (const Quantum *) NULL)
1274 break;
cristycafe0412012-01-10 13:29:58 +00001275 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001276 {
1277 register ssize_t
1278 i;
1279
cristy14d71292012-05-20 16:48:13 +00001280 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001281 {
1282 *q=0;
1283 switch (quantum_map[i])
1284 {
1285 case RedQuantum:
1286 case CyanQuantum:
1287 {
cristy6c9e1682012-01-07 21:37:44 +00001288 *q=ScaleQuantumToLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001289 break;
1290 }
1291 case GreenQuantum:
1292 case MagentaQuantum:
1293 {
cristy6c9e1682012-01-07 21:37:44 +00001294 *q=ScaleQuantumToLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001295 break;
1296 }
1297 case BlueQuantum:
1298 case YellowQuantum:
1299 {
cristy6c9e1682012-01-07 21:37:44 +00001300 *q=ScaleQuantumToLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001301 break;
1302 }
1303 case AlphaQuantum:
1304 {
cristy6c9e1682012-01-07 21:37:44 +00001305 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001306 break;
1307 }
1308 case OpacityQuantum:
1309 {
cristy6c9e1682012-01-07 21:37:44 +00001310 *q=ScaleQuantumToLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001311 break;
1312 }
1313 case BlackQuantum:
1314 {
1315 if (image->colorspace == CMYKColorspace)
cristy6c9e1682012-01-07 21:37:44 +00001316 *q=ScaleQuantumToLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001317 break;
1318 }
1319 case IndexQuantum:
1320 {
cristy70e9f682013-03-12 22:31:22 +00001321 *q=ScaleQuantumToLong(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001322 break;
1323 }
1324 default:
cristy6c9e1682012-01-07 21:37:44 +00001325 break;
cristye5370942012-01-06 03:49:31 +00001326 }
1327 q++;
1328 }
1329 p+=GetPixelChannels(image);
1330 }
1331 }
1332}
1333
dirk39fee9a2016-01-09 12:09:47 +01001334static void ExportLongLongPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01001335 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +00001336 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001337{
1338 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001339 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00001340
1341 register ssize_t
1342 x;
1343
cristyb13e12a2012-01-06 21:48:27 +00001344 register MagickSizeType
dirk05d2ff72015-11-18 23:13:43 +01001345 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00001346
cristy14d71292012-05-20 16:48:13 +00001347 size_t
1348 length;
1349
cristye5370942012-01-06 03:49:31 +00001350 ssize_t
1351 y;
1352
cristyb13e12a2012-01-06 21:48:27 +00001353 q=(MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00001354 if (LocaleCompare(map,"BGR") == 0)
1355 {
cristycafe0412012-01-10 13:29:58 +00001356 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001357 {
cristycafe0412012-01-10 13:29:58 +00001358 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001359 if (p == (const Quantum *) NULL)
1360 break;
cristycafe0412012-01-10 13:29:58 +00001361 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001362 {
cristyb13e12a2012-01-06 21:48:27 +00001363 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1364 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1365 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001366 p+=GetPixelChannels(image);
1367 }
1368 }
1369 return;
1370 }
1371 if (LocaleCompare(map,"BGRA") == 0)
1372 {
cristycafe0412012-01-10 13:29:58 +00001373 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001374 {
cristycafe0412012-01-10 13:29:58 +00001375 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001376 if (p == (const Quantum *) NULL)
1377 break;
cristycafe0412012-01-10 13:29:58 +00001378 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001379 {
cristyb13e12a2012-01-06 21:48:27 +00001380 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1381 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1382 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1383 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001384 p+=GetPixelChannels(image);
1385 }
1386 }
1387 return;
1388 }
1389 if (LocaleCompare(map,"BGRP") == 0)
1390 {
cristycafe0412012-01-10 13:29:58 +00001391 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001392 {
cristycafe0412012-01-10 13:29:58 +00001393 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001394 if (p == (const Quantum *) NULL)
1395 break;
cristycafe0412012-01-10 13:29:58 +00001396 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001397 {
cristyb13e12a2012-01-06 21:48:27 +00001398 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1399 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1400 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001401 *q++=0;
1402 p+=GetPixelChannels(image);
1403 }
1404 }
1405 return;
1406 }
1407 if (LocaleCompare(map,"I") == 0)
1408 {
cristycafe0412012-01-10 13:29:58 +00001409 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001410 {
cristycafe0412012-01-10 13:29:58 +00001411 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001412 if (p == (const Quantum *) NULL)
1413 break;
cristycafe0412012-01-10 13:29:58 +00001414 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001415 {
cristy31e75932015-05-24 18:11:01 +00001416 *q++=ScaleQuantumToLongLong(ClampToQuantum(
1417 GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001418 p+=GetPixelChannels(image);
1419 }
1420 }
1421 return;
1422 }
1423 if (LocaleCompare(map,"RGB") == 0)
1424 {
cristycafe0412012-01-10 13:29:58 +00001425 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001426 {
cristycafe0412012-01-10 13:29:58 +00001427 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001428 if (p == (const Quantum *) NULL)
1429 break;
cristycafe0412012-01-10 13:29:58 +00001430 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001431 {
cristyb13e12a2012-01-06 21:48:27 +00001432 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1433 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1434 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001435 p+=GetPixelChannels(image);
1436 }
1437 }
1438 return;
1439 }
1440 if (LocaleCompare(map,"RGBA") == 0)
1441 {
cristycafe0412012-01-10 13:29:58 +00001442 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001443 {
cristycafe0412012-01-10 13:29:58 +00001444 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001445 if (p == (const Quantum *) NULL)
1446 break;
cristycafe0412012-01-10 13:29:58 +00001447 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001448 {
cristyb13e12a2012-01-06 21:48:27 +00001449 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1450 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1451 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
1452 *q++=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001453 p+=GetPixelChannels(image);
1454 }
1455 }
1456 return;
1457 }
1458 if (LocaleCompare(map,"RGBP") == 0)
1459 {
cristycafe0412012-01-10 13:29:58 +00001460 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001461 {
cristycafe0412012-01-10 13:29:58 +00001462 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001463 if (p == (const Quantum *) NULL)
1464 break;
cristycafe0412012-01-10 13:29:58 +00001465 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001466 {
cristyb13e12a2012-01-06 21:48:27 +00001467 *q++=ScaleQuantumToLongLong(GetPixelRed(image,p));
1468 *q++=ScaleQuantumToLongLong(GetPixelGreen(image,p));
1469 *q++=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001470 *q++=0;
1471 p+=GetPixelChannels(image);
1472 }
1473 }
1474 return;
1475 }
cristy14d71292012-05-20 16:48:13 +00001476 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001477 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001478 {
cristycafe0412012-01-10 13:29:58 +00001479 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001480 if (p == (const Quantum *) NULL)
1481 break;
cristycafe0412012-01-10 13:29:58 +00001482 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001483 {
1484 register ssize_t
1485 i;
1486
cristy14d71292012-05-20 16:48:13 +00001487 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001488 {
1489 *q=0;
1490 switch (quantum_map[i])
1491 {
1492 case RedQuantum:
1493 case CyanQuantum:
1494 {
cristyb13e12a2012-01-06 21:48:27 +00001495 *q=ScaleQuantumToLongLong(GetPixelRed(image,p));
cristye5370942012-01-06 03:49:31 +00001496 break;
1497 }
1498 case GreenQuantum:
1499 case MagentaQuantum:
1500 {
cristyb13e12a2012-01-06 21:48:27 +00001501 *q=ScaleQuantumToLongLong(GetPixelGreen(image,p));
cristye5370942012-01-06 03:49:31 +00001502 break;
1503 }
1504 case BlueQuantum:
1505 case YellowQuantum:
1506 {
cristyb13e12a2012-01-06 21:48:27 +00001507 *q=ScaleQuantumToLongLong(GetPixelBlue(image,p));
cristye5370942012-01-06 03:49:31 +00001508 break;
1509 }
1510 case AlphaQuantum:
1511 {
cristyb13e12a2012-01-06 21:48:27 +00001512 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001513 break;
1514 }
1515 case OpacityQuantum:
1516 {
cristyb13e12a2012-01-06 21:48:27 +00001517 *q=ScaleQuantumToLongLong(GetPixelAlpha(image,p));
cristye5370942012-01-06 03:49:31 +00001518 break;
1519 }
1520 case BlackQuantum:
1521 {
1522 if (image->colorspace == CMYKColorspace)
cristyb13e12a2012-01-06 21:48:27 +00001523 *q=ScaleQuantumToLongLong(GetPixelBlack(image,p));
cristye5370942012-01-06 03:49:31 +00001524 break;
1525 }
1526 case IndexQuantum:
1527 {
cristy58ee5012013-05-26 23:58:44 +00001528 *q=ScaleQuantumToLongLong(ClampToQuantum(
1529 GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001530 break;
1531 }
1532 default:
1533 break;
1534 }
1535 q++;
1536 }
1537 p+=GetPixelChannels(image);
1538 }
1539 }
1540}
1541
dirk39fee9a2016-01-09 12:09:47 +01001542static void ExportQuantumPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01001543 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +00001544 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001545{
1546 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001547 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00001548
1549 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01001550 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00001551
1552 register ssize_t
1553 x;
1554
cristy14d71292012-05-20 16:48:13 +00001555 size_t
1556 length;
1557
cristye5370942012-01-06 03:49:31 +00001558 ssize_t
1559 y;
1560
1561 q=(Quantum *) pixels;
1562 if (LocaleCompare(map,"BGR") == 0)
1563 {
cristycafe0412012-01-10 13:29:58 +00001564 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001565 {
cristycafe0412012-01-10 13:29:58 +00001566 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001567 if (p == (const Quantum *) NULL)
1568 break;
cristycafe0412012-01-10 13:29:58 +00001569 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001570 {
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 {
cristycafe0412012-01-10 13:29:58 +00001581 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001582 {
cristycafe0412012-01-10 13:29:58 +00001583 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001584 if (p == (const Quantum *) NULL)
1585 break;
cristycafe0412012-01-10 13:29:58 +00001586 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001587 {
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 {
cristycafe0412012-01-10 13:29:58 +00001599 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001600 {
cristycafe0412012-01-10 13:29:58 +00001601 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001602 if (p == (const Quantum *) NULL)
1603 break;
cristycafe0412012-01-10 13:29:58 +00001604 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001605 {
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 {
cristycafe0412012-01-10 13:29:58 +00001617 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001618 {
cristycafe0412012-01-10 13:29:58 +00001619 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001620 if (p == (const Quantum *) NULL)
1621 break;
cristycafe0412012-01-10 13:29:58 +00001622 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001623 {
cristy70e9f682013-03-12 22:31:22 +00001624 *q++=ClampToQuantum(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001625 p+=GetPixelChannels(image);
1626 }
1627 }
1628 return;
1629 }
1630 if (LocaleCompare(map,"RGB") == 0)
1631 {
cristycafe0412012-01-10 13:29:58 +00001632 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001633 {
cristycafe0412012-01-10 13:29:58 +00001634 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001635 if (p == (const Quantum *) NULL)
1636 break;
cristycafe0412012-01-10 13:29:58 +00001637 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001638 {
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 {
cristycafe0412012-01-10 13:29:58 +00001649 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001650 {
cristycafe0412012-01-10 13:29:58 +00001651 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001652 if (p == (const Quantum *) NULL)
1653 break;
cristycafe0412012-01-10 13:29:58 +00001654 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001655 {
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 {
cristycafe0412012-01-10 13:29:58 +00001667 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001668 {
cristycafe0412012-01-10 13:29:58 +00001669 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001670 if (p == (const Quantum *) NULL)
1671 break;
cristycafe0412012-01-10 13:29:58 +00001672 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001673 {
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 }
cristy14d71292012-05-20 16:48:13 +00001683 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001684 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001685 {
cristycafe0412012-01-10 13:29:58 +00001686 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001687 if (p == (const Quantum *) NULL)
1688 break;
cristycafe0412012-01-10 13:29:58 +00001689 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001690 {
1691 register ssize_t
1692 i;
1693
cristy14d71292012-05-20 16:48:13 +00001694 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001695 {
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 {
cristy70e9f682013-03-12 22:31:22 +00001735 *q=ClampToQuantum(GetPixelIntensity(image,p));
cristye5370942012-01-06 03:49:31 +00001736 break;
1737 }
1738 default:
1739 {
1740 *q=(Quantum) 0;
1741 break;
1742 }
1743 }
1744 q++;
1745 }
1746 p+=GetPixelChannels(image);
1747 }
1748 }
1749}
1750
dirk39fee9a2016-01-09 12:09:47 +01001751static void ExportShortPixel(const Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01001752 const char *magick_restrict map,const QuantumType *quantum_map,void *pixels,
cristy46f4be22012-01-07 00:26:39 +00001753 ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00001754{
1755 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01001756 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00001757
1758 register ssize_t
1759 x;
1760
cristye5370942012-01-06 03:49:31 +00001761 register unsigned short
dirk05d2ff72015-11-18 23:13:43 +01001762 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00001763
cristy14d71292012-05-20 16:48:13 +00001764 size_t
1765 length;
1766
1767 ssize_t
1768 y;
1769
cristye5370942012-01-06 03:49:31 +00001770 q=(unsigned short *) pixels;
1771 if (LocaleCompare(map,"BGR") == 0)
1772 {
cristycafe0412012-01-10 13:29:58 +00001773 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001774 {
cristycafe0412012-01-10 13:29:58 +00001775 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001776 if (p == (const Quantum *) NULL)
1777 break;
cristycafe0412012-01-10 13:29:58 +00001778 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001779 {
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 {
cristycafe0412012-01-10 13:29:58 +00001790 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001791 {
cristycafe0412012-01-10 13:29:58 +00001792 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001793 if (p == (const Quantum *) NULL)
1794 break;
cristycafe0412012-01-10 13:29:58 +00001795 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001796 {
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 {
cristycafe0412012-01-10 13:29:58 +00001808 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001809 {
cristycafe0412012-01-10 13:29:58 +00001810 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001811 if (p == (const Quantum *) NULL)
1812 break;
cristycafe0412012-01-10 13:29:58 +00001813 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001814 {
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 {
cristycafe0412012-01-10 13:29:58 +00001826 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001827 {
cristycafe0412012-01-10 13:29:58 +00001828 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001829 if (p == (const Quantum *) NULL)
1830 break;
cristycafe0412012-01-10 13:29:58 +00001831 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001832 {
cristy70e9f682013-03-12 22:31:22 +00001833 *q++=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001834 p+=GetPixelChannels(image);
1835 }
1836 }
1837 return;
1838 }
1839 if (LocaleCompare(map,"RGB") == 0)
1840 {
cristycafe0412012-01-10 13:29:58 +00001841 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001842 {
cristycafe0412012-01-10 13:29:58 +00001843 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001844 if (p == (const Quantum *) NULL)
1845 break;
cristycafe0412012-01-10 13:29:58 +00001846 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001847 {
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 {
cristycafe0412012-01-10 13:29:58 +00001858 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001859 {
cristycafe0412012-01-10 13:29:58 +00001860 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001861 if (p == (const Quantum *) NULL)
1862 break;
cristycafe0412012-01-10 13:29:58 +00001863 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001864 {
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 {
cristycafe0412012-01-10 13:29:58 +00001876 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001877 {
cristycafe0412012-01-10 13:29:58 +00001878 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001879 if (p == (const Quantum *) NULL)
1880 break;
cristycafe0412012-01-10 13:29:58 +00001881 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001882 {
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 }
cristy14d71292012-05-20 16:48:13 +00001892 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00001893 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00001894 {
cristycafe0412012-01-10 13:29:58 +00001895 p=GetVirtualPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00001896 if (p == (const Quantum *) NULL)
1897 break;
cristycafe0412012-01-10 13:29:58 +00001898 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00001899 {
1900 register ssize_t
1901 i;
1902
cristy14d71292012-05-20 16:48:13 +00001903 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00001904 {
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 {
cristy70e9f682013-03-12 22:31:22 +00001944 *q=ScaleQuantumToShort(ClampToQuantum(GetPixelIntensity(image,p)));
cristye5370942012-01-06 03:49:31 +00001945 break;
1946 }
1947 default:
1948 break;
1949 }
1950 q++;
1951 }
1952 p+=GetPixelChannels(image);
1953 }
1954 }
1955}
1956
dirk39fee9a2016-01-09 12:09:47 +01001957MagickExport MagickBooleanType ExportImagePixels(const Image *image,const ssize_t x,
cristy58ee5012013-05-26 23:58:44 +00001958 const ssize_t y,const size_t width,const size_t height,const char *map,
1959 const StorageType type,void *pixels,ExceptionInfo *exception)
cristy4c08aed2011-07-01 19:47:50 +00001960{
1961 QuantumType
1962 *quantum_map;
1963
cristycafe0412012-01-10 13:29:58 +00001964 RectangleInfo
1965 roi;
1966
cristy4c08aed2011-07-01 19:47:50 +00001967 register ssize_t
cristye5370942012-01-06 03:49:31 +00001968 i;
cristy4c08aed2011-07-01 19:47:50 +00001969
cristy14d71292012-05-20 16:48:13 +00001970 size_t
1971 length;
1972
cristy4c08aed2011-07-01 19:47:50 +00001973 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00001974 assert(image->signature == MagickCoreSignature);
cristy4c08aed2011-07-01 19:47:50 +00001975 if (image->debug != MagickFalse)
1976 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00001977 length=strlen(map);
1978 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00001979 if (quantum_map == (QuantumType *) NULL)
1980 {
1981 (void) ThrowMagickException(exception,GetMagickModule(),
cristyefe601c2013-01-05 17:51:12 +00001982 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
cristy4c08aed2011-07-01 19:47:50 +00001983 return(MagickFalse);
1984 }
cristy14d71292012-05-20 16:48:13 +00001985 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00001986 {
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,
cristyefe601c2013-01-05 17:51:12 +00002009 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002010 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,
cristyefe601c2013-01-05 17:51:12 +00002032 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002033 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,
cristyefe601c2013-01-05 17:51:12 +00002043 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002044 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,
cristyefe601c2013-01-05 17:51:12 +00002072 "ColorSeparatedImageRequired","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002073 return(MagickFalse);
2074 }
2075 default:
2076 {
2077 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2078 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00002079 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002080 return(MagickFalse);
2081 }
2082 }
2083 }
cristycafe0412012-01-10 13:29:58 +00002084 roi.width=width;
2085 roi.height=height;
2086 roi.x=x;
2087 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00002088 switch (type)
2089 {
2090 case CharPixel:
2091 {
cristycafe0412012-01-10 13:29:58 +00002092 ExportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002093 break;
2094 }
2095 case DoublePixel:
2096 {
cristycafe0412012-01-10 13:29:58 +00002097 ExportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002098 break;
2099 }
2100 case FloatPixel:
2101 {
cristycafe0412012-01-10 13:29:58 +00002102 ExportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002103 break;
2104 }
cristy4c08aed2011-07-01 19:47:50 +00002105 case LongPixel:
2106 {
cristycafe0412012-01-10 13:29:58 +00002107 ExportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002108 break;
2109 }
cristy6c9e1682012-01-07 21:37:44 +00002110 case LongLongPixel:
2111 {
cristycafe0412012-01-10 13:29:58 +00002112 ExportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00002113 break;
2114 }
cristy4c08aed2011-07-01 19:47:50 +00002115 case QuantumPixel:
2116 {
cristycafe0412012-01-10 13:29:58 +00002117 ExportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002118 break;
2119 }
2120 case ShortPixel:
2121 {
cristycafe0412012-01-10 13:29:58 +00002122 ExportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00002123 break;
2124 }
2125 default:
2126 {
2127 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2128 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00002129 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00002130 break;
2131 }
2132 }
2133 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
2134 return(MagickTrue);
2135}
2136
2137/*
2138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2139% %
2140% %
2141% %
cristyaa8634f2011-10-01 13:25:12 +00002142% G e t P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00002143% %
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%
anthonya322a832013-04-27 06:28:03 +00002156% o image: the image. (optional - may be NULL)
cristy4c08aed2011-07-01 19:47:50 +00002157%
cristy101ab702011-10-13 13:06:32 +00002158% o pixel: Specifies a pointer to a PixelInfo structure.
cristy4c08aed2011-07-01 19:47:50 +00002159%
2160*/
cristyaa8634f2011-10-01 13:25:12 +00002161MagickExport void GetPixelInfo(const Image *image,PixelInfo *pixel)
cristy4c08aed2011-07-01 19:47:50 +00002162{
2163 pixel->storage_class=DirectClass;
cristy7020ae62012-04-18 12:58:34 +00002164 pixel->colorspace=sRGBColorspace;
cristy8a46d822012-08-28 23:32:39 +00002165 pixel->alpha_trait=UndefinedPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00002166 pixel->fuzz=0.0;
2167 pixel->depth=MAGICKCORE_QUANTUM_DEPTH;
2168 pixel->red=0.0;
2169 pixel->green=0.0;
2170 pixel->blue=0.0;
2171 pixel->black=0.0;
cristya19f1d72012-08-07 18:24:38 +00002172 pixel->alpha=(double) OpaqueAlpha;
cristy4c08aed2011-07-01 19:47:50 +00002173 pixel->index=0.0;
cristyf2a82ee2014-05-26 17:49:54 +00002174 pixel->count=0;
2175 pixel->fuzz=0.0;
cristy4c08aed2011-07-01 19:47:50 +00002176 if (image == (const Image *) NULL)
2177 return;
2178 pixel->storage_class=image->storage_class;
2179 pixel->colorspace=image->colorspace;
cristy8a46d822012-08-28 23:32:39 +00002180 pixel->alpha_trait=image->alpha_trait;
cristy4c08aed2011-07-01 19:47:50 +00002181 pixel->depth=image->depth;
2182 pixel->fuzz=image->fuzz;
2183}
2184
2185/*
2186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2187% %
2188% %
2189% %
cristy11a06d32015-01-04 12:03:27 +00002190% 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*/
dirk05d2ff72015-11-18 23:13:43 +01002222MagickExport MagickRealType GetPixelInfoIntensity(
2223 const Image *magick_restrict image,const PixelInfo *magick_restrict pixel)
cristy11a06d32015-01-04 12:03:27 +00002224{
2225 MagickRealType
2226 blue,
2227 green,
2228 red,
2229 intensity;
2230
2231 PixelIntensityMethod
2232 method;
2233
2234 method=Rec709LumaPixelIntensityMethod;
dirkfff909e2015-05-25 08:44:35 +00002235 if (image != (const Image *) NULL)
Cristy73323e72015-09-19 07:55:24 -04002236 method=image->intensity;
2237 red=pixel->red;
2238 green=pixel->green;
2239 blue=pixel->blue;
cristy11a06d32015-01-04 12:03:27 +00002240 switch (method)
2241 {
2242 case AveragePixelIntensityMethod:
2243 {
2244 intensity=(red+green+blue)/3.0;
2245 break;
2246 }
2247 case BrightnessPixelIntensityMethod:
2248 {
2249 intensity=MagickMax(MagickMax(red,green),blue);
2250 break;
2251 }
2252 case LightnessPixelIntensityMethod:
2253 {
2254 intensity=(MagickMin(MagickMin(red,green),blue)+
2255 MagickMax(MagickMax(red,green),blue))/2.0;
2256 break;
2257 }
2258 case MSPixelIntensityMethod:
2259 {
2260 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2261 (3.0*QuantumRange));
2262 break;
2263 }
2264 case Rec601LumaPixelIntensityMethod:
2265 {
2266 if (pixel->colorspace == RGBColorspace)
2267 {
2268 red=EncodePixelGamma(red);
2269 green=EncodePixelGamma(green);
2270 blue=EncodePixelGamma(blue);
2271 }
2272 intensity=0.298839*red+0.586811*green+0.114350*blue;
2273 break;
2274 }
2275 case Rec601LuminancePixelIntensityMethod:
2276 {
2277 if (pixel->colorspace == sRGBColorspace)
2278 {
2279 red=DecodePixelGamma(red);
2280 green=DecodePixelGamma(green);
2281 blue=DecodePixelGamma(blue);
2282 }
2283 intensity=0.298839*red+0.586811*green+0.114350*blue;
2284 break;
2285 }
2286 case Rec709LumaPixelIntensityMethod:
2287 default:
2288 {
2289 if (pixel->colorspace == RGBColorspace)
2290 {
2291 red=EncodePixelGamma(red);
2292 green=EncodePixelGamma(green);
2293 blue=EncodePixelGamma(blue);
2294 }
2295 intensity=0.212656*red+0.715158*green+0.072186*blue;
2296 break;
2297 }
2298 case Rec709LuminancePixelIntensityMethod:
2299 {
2300 if (pixel->colorspace == sRGBColorspace)
2301 {
2302 red=DecodePixelGamma(red);
2303 green=DecodePixelGamma(green);
2304 blue=DecodePixelGamma(blue);
2305 }
2306 intensity=0.212656*red+0.715158*green+0.072186*blue;
2307 break;
2308 }
2309 case RMSPixelIntensityMethod:
2310 {
2311 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2312 sqrt(3.0));
2313 break;
2314 }
2315 }
2316 return(intensity);
2317}
2318
2319/*
2320%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2321% %
2322% %
2323% %
cristy9731df72013-03-12 16:31:13 +00002324% G e t P i x e l I n t e n s i t y %
2325% %
2326% %
2327% %
2328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2329%
cristy0c5c8892013-03-12 16:33:48 +00002330% GetPixelIntensity() returns a single sample intensity value from the red,
cristy70e9f682013-03-12 22:31:22 +00002331% green, and blue components of a pixel based on the selected method:
2332%
cristy2cf5d372013-03-13 12:03:11 +00002333% Rec601Luma 0.298839R' + 0.586811G' + 0.114350B'
2334% Rec601Luminance 0.298839R + 0.586811G + 0.114350B
cristy1352acf2013-06-10 17:16:17 +00002335% Rec709Luma 0.212656R' + 0.715158G' + 0.072186B'
2336% Rec709Luminance 0.212656R + 0.715158G + 0.072186B
cristy09bb0432013-06-01 13:39:18 +00002337% Brightness max(R', G', B')
2338% Lightness (min(R', G', B') + max(R', G', B')) / 2.0
cristy62cc94b2014-12-19 00:30:56 +00002339%
cristy09bb0432013-06-01 13:39:18 +00002340% 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
cristy9731df72013-03-12 16:31:13 +00002343%
2344% The format of the GetPixelIntensity method is:
2345%
cristy2cf5d372013-03-13 12:03:11 +00002346% MagickRealType GetPixelIntensity(const Image *image,
2347% const Quantum *pixel)
cristy9731df72013-03-12 16:31:13 +00002348%
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*/
dirk05d2ff72015-11-18 23:13:43 +01002356MagickExport MagickRealType GetPixelIntensity(const Image *magick_restrict image,
2357 const Quantum *magick_restrict pixel)
cristy9731df72013-03-12 16:31:13 +00002358{
2359 MagickRealType
2360 blue,
2361 green,
cristy70e9f682013-03-12 22:31:22 +00002362 red,
2363 intensity;
cristy9731df72013-03-12 16:31:13 +00002364
Cristy402bc9f2017-02-11 20:38:11 -05002365 red=(MagickRealType) GetPixelRed(image,pixel);
2366 green=(MagickRealType) GetPixelGreen(image,pixel);
2367 blue=(MagickRealType) GetPixelBlue(image,pixel);
cristy70e9f682013-03-12 22:31:22 +00002368 switch (image->intensity)
2369 {
cristybf02d732013-03-13 16:28:58 +00002370 case AveragePixelIntensityMethod:
2371 {
2372 intensity=(red+green+blue)/3.0;
2373 break;
2374 }
2375 case BrightnessPixelIntensityMethod:
2376 {
2377 intensity=MagickMax(MagickMax(red,green),blue);
2378 break;
2379 }
2380 case LightnessPixelIntensityMethod:
2381 {
cristy09bb0432013-06-01 13:39:18 +00002382 intensity=(MagickMin(MagickMin(red,green),blue)+
cristyce326722013-06-01 13:40:28 +00002383 MagickMax(MagickMax(red,green),blue))/2.0;
cristybf02d732013-03-13 16:28:58 +00002384 break;
2385 }
cristy462c1ca2013-04-15 10:29:18 +00002386 case MSPixelIntensityMethod:
2387 {
2388 intensity=(MagickRealType) (((double) red*red+green*green+blue*blue)/
2389 (3.0*QuantumRange));
2390 break;
2391 }
cristy70e9f682013-03-12 22:31:22 +00002392 case Rec601LumaPixelIntensityMethod:
cristy70e9f682013-03-12 22:31:22 +00002393 {
cristy09bb0432013-06-01 13:39:18 +00002394 if (image->colorspace == RGBColorspace)
2395 {
2396 red=EncodePixelGamma(red);
2397 green=EncodePixelGamma(green);
2398 blue=EncodePixelGamma(blue);
2399 }
cristy9e2436a2013-05-02 20:35:59 +00002400 intensity=0.298839*red+0.586811*green+0.114350*blue;
cristy2cf5d372013-03-13 12:03:11 +00002401 break;
2402 }
2403 case Rec601LuminancePixelIntensityMethod:
2404 {
cristy70e9f682013-03-12 22:31:22 +00002405 if (image->colorspace == sRGBColorspace)
2406 {
2407 red=DecodePixelGamma(red);
2408 green=DecodePixelGamma(green);
2409 blue=DecodePixelGamma(blue);
2410 }
cristy9e2436a2013-05-02 20:35:59 +00002411 intensity=0.298839*red+0.586811*green+0.114350*blue;
cristy70e9f682013-03-12 22:31:22 +00002412 break;
2413 }
2414 case Rec709LumaPixelIntensityMethod:
cristyc94210c2013-05-06 14:09:53 +00002415 default:
cristy70e9f682013-03-12 22:31:22 +00002416 {
cristy09bb0432013-06-01 13:39:18 +00002417 if (image->colorspace == RGBColorspace)
2418 {
2419 red=EncodePixelGamma(red);
2420 green=EncodePixelGamma(green);
2421 blue=EncodePixelGamma(blue);
2422 }
cristy1352acf2013-06-10 17:16:17 +00002423 intensity=0.212656*red+0.715158*green+0.072186*blue;
cristy2cf5d372013-03-13 12:03:11 +00002424 break;
2425 }
2426 case Rec709LuminancePixelIntensityMethod:
2427 {
cristy70e9f682013-03-12 22:31:22 +00002428 if (image->colorspace == sRGBColorspace)
2429 {
2430 red=DecodePixelGamma(red);
2431 green=DecodePixelGamma(green);
2432 blue=DecodePixelGamma(blue);
2433 }
cristy1352acf2013-06-10 17:16:17 +00002434 intensity=0.212656*red+0.715158*green+0.072186*blue;
cristy70e9f682013-03-12 22:31:22 +00002435 break;
2436 }
cristy70e9f682013-03-12 22:31:22 +00002437 case RMSPixelIntensityMethod:
2438 {
cristy462c1ca2013-04-15 10:29:18 +00002439 intensity=(MagickRealType) (sqrt((double) red*red+green*green+blue*blue)/
2440 sqrt(3.0));
cristy70e9f682013-03-12 22:31:22 +00002441 break;
2442 }
cristy70e9f682013-03-12 22:31:22 +00002443 }
2444 return(intensity);
cristy9731df72013-03-12 16:31:13 +00002445}
cristy9731df72013-03-12 16:31:13 +00002446
2447/*
2448%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2449% %
2450% %
2451% %
cristy4c08aed2011-07-01 19:47:50 +00002452% 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,
cristyb5a45a32012-01-10 13:31:13 +00002461% Quantum, short int, unsigned int, unsigned long long, float, or double in
2462% the order specified by map.
cristy4c08aed2011-07-01 19:47:50 +00002463%
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%
cristycafe0412012-01-10 13:29:58 +00002471% 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)
cristy4c08aed2011-07-01 19:47:50 +00002475%
2476% A description of each parameter follows:
2477%
2478% o image: the image.
2479%
cristycafe0412012-01-10 13:29:58 +00002480% o x,y,width,height: These values define the perimeter
cristy4c08aed2011-07-01 19:47:50 +00002481% 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
cristy6c9e1682012-01-07 21:37:44 +00002491% types: CharPixel (char *), DoublePixel (double *), FloatPixel (float *),
cristyff6834e2012-01-10 03:00:25 +00002492% LongPixel (unsigned int *), LongLongPixel (unsigned long long *),
cristy6c9e1682012-01-07 21:37:44 +00002493% QuantumPixel (Quantum *), or ShortPixel (unsigned short *).
cristy4c08aed2011-07-01 19:47:50 +00002494%
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%
cristy018f07f2011-09-04 21:15:19 +00002499% o exception: return any errors or warnings in this structure.
2500%
cristy4c08aed2011-07-01 19:47:50 +00002501*/
cristye5370942012-01-06 03:49:31 +00002502
cristycafe0412012-01-10 13:29:58 +00002503static void ImportCharPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01002504 const char *magick_restrict map,const QuantumType *quantum_map,
2505 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002506{
2507 register const unsigned char
dirk05d2ff72015-11-18 23:13:43 +01002508 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00002509
2510 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01002511 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00002512
2513 register ssize_t
2514 x;
2515
cristy14d71292012-05-20 16:48:13 +00002516 size_t
2517 length;
2518
cristye5370942012-01-06 03:49:31 +00002519 ssize_t
2520 y;
2521
2522 p=(const unsigned char *) pixels;
2523 if (LocaleCompare(map,"BGR") == 0)
2524 {
cristycafe0412012-01-10 13:29:58 +00002525 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002526 {
cristycafe0412012-01-10 13:29:58 +00002527 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002528 if (q == (Quantum *) NULL)
2529 break;
cristycafe0412012-01-10 13:29:58 +00002530 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002531 {
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 {
cristycafe0412012-01-10 13:29:58 +00002544 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002545 {
cristycafe0412012-01-10 13:29:58 +00002546 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002547 if (q == (Quantum *) NULL)
2548 break;
cristycafe0412012-01-10 13:29:58 +00002549 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002550 {
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 {
cristycafe0412012-01-10 13:29:58 +00002564 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002565 {
cristycafe0412012-01-10 13:29:58 +00002566 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002567 if (q == (Quantum *) NULL)
2568 break;
cristycafe0412012-01-10 13:29:58 +00002569 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002570 {
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 {
cristycafe0412012-01-10 13:29:58 +00002584 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002585 {
cristycafe0412012-01-10 13:29:58 +00002586 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002587 if (q == (Quantum *) NULL)
2588 break;
cristycafe0412012-01-10 13:29:58 +00002589 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002590 {
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 {
cristycafe0412012-01-10 13:29:58 +00002604 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002605 {
cristycafe0412012-01-10 13:29:58 +00002606 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002607 if (q == (Quantum *) NULL)
2608 break;
cristycafe0412012-01-10 13:29:58 +00002609 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002610 {
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 {
cristycafe0412012-01-10 13:29:58 +00002621 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002622 {
cristycafe0412012-01-10 13:29:58 +00002623 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002624 if (q == (Quantum *) NULL)
2625 break;
cristycafe0412012-01-10 13:29:58 +00002626 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002627 {
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 {
cristycafe0412012-01-10 13:29:58 +00002640 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002641 {
cristycafe0412012-01-10 13:29:58 +00002642 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002643 if (q == (Quantum *) NULL)
2644 break;
cristycafe0412012-01-10 13:29:58 +00002645 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002646 {
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 {
cristycafe0412012-01-10 13:29:58 +00002660 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002661 {
cristycafe0412012-01-10 13:29:58 +00002662 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002663 if (q == (Quantum *) NULL)
2664 break;
cristycafe0412012-01-10 13:29:58 +00002665 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002666 {
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 {
cristycafe0412012-01-10 13:29:58 +00002680 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002681 {
cristycafe0412012-01-10 13:29:58 +00002682 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002683 if (q == (Quantum *) NULL)
2684 break;
cristycafe0412012-01-10 13:29:58 +00002685 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002686 {
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 }
cristy14d71292012-05-20 16:48:13 +00002698 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002699 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002700 {
cristycafe0412012-01-10 13:29:58 +00002701 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002702 if (q == (Quantum *) NULL)
2703 break;
cristycafe0412012-01-10 13:29:58 +00002704 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002705 {
2706 register ssize_t
2707 i;
2708
cristy14d71292012-05-20 16:48:13 +00002709 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002710 {
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
cristycafe0412012-01-10 13:29:58 +00002763static void ImportDoublePixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01002764 const char *magick_restrict map,const QuantumType *quantum_map,
2765 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00002766{
2767 register const double
dirk05d2ff72015-11-18 23:13:43 +01002768 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00002769
2770 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01002771 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00002772
2773 register ssize_t
2774 x;
2775
cristy14d71292012-05-20 16:48:13 +00002776 size_t
2777 length;
2778
cristye5370942012-01-06 03:49:31 +00002779 ssize_t
2780 y;
2781
2782 p=(const double *) pixels;
2783 if (LocaleCompare(map,"BGR") == 0)
2784 {
cristycafe0412012-01-10 13:29:58 +00002785 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002786 {
cristycafe0412012-01-10 13:29:58 +00002787 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002788 if (q == (Quantum *) NULL)
2789 break;
cristycafe0412012-01-10 13:29:58 +00002790 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002791 {
cristy8cd03c32012-07-07 18:57:59 +00002792 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002793 p++;
cristy8cd03c32012-07-07 18:57:59 +00002794 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002795 p++;
cristy8cd03c32012-07-07 18:57:59 +00002796 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002797 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 {
cristycafe0412012-01-10 13:29:58 +00002807 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002808 {
cristycafe0412012-01-10 13:29:58 +00002809 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002810 if (q == (Quantum *) NULL)
2811 break;
cristycafe0412012-01-10 13:29:58 +00002812 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002813 {
cristy8cd03c32012-07-07 18:57:59 +00002814 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002815 p++;
cristy8cd03c32012-07-07 18:57:59 +00002816 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002817 p++;
cristy8cd03c32012-07-07 18:57:59 +00002818 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002819 p++;
cristy8cd03c32012-07-07 18:57:59 +00002820 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002821 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 {
cristycafe0412012-01-10 13:29:58 +00002831 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002832 {
cristycafe0412012-01-10 13:29:58 +00002833 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002834 if (q == (Quantum *) NULL)
2835 break;
cristycafe0412012-01-10 13:29:58 +00002836 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002837 {
cristy8cd03c32012-07-07 18:57:59 +00002838 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002839 p++;
cristy8cd03c32012-07-07 18:57:59 +00002840 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002841 p++;
cristy8cd03c32012-07-07 18:57:59 +00002842 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002843 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 {
cristycafe0412012-01-10 13:29:58 +00002854 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002855 {
cristycafe0412012-01-10 13:29:58 +00002856 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002857 if (q == (Quantum *) NULL)
2858 break;
cristycafe0412012-01-10 13:29:58 +00002859 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002860 {
cristy8cd03c32012-07-07 18:57:59 +00002861 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002862 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 {
cristycafe0412012-01-10 13:29:58 +00002872 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002873 {
cristycafe0412012-01-10 13:29:58 +00002874 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002875 if (q == (Quantum *) NULL)
2876 break;
cristycafe0412012-01-10 13:29:58 +00002877 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002878 {
cristy8cd03c32012-07-07 18:57:59 +00002879 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002880 p++;
cristy8cd03c32012-07-07 18:57:59 +00002881 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002882 p++;
cristy8cd03c32012-07-07 18:57:59 +00002883 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002884 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 {
cristycafe0412012-01-10 13:29:58 +00002894 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002895 {
cristycafe0412012-01-10 13:29:58 +00002896 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002897 if (q == (Quantum *) NULL)
2898 break;
cristycafe0412012-01-10 13:29:58 +00002899 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002900 {
cristy8cd03c32012-07-07 18:57:59 +00002901 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002902 p++;
cristy8cd03c32012-07-07 18:57:59 +00002903 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002904 p++;
cristy8cd03c32012-07-07 18:57:59 +00002905 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002906 p++;
cristy8cd03c32012-07-07 18:57:59 +00002907 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002908 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 {
cristycafe0412012-01-10 13:29:58 +00002918 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002919 {
cristycafe0412012-01-10 13:29:58 +00002920 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002921 if (q == (Quantum *) NULL)
2922 break;
cristycafe0412012-01-10 13:29:58 +00002923 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002924 {
cristy8cd03c32012-07-07 18:57:59 +00002925 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002926 p++;
cristy8cd03c32012-07-07 18:57:59 +00002927 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002928 p++;
cristy8cd03c32012-07-07 18:57:59 +00002929 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002930 p++;
2931 q+=GetPixelChannels(image);
2932 }
2933 if (SyncAuthenticPixels(image,exception) == MagickFalse)
2934 break;
2935 }
2936 return;
2937 }
cristy14d71292012-05-20 16:48:13 +00002938 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00002939 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00002940 {
cristycafe0412012-01-10 13:29:58 +00002941 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00002942 if (q == (Quantum *) NULL)
2943 break;
cristycafe0412012-01-10 13:29:58 +00002944 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00002945 {
2946 register ssize_t
2947 i;
2948
cristy14d71292012-05-20 16:48:13 +00002949 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00002950 {
2951 switch (quantum_map[i])
2952 {
2953 case RedQuantum:
2954 case CyanQuantum:
2955 {
cristy8cd03c32012-07-07 18:57:59 +00002956 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002957 break;
2958 }
2959 case GreenQuantum:
2960 case MagentaQuantum:
2961 {
cristy8cd03c32012-07-07 18:57:59 +00002962 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002963 break;
2964 }
2965 case BlueQuantum:
2966 case YellowQuantum:
2967 {
cristy8cd03c32012-07-07 18:57:59 +00002968 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002969 break;
2970 }
2971 case AlphaQuantum:
2972 {
cristy8cd03c32012-07-07 18:57:59 +00002973 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002974 break;
2975 }
2976 case OpacityQuantum:
2977 {
cristy8cd03c32012-07-07 18:57:59 +00002978 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002979 break;
2980 }
2981 case BlackQuantum:
2982 {
cristy8cd03c32012-07-07 18:57:59 +00002983 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002984 break;
2985 }
2986 case IndexQuantum:
2987 {
cristy8cd03c32012-07-07 18:57:59 +00002988 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00002989 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
cristycafe0412012-01-10 13:29:58 +00003003static void ImportFloatPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01003004 const char *magick_restrict map,const QuantumType *quantum_map,
3005 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003006{
3007 register const float
dirk05d2ff72015-11-18 23:13:43 +01003008 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00003009
3010 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01003011 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00003012
3013 register ssize_t
3014 x;
3015
cristy14d71292012-05-20 16:48:13 +00003016 size_t
3017 length;
3018
cristye5370942012-01-06 03:49:31 +00003019 ssize_t
3020 y;
3021
3022 p=(const float *) pixels;
3023 if (LocaleCompare(map,"BGR") == 0)
3024 {
cristycafe0412012-01-10 13:29:58 +00003025 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003026 {
cristycafe0412012-01-10 13:29:58 +00003027 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003028 if (q == (Quantum *) NULL)
3029 break;
cristycafe0412012-01-10 13:29:58 +00003030 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003031 {
cristy8cd03c32012-07-07 18:57:59 +00003032 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003033 p++;
cristy8cd03c32012-07-07 18:57:59 +00003034 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003035 p++;
cristy8cd03c32012-07-07 18:57:59 +00003036 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003037 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 {
cristycafe0412012-01-10 13:29:58 +00003047 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003048 {
cristycafe0412012-01-10 13:29:58 +00003049 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003050 if (q == (Quantum *) NULL)
3051 break;
cristycafe0412012-01-10 13:29:58 +00003052 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003053 {
cristy8cd03c32012-07-07 18:57:59 +00003054 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003055 p++;
cristy8cd03c32012-07-07 18:57:59 +00003056 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003057 p++;
cristy8cd03c32012-07-07 18:57:59 +00003058 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003059 p++;
cristy8cd03c32012-07-07 18:57:59 +00003060 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003061 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 {
cristycafe0412012-01-10 13:29:58 +00003071 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003072 {
cristycafe0412012-01-10 13:29:58 +00003073 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003074 if (q == (Quantum *) NULL)
3075 break;
cristycafe0412012-01-10 13:29:58 +00003076 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003077 {
cristy8cd03c32012-07-07 18:57:59 +00003078 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003079 p++;
cristy8cd03c32012-07-07 18:57:59 +00003080 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003081 p++;
cristy8cd03c32012-07-07 18:57:59 +00003082 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003083 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 {
cristycafe0412012-01-10 13:29:58 +00003094 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003095 {
cristycafe0412012-01-10 13:29:58 +00003096 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003097 if (q == (Quantum *) NULL)
3098 break;
cristycafe0412012-01-10 13:29:58 +00003099 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003100 {
cristy8cd03c32012-07-07 18:57:59 +00003101 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003102 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 {
cristycafe0412012-01-10 13:29:58 +00003112 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003113 {
cristycafe0412012-01-10 13:29:58 +00003114 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003115 if (q == (Quantum *) NULL)
3116 break;
cristycafe0412012-01-10 13:29:58 +00003117 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003118 {
cristy8cd03c32012-07-07 18:57:59 +00003119 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003120 p++;
cristy8cd03c32012-07-07 18:57:59 +00003121 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003122 p++;
cristy8cd03c32012-07-07 18:57:59 +00003123 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003124 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 {
cristycafe0412012-01-10 13:29:58 +00003134 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003135 {
cristycafe0412012-01-10 13:29:58 +00003136 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003137 if (q == (Quantum *) NULL)
3138 break;
cristycafe0412012-01-10 13:29:58 +00003139 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003140 {
cristy8cd03c32012-07-07 18:57:59 +00003141 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003142 p++;
cristy8cd03c32012-07-07 18:57:59 +00003143 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003144 p++;
cristy8cd03c32012-07-07 18:57:59 +00003145 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003146 p++;
cristy8cd03c32012-07-07 18:57:59 +00003147 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003148 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 {
cristycafe0412012-01-10 13:29:58 +00003158 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003159 {
cristycafe0412012-01-10 13:29:58 +00003160 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003161 if (q == (Quantum *) NULL)
3162 break;
cristycafe0412012-01-10 13:29:58 +00003163 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003164 {
cristy8cd03c32012-07-07 18:57:59 +00003165 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003166 p++;
cristy8cd03c32012-07-07 18:57:59 +00003167 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003168 p++;
cristy8cd03c32012-07-07 18:57:59 +00003169 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003170 p++;
3171 q+=GetPixelChannels(image);
3172 }
3173 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3174 break;
3175 }
3176 return;
3177 }
cristy14d71292012-05-20 16:48:13 +00003178 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003179 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003180 {
cristycafe0412012-01-10 13:29:58 +00003181 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003182 if (q == (Quantum *) NULL)
3183 break;
cristycafe0412012-01-10 13:29:58 +00003184 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003185 {
3186 register ssize_t
3187 i;
3188
cristy14d71292012-05-20 16:48:13 +00003189 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003190 {
3191 switch (quantum_map[i])
3192 {
3193 case RedQuantum:
3194 case CyanQuantum:
3195 {
cristy8cd03c32012-07-07 18:57:59 +00003196 SetPixelRed(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003197 break;
3198 }
3199 case GreenQuantum:
3200 case MagentaQuantum:
3201 {
cristy8cd03c32012-07-07 18:57:59 +00003202 SetPixelGreen(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003203 break;
3204 }
3205 case BlueQuantum:
3206 case YellowQuantum:
3207 {
cristy8cd03c32012-07-07 18:57:59 +00003208 SetPixelBlue(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003209 break;
3210 }
3211 case AlphaQuantum:
3212 {
cristy8cd03c32012-07-07 18:57:59 +00003213 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003214 break;
3215 }
3216 case OpacityQuantum:
3217 {
cristy8cd03c32012-07-07 18:57:59 +00003218 SetPixelAlpha(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003219 break;
3220 }
3221 case BlackQuantum:
3222 {
cristy8cd03c32012-07-07 18:57:59 +00003223 SetPixelBlack(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003224 break;
3225 }
3226 case IndexQuantum:
3227 {
cristy8cd03c32012-07-07 18:57:59 +00003228 SetPixelGray(image,ClampToQuantum(QuantumRange*(*p)),q);
cristye5370942012-01-06 03:49:31 +00003229 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
cristycafe0412012-01-10 13:29:58 +00003243static void ImportLongPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01003244 const char *magick_restrict map,const QuantumType *quantum_map,
3245 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003246{
3247 register const unsigned int
dirk05d2ff72015-11-18 23:13:43 +01003248 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00003249
3250 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01003251 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00003252
3253 register ssize_t
3254 x;
3255
cristy14d71292012-05-20 16:48:13 +00003256 size_t
3257 length;
3258
cristye5370942012-01-06 03:49:31 +00003259 ssize_t
3260 y;
3261
3262 p=(const unsigned int *) pixels;
3263 if (LocaleCompare(map,"BGR") == 0)
3264 {
cristycafe0412012-01-10 13:29:58 +00003265 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003266 {
cristycafe0412012-01-10 13:29:58 +00003267 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003268 if (q == (Quantum *) NULL)
3269 break;
cristycafe0412012-01-10 13:29:58 +00003270 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003271 {
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 {
cristycafe0412012-01-10 13:29:58 +00003284 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003285 {
cristycafe0412012-01-10 13:29:58 +00003286 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003287 if (q == (Quantum *) NULL)
3288 break;
cristycafe0412012-01-10 13:29:58 +00003289 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003290 {
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 {
cristycafe0412012-01-10 13:29:58 +00003304 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003305 {
cristycafe0412012-01-10 13:29:58 +00003306 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003307 if (q == (Quantum *) NULL)
3308 break;
cristycafe0412012-01-10 13:29:58 +00003309 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003310 {
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 {
cristycafe0412012-01-10 13:29:58 +00003324 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003325 {
cristycafe0412012-01-10 13:29:58 +00003326 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003327 if (q == (Quantum *) NULL)
3328 break;
cristycafe0412012-01-10 13:29:58 +00003329 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003330 {
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 {
cristycafe0412012-01-10 13:29:58 +00003341 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003342 {
cristycafe0412012-01-10 13:29:58 +00003343 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003344 if (q == (Quantum *) NULL)
3345 break;
cristycafe0412012-01-10 13:29:58 +00003346 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003347 {
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 {
cristycafe0412012-01-10 13:29:58 +00003360 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003361 {
cristycafe0412012-01-10 13:29:58 +00003362 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003363 if (q == (Quantum *) NULL)
3364 break;
cristycafe0412012-01-10 13:29:58 +00003365 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003366 {
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 {
cristycafe0412012-01-10 13:29:58 +00003380 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003381 {
cristycafe0412012-01-10 13:29:58 +00003382 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003383 if (q == (Quantum *) NULL)
3384 break;
cristycafe0412012-01-10 13:29:58 +00003385 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003386 {
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 }
cristy14d71292012-05-20 16:48:13 +00003398 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003399 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003400 {
cristycafe0412012-01-10 13:29:58 +00003401 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003402 if (q == (Quantum *) NULL)
3403 break;
cristycafe0412012-01-10 13:29:58 +00003404 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003405 {
3406 register ssize_t
3407 i;
3408
cristy14d71292012-05-20 16:48:13 +00003409 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003410 {
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
cristycafe0412012-01-10 13:29:58 +00003463static void ImportLongLongPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01003464 const char *magick_restrict map,const QuantumType *quantum_map,
3465 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003466{
cristyb13e12a2012-01-06 21:48:27 +00003467 register const MagickSizeType
dirk05d2ff72015-11-18 23:13:43 +01003468 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00003469
3470 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01003471 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00003472
3473 register ssize_t
3474 x;
3475
cristy14d71292012-05-20 16:48:13 +00003476 size_t
3477 length;
3478
cristye5370942012-01-06 03:49:31 +00003479 ssize_t
3480 y;
3481
cristyb13e12a2012-01-06 21:48:27 +00003482 p=(const MagickSizeType *) pixels;
cristye5370942012-01-06 03:49:31 +00003483 if (LocaleCompare(map,"BGR") == 0)
3484 {
cristycafe0412012-01-10 13:29:58 +00003485 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003486 {
cristycafe0412012-01-10 13:29:58 +00003487 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003488 if (q == (Quantum *) NULL)
3489 break;
cristycafe0412012-01-10 13:29:58 +00003490 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003491 {
cristyb13e12a2012-01-06 21:48:27 +00003492 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3493 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3494 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003495 q+=GetPixelChannels(image);
3496 }
3497 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3498 break;
3499 }
3500 return;
3501 }
3502 if (LocaleCompare(map,"BGRA") == 0)
3503 {
cristycafe0412012-01-10 13:29:58 +00003504 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003505 {
cristycafe0412012-01-10 13:29:58 +00003506 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003507 if (q == (Quantum *) NULL)
3508 break;
cristycafe0412012-01-10 13:29:58 +00003509 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003510 {
cristyb13e12a2012-01-06 21:48:27 +00003511 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3512 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3513 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3514 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003515 q+=GetPixelChannels(image);
3516 }
3517 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3518 break;
3519 }
3520 return;
3521 }
3522 if (LocaleCompare(map,"BGRP") == 0)
3523 {
cristycafe0412012-01-10 13:29:58 +00003524 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003525 {
cristycafe0412012-01-10 13:29:58 +00003526 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003527 if (q == (Quantum *) NULL)
3528 break;
cristycafe0412012-01-10 13:29:58 +00003529 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003530 {
cristyb13e12a2012-01-06 21:48:27 +00003531 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3532 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3533 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003534 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 {
cristycafe0412012-01-10 13:29:58 +00003544 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003545 {
cristycafe0412012-01-10 13:29:58 +00003546 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003547 if (q == (Quantum *) NULL)
3548 break;
cristycafe0412012-01-10 13:29:58 +00003549 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003550 {
cristyb13e12a2012-01-06 21:48:27 +00003551 SetPixelGray(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003552 q+=GetPixelChannels(image);
3553 }
3554 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3555 break;
3556 }
3557 return;
3558 }
3559 if (LocaleCompare(map,"RGB") == 0)
3560 {
cristycafe0412012-01-10 13:29:58 +00003561 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003562 {
cristycafe0412012-01-10 13:29:58 +00003563 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003564 if (q == (Quantum *) NULL)
3565 break;
cristycafe0412012-01-10 13:29:58 +00003566 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003567 {
cristyb13e12a2012-01-06 21:48:27 +00003568 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3569 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3570 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003571 q+=GetPixelChannels(image);
3572 }
3573 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3574 break;
3575 }
3576 return;
3577 }
3578 if (LocaleCompare(map,"RGBA") == 0)
3579 {
cristycafe0412012-01-10 13:29:58 +00003580 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003581 {
cristycafe0412012-01-10 13:29:58 +00003582 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003583 if (q == (Quantum *) NULL)
3584 break;
cristycafe0412012-01-10 13:29:58 +00003585 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003586 {
cristyb13e12a2012-01-06 21:48:27 +00003587 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3588 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3589 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
3590 SetPixelAlpha(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003591 q+=GetPixelChannels(image);
3592 }
3593 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3594 break;
3595 }
3596 return;
3597 }
3598 if (LocaleCompare(map,"RGBP") == 0)
3599 {
cristycafe0412012-01-10 13:29:58 +00003600 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003601 {
cristycafe0412012-01-10 13:29:58 +00003602 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003603 if (q == (Quantum *) NULL)
3604 break;
cristycafe0412012-01-10 13:29:58 +00003605 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003606 {
cristyb13e12a2012-01-06 21:48:27 +00003607 SetPixelRed(image,ScaleLongLongToQuantum(*p++),q);
3608 SetPixelGreen(image,ScaleLongLongToQuantum(*p++),q);
3609 SetPixelBlue(image,ScaleLongLongToQuantum(*p++),q);
cristye5370942012-01-06 03:49:31 +00003610 p++;
3611 q+=GetPixelChannels(image);
3612 }
3613 if (SyncAuthenticPixels(image,exception) == MagickFalse)
3614 break;
3615 }
3616 return;
3617 }
cristy14d71292012-05-20 16:48:13 +00003618 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003619 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003620 {
cristycafe0412012-01-10 13:29:58 +00003621 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003622 if (q == (Quantum *) NULL)
3623 break;
cristycafe0412012-01-10 13:29:58 +00003624 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003625 {
3626 register ssize_t
3627 i;
3628
cristy14d71292012-05-20 16:48:13 +00003629 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003630 {
3631 switch (quantum_map[i])
3632 {
3633 case RedQuantum:
3634 case CyanQuantum:
3635 {
cristyb13e12a2012-01-06 21:48:27 +00003636 SetPixelRed(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003637 break;
3638 }
3639 case GreenQuantum:
3640 case MagentaQuantum:
3641 {
cristyb13e12a2012-01-06 21:48:27 +00003642 SetPixelGreen(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003643 break;
3644 }
3645 case BlueQuantum:
3646 case YellowQuantum:
3647 {
cristyb13e12a2012-01-06 21:48:27 +00003648 SetPixelBlue(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003649 break;
3650 }
3651 case AlphaQuantum:
3652 {
cristyb13e12a2012-01-06 21:48:27 +00003653 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003654 break;
3655 }
3656 case OpacityQuantum:
3657 {
cristyb13e12a2012-01-06 21:48:27 +00003658 SetPixelAlpha(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003659 break;
3660 }
3661 case BlackQuantum:
3662 {
cristyb13e12a2012-01-06 21:48:27 +00003663 SetPixelBlack(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003664 break;
3665 }
3666 case IndexQuantum:
3667 {
cristyb13e12a2012-01-06 21:48:27 +00003668 SetPixelGray(image,ScaleLongLongToQuantum(*p),q);
cristye5370942012-01-06 03:49:31 +00003669 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
cristycafe0412012-01-10 13:29:58 +00003683static void ImportQuantumPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01003684 const char *magick_restrict map,const QuantumType *quantum_map,
3685 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003686{
3687 register const Quantum
dirk05d2ff72015-11-18 23:13:43 +01003688 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00003689
3690 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01003691 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00003692
3693 register ssize_t
3694 x;
3695
cristy14d71292012-05-20 16:48:13 +00003696 size_t
3697 length;
3698
cristye5370942012-01-06 03:49:31 +00003699 ssize_t
3700 y;
3701
3702 p=(const Quantum *) pixels;
3703 if (LocaleCompare(map,"BGR") == 0)
3704 {
cristycafe0412012-01-10 13:29:58 +00003705 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003706 {
cristycafe0412012-01-10 13:29:58 +00003707 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003708 if (q == (Quantum *) NULL)
3709 break;
cristycafe0412012-01-10 13:29:58 +00003710 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003711 {
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 {
cristycafe0412012-01-10 13:29:58 +00003724 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003725 {
cristycafe0412012-01-10 13:29:58 +00003726 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003727 if (q == (Quantum *) NULL)
3728 break;
cristycafe0412012-01-10 13:29:58 +00003729 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003730 {
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 {
cristycafe0412012-01-10 13:29:58 +00003744 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003745 {
cristycafe0412012-01-10 13:29:58 +00003746 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003747 if (q == (Quantum *) NULL)
3748 break;
cristycafe0412012-01-10 13:29:58 +00003749 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003750 {
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 {
cristycafe0412012-01-10 13:29:58 +00003764 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003765 {
cristycafe0412012-01-10 13:29:58 +00003766 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003767 if (q == (Quantum *) NULL)
3768 break;
cristycafe0412012-01-10 13:29:58 +00003769 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003770 {
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 {
cristycafe0412012-01-10 13:29:58 +00003781 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003782 {
cristycafe0412012-01-10 13:29:58 +00003783 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003784 if (q == (Quantum *) NULL)
3785 break;
cristycafe0412012-01-10 13:29:58 +00003786 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003787 {
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 {
cristycafe0412012-01-10 13:29:58 +00003800 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003801 {
cristycafe0412012-01-10 13:29:58 +00003802 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003803 if (q == (Quantum *) NULL)
3804 break;
cristycafe0412012-01-10 13:29:58 +00003805 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003806 {
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 {
cristycafe0412012-01-10 13:29:58 +00003820 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003821 {
cristycafe0412012-01-10 13:29:58 +00003822 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003823 if (q == (Quantum *) NULL)
3824 break;
cristycafe0412012-01-10 13:29:58 +00003825 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003826 {
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 }
cristy14d71292012-05-20 16:48:13 +00003838 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00003839 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003840 {
cristycafe0412012-01-10 13:29:58 +00003841 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003842 if (q == (Quantum *) NULL)
3843 break;
cristycafe0412012-01-10 13:29:58 +00003844 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003845 {
3846 register ssize_t
3847 i;
3848
cristy14d71292012-05-20 16:48:13 +00003849 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00003850 {
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
cristycafe0412012-01-10 13:29:58 +00003903static void ImportShortPixel(Image *image,const RectangleInfo *roi,
dirk05d2ff72015-11-18 23:13:43 +01003904 const char *magick_restrict map,const QuantumType *quantum_map,
3905 const void *pixels,ExceptionInfo *exception)
cristye5370942012-01-06 03:49:31 +00003906{
3907 register const unsigned short
dirk05d2ff72015-11-18 23:13:43 +01003908 *magick_restrict p;
cristye5370942012-01-06 03:49:31 +00003909
3910 register Quantum
dirk05d2ff72015-11-18 23:13:43 +01003911 *magick_restrict q;
cristye5370942012-01-06 03:49:31 +00003912
3913 register ssize_t
3914 x;
3915
cristy14d71292012-05-20 16:48:13 +00003916 size_t
3917 length;
3918
cristye5370942012-01-06 03:49:31 +00003919 ssize_t
3920 y;
3921
3922 p=(const unsigned short *) pixels;
3923 if (LocaleCompare(map,"BGR") == 0)
3924 {
cristycafe0412012-01-10 13:29:58 +00003925 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003926 {
cristycafe0412012-01-10 13:29:58 +00003927 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003928 if (q == (Quantum *) NULL)
3929 break;
cristycafe0412012-01-10 13:29:58 +00003930 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003931 {
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 {
cristycafe0412012-01-10 13:29:58 +00003944 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003945 {
cristycafe0412012-01-10 13:29:58 +00003946 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003947 if (q == (Quantum *) NULL)
3948 break;
cristycafe0412012-01-10 13:29:58 +00003949 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003950 {
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 {
cristycafe0412012-01-10 13:29:58 +00003964 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003965 {
cristycafe0412012-01-10 13:29:58 +00003966 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003967 if (q == (Quantum *) NULL)
3968 break;
cristycafe0412012-01-10 13:29:58 +00003969 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003970 {
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 {
cristycafe0412012-01-10 13:29:58 +00003984 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00003985 {
cristycafe0412012-01-10 13:29:58 +00003986 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00003987 if (q == (Quantum *) NULL)
3988 break;
cristycafe0412012-01-10 13:29:58 +00003989 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00003990 {
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 {
cristycafe0412012-01-10 13:29:58 +00004001 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00004002 {
cristycafe0412012-01-10 13:29:58 +00004003 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00004004 if (q == (Quantum *) NULL)
4005 break;
cristycafe0412012-01-10 13:29:58 +00004006 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00004007 {
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 {
cristycafe0412012-01-10 13:29:58 +00004020 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00004021 {
cristycafe0412012-01-10 13:29:58 +00004022 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00004023 if (q == (Quantum *) NULL)
4024 break;
cristycafe0412012-01-10 13:29:58 +00004025 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00004026 {
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 {
cristycafe0412012-01-10 13:29:58 +00004040 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00004041 {
cristycafe0412012-01-10 13:29:58 +00004042 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00004043 if (q == (Quantum *) NULL)
4044 break;
cristycafe0412012-01-10 13:29:58 +00004045 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00004046 {
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 }
cristy14d71292012-05-20 16:48:13 +00004058 length=strlen(map);
cristycafe0412012-01-10 13:29:58 +00004059 for (y=0; y < (ssize_t) roi->height; y++)
cristye5370942012-01-06 03:49:31 +00004060 {
cristycafe0412012-01-10 13:29:58 +00004061 q=GetAuthenticPixels(image,roi->x,roi->y+y,roi->width,1,exception);
cristye5370942012-01-06 03:49:31 +00004062 if (q == (Quantum *) NULL)
4063 break;
cristycafe0412012-01-10 13:29:58 +00004064 for (x=0; x < (ssize_t) roi->width; x++)
cristye5370942012-01-06 03:49:31 +00004065 {
4066 register ssize_t
4067 i;
4068
cristy14d71292012-05-20 16:48:13 +00004069 for (i=0; i < (ssize_t) length; i++)
cristye5370942012-01-06 03:49:31 +00004070 {
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
cristycafe0412012-01-10 13:29:58 +00004123MagickExport MagickBooleanType ImportImagePixels(Image *image,const ssize_t x,
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)
cristy4c08aed2011-07-01 19:47:50 +00004126{
cristy4c08aed2011-07-01 19:47:50 +00004127 QuantumType
4128 *quantum_map;
4129
cristycafe0412012-01-10 13:29:58 +00004130 RectangleInfo
4131 roi;
4132
cristy4c08aed2011-07-01 19:47:50 +00004133 register ssize_t
cristye5370942012-01-06 03:49:31 +00004134 i;
cristy4c08aed2011-07-01 19:47:50 +00004135
cristy14d71292012-05-20 16:48:13 +00004136 size_t
4137 length;
4138
cristy4c08aed2011-07-01 19:47:50 +00004139 /*
4140 Allocate image structure.
4141 */
4142 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004143 assert(image->signature == MagickCoreSignature);
cristy4c08aed2011-07-01 19:47:50 +00004144 if (image->debug != MagickFalse)
4145 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy14d71292012-05-20 16:48:13 +00004146 length=strlen(map);
4147 quantum_map=(QuantumType *) AcquireQuantumMemory(length,sizeof(*quantum_map));
cristy4c08aed2011-07-01 19:47:50 +00004148 if (quantum_map == (QuantumType *) NULL)
4149 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
4150 image->filename);
cristy14d71292012-05-20 16:48:13 +00004151 for (i=0; i < (ssize_t) length; i++)
cristy4c08aed2011-07-01 19:47:50 +00004152 {
4153 switch (map[i])
4154 {
4155 case 'a':
4156 case 'A':
4157 {
4158 quantum_map[i]=AlphaQuantum;
cristy8a46d822012-08-28 23:32:39 +00004159 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00004160 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;
cristy63240882011-08-05 19:05:27 +00004172 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00004173 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;
cristy63240882011-08-05 19:05:27 +00004185 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00004186 break;
4187 }
4188 case 'I':
4189 case 'i':
4190 {
4191 quantum_map[i]=IndexQuantum;
cristyb7b3da62012-07-05 15:43:37 +00004192 (void) SetImageColorspace(image,GRAYColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00004193 break;
4194 }
4195 case 'm':
4196 case 'M':
4197 {
4198 quantum_map[i]=MagentaQuantum;
cristy63240882011-08-05 19:05:27 +00004199 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00004200 break;
4201 }
4202 case 'O':
4203 case 'o':
4204 {
4205 quantum_map[i]=OpacityQuantum;
cristy8a46d822012-08-28 23:32:39 +00004206 image->alpha_trait=BlendPixelTrait;
cristy4c08aed2011-07-01 19:47:50 +00004207 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;
cristy63240882011-08-05 19:05:27 +00004225 (void) SetImageColorspace(image,CMYKColorspace,exception);
cristy4c08aed2011-07-01 19:47:50 +00004226 break;
4227 }
4228 default:
4229 {
4230 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristy63240882011-08-05 19:05:27 +00004231 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
cristyefe601c2013-01-05 17:51:12 +00004232 "UnrecognizedPixelMap","`%s'",map);
cristy4c08aed2011-07-01 19:47:50 +00004233 return(MagickFalse);
4234 }
4235 }
4236 }
cristy63240882011-08-05 19:05:27 +00004237 if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse)
cristy4c08aed2011-07-01 19:47:50 +00004238 return(MagickFalse);
4239 /*
cristye5370942012-01-06 03:49:31 +00004240 Transfer the pixels from the pixel data to the image.
cristy4c08aed2011-07-01 19:47:50 +00004241 */
cristycafe0412012-01-10 13:29:58 +00004242 roi.width=width;
4243 roi.height=height;
4244 roi.x=x;
4245 roi.y=y;
cristy4c08aed2011-07-01 19:47:50 +00004246 switch (type)
4247 {
4248 case CharPixel:
4249 {
cristycafe0412012-01-10 13:29:58 +00004250 ImportCharPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004251 break;
4252 }
4253 case DoublePixel:
4254 {
cristycafe0412012-01-10 13:29:58 +00004255 ImportDoublePixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004256 break;
4257 }
4258 case FloatPixel:
4259 {
cristycafe0412012-01-10 13:29:58 +00004260 ImportFloatPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004261 break;
4262 }
cristy4c08aed2011-07-01 19:47:50 +00004263 case LongPixel:
4264 {
cristycafe0412012-01-10 13:29:58 +00004265 ImportLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004266 break;
4267 }
cristy6c9e1682012-01-07 21:37:44 +00004268 case LongLongPixel:
4269 {
cristycafe0412012-01-10 13:29:58 +00004270 ImportLongLongPixel(image,&roi,map,quantum_map,pixels,exception);
cristy6c9e1682012-01-07 21:37:44 +00004271 break;
4272 }
cristy4c08aed2011-07-01 19:47:50 +00004273 case QuantumPixel:
4274 {
cristycafe0412012-01-10 13:29:58 +00004275 ImportQuantumPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004276 break;
4277 }
4278 case ShortPixel:
4279 {
cristycafe0412012-01-10 13:29:58 +00004280 ImportShortPixel(image,&roi,map,quantum_map,pixels,exception);
cristy4c08aed2011-07-01 19:47:50 +00004281 break;
4282 }
4283 default:
4284 {
4285 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
cristyc82a27b2011-10-21 01:07:16 +00004286 (void) ThrowMagickException(exception,GetMagickModule(),OptionError,
dirk94db6c12013-08-18 21:00:02 +00004287 "UnrecognizedStorageType","`%d'",type);
cristy4c08aed2011-07-01 19:47:50 +00004288 break;
4289 }
4290 }
4291 quantum_map=(QuantumType *) RelinquishMagickMemory(quantum_map);
4292 return(MagickTrue);
4293}
4294
4295/*
4296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4297% %
4298% %
4299% %
cristybd5a96c2011-08-21 00:04:26 +00004300+ 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*/
cristye2a912b2011-12-05 20:02:07 +00004317MagickExport void InitializePixelChannelMap(Image *image)
cristy77c30f52011-10-24 18:56:57 +00004318{
cristye2a912b2011-12-05 20:02:07 +00004319 PixelTrait
4320 trait;
4321
cristy77c30f52011-10-24 18:56:57 +00004322 register ssize_t
4323 i;
4324
cristyd26338f2011-12-14 02:39:30 +00004325 ssize_t
cristy77c30f52011-10-24 18:56:57 +00004326 n;
4327
4328 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004329 assert(image->signature == MagickCoreSignature);
cristye2a912b2011-12-05 20:02:07 +00004330 (void) ResetMagickMemory(image->channel_map,0,MaxPixelChannels*
4331 sizeof(*image->channel_map));
4332 trait=UpdatePixelTrait;
cristy17f11b02014-12-20 19:37:04 +00004333 if (image->alpha_trait != UndefinedPixelTrait)
cristy61f18ad2011-12-08 21:12:37 +00004334 trait=(PixelTrait) (trait | BlendPixelTrait);
Cristy29f8d572017-02-03 08:33:50 -05004335 n=0;
Cristy31c17a72017-02-02 20:33:08 -05004336 if (image->colorspace == GRAYColorspace)
cristy77c30f52011-10-24 18:56:57 +00004337 {
cristycf1296e2012-08-26 23:40:49 +00004338 SetPixelChannelAttributes(image,BluePixelChannel,trait,n);
4339 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n);
4340 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
cristy3c316282011-12-15 15:43:24 +00004341 }
4342 else
4343 {
cristycf1296e2012-08-26 23:40:49 +00004344 SetPixelChannelAttributes(image,RedPixelChannel,trait,n++);
4345 SetPixelChannelAttributes(image,GreenPixelChannel,trait,n++);
4346 SetPixelChannelAttributes(image,BluePixelChannel,trait,n++);
cristy77c30f52011-10-24 18:56:57 +00004347 }
4348 if (image->colorspace == CMYKColorspace)
cristycf1296e2012-08-26 23:40:49 +00004349 SetPixelChannelAttributes(image,BlackPixelChannel,trait,n++);
Cristy86519842017-02-04 18:14:51 -05004350 for (i=0; i < (ssize_t) image->number_meta_channels; i++)
4351 {
4352 SetPixelChannelAttributes(image,(PixelChannel) n,UpdatePixelTrait,n);
4353 n++;
4354 }
cristy17f11b02014-12-20 19:37:04 +00004355 if (image->alpha_trait != UndefinedPixelTrait)
cristycf1296e2012-08-26 23:40:49 +00004356 SetPixelChannelAttributes(image,AlphaPixelChannel,CopyPixelTrait,n++);
cristye2a912b2011-12-05 20:02:07 +00004357 if (image->storage_class == PseudoClass)
cristycf1296e2012-08-26 23:40:49 +00004358 SetPixelChannelAttributes(image,IndexPixelChannel,CopyPixelTrait,n++);
cristy883fde12013-04-08 00:50:13 +00004359 if (image->read_mask != MagickFalse)
4360 SetPixelChannelAttributes(image,ReadMaskPixelChannel,CopyPixelTrait,n++);
4361 if (image->write_mask != MagickFalse)
4362 SetPixelChannelAttributes(image,WriteMaskPixelChannel,CopyPixelTrait,n++);
Cristy29f8d572017-02-03 08:33:50 -05004363 image->number_channels=(size_t) n;
Cristy402bc9f2017-02-11 20:38:11 -05004364 (void) SetPixelChannelMask(image,image->channel_mask);
cristy77c30f52011-10-24 18:56:57 +00004365}
cristybd5a96c2011-08-21 00:04:26 +00004366
4367/*
4368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4369% %
4370% %
4371% %
cristya085a432011-07-30 01:39:32 +00004372% 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%
cristy884f6002011-07-31 00:51:45 +00004378% 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.
cristya085a432011-07-30 01:39:32 +00004381%
anthonycf4e33d2012-06-08 07:33:23 +00004382% Interpolation is restricted to just the specified channel.
4383%
cristya085a432011-07-30 01:39:32 +00004384% The format of the InterpolatePixelChannel method is:
4385%
4386% MagickBooleanType InterpolatePixelChannel(const Image *image,
cristy444eda62011-08-10 02:07:46 +00004387% const CacheView *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004388% const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004389% 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*/
cristy94ea1632011-07-30 20:40:25 +00004408
cristyb0a657e2012-08-29 00:45:37 +00004409static inline void CatromWeights(const double x,double (*weights)[4])
cristy884f6002011-07-31 00:51:45 +00004410{
cristya19f1d72012-08-07 18:24:38 +00004411 double
cristy884f6002011-07-31 00:51:45 +00004412 alpha,
nicolasd32d5e52012-06-12 15:34:10 +00004413 beta,
cristy884f6002011-07-31 00:51:45 +00004414 gamma;
4415
cristy5a5e4d92012-08-29 00:06:25 +00004416 /*
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 */
cristya19f1d72012-08-07 18:24:38 +00004423 alpha=(double) 1.0-x;
4424 beta=(double) (-0.5)*x*alpha;
nicolasd32d5e52012-06-12 15:34:10 +00004425 (*weights)[0]=alpha*beta;
4426 (*weights)[3]=x*beta;
4427 /*
cristy5a5e4d92012-08-29 00:06:25 +00004428 The following computation of the inner weights from the outer ones work
4429 for all Keys cubics.
nicolasd32d5e52012-06-12 15:34:10 +00004430 */
4431 gamma=(*weights)[3]-(*weights)[0];
4432 (*weights)[1]=alpha-(*weights)[0]+gamma;
4433 (*weights)[2]=x-(*weights)[3]-gamma;
4434}
4435
cristyb0a657e2012-08-29 00:45:37 +00004436static inline void SplineWeights(const double x,double (*weights)[4])
nicolasd32d5e52012-06-12 15:34:10 +00004437{
cristy5a5e4d92012-08-29 00:06:25 +00004438 double
4439 alpha,
4440 beta;
4441
nicolasd32d5e52012-06-12 15:34:10 +00004442 /*
cristy58ee5012013-05-26 23:58:44 +00004443 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.
nicolasd32d5e52012-06-12 15:34:10 +00004447 */
cristya19f1d72012-08-07 18:24:38 +00004448 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;
nicolasd32d5e52012-06-12 15:34:10 +00004451 beta=(*weights)[3]-(*weights)[0];
4452 (*weights)[1]=alpha-(*weights)[0]+beta;
4453 (*weights)[2]=x-(*weights)[3]-beta;
cristy884f6002011-07-31 00:51:45 +00004454}
4455
cristy94ea1632011-07-30 20:40:25 +00004456static 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
anthonycf4e33d2012-06-08 07:33:23 +00004462/*
cristya19f1d72012-08-07 18:24:38 +00004463static inline ssize_t NearestNeighbor(const double x)
cristy884f6002011-07-31 00:51:45 +00004464{
4465 if (x >= 0.0)
4466 return((ssize_t) (x+0.5));
4467 return((ssize_t) (x-0.5));
4468}
anthonycf4e33d2012-06-08 07:33:23 +00004469*/
cristy884f6002011-07-31 00:51:45 +00004470
cristya085a432011-07-30 01:39:32 +00004471MagickExport MagickBooleanType InterpolatePixelChannel(const Image *image,
dirk39fee9a2016-01-09 12:09:47 +01004472 const CacheView_ *image_view,const PixelChannel channel,
cristy5c4e2582011-09-11 19:21:03 +00004473 const PixelInterpolateMethod method,const double x,const double y,
cristya085a432011-07-30 01:39:32 +00004474 double *pixel,ExceptionInfo *exception)
4475{
cristya19f1d72012-08-07 18:24:38 +00004476 double
cristy94ea1632011-07-30 20:40:25 +00004477 alpha[16],
cristy884f6002011-07-31 00:51:45 +00004478 gamma,
4479 pixels[16];
cristy94ea1632011-07-30 20:40:25 +00004480
cristy58ee5012013-05-26 23:58:44 +00004481 MagickBooleanType
4482 status;
4483
4484 PixelInterpolateMethod
4485 interpolate;
4486
cristy94ea1632011-07-30 20:40:25 +00004487 PixelTrait
4488 traits;
4489
cristy94ea1632011-07-30 20:40:25 +00004490 register const Quantum
4491 *p;
4492
cristy50e64b82012-06-22 17:46:19 +00004493 register ssize_t
cristy94ea1632011-07-30 20:40:25 +00004494 i;
4495
cristya085a432011-07-30 01:39:32 +00004496 ssize_t
4497 x_offset,
4498 y_offset;
4499
4500 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004501 assert(image->signature == MagickCoreSignature);
cristya085a432011-07-30 01:39:32 +00004502 assert(image_view != (CacheView *) NULL);
4503 status=MagickTrue;
cristy884f6002011-07-31 00:51:45 +00004504 *pixel=0.0;
cristycf1296e2012-08-26 23:40:49 +00004505 traits=GetPixelChannelTraits(image,channel);
cristya085a432011-07-30 01:39:32 +00004506 x_offset=(ssize_t) floor(x);
4507 y_offset=(ssize_t) floor(y);
cristycfc71b12014-11-30 15:23:52 +00004508 interpolate=method;
4509 if (interpolate == UndefinedInterpolatePixel)
4510 interpolate=image->interpolate;
anthonycf4e33d2012-06-08 07:33:23 +00004511 switch (interpolate)
cristya085a432011-07-30 01:39:32 +00004512 {
cristy58ee5012013-05-26 23:58:44 +00004513 case AverageInterpolatePixel: /* nearest 4 neighbours */
4514 case Average9InterpolatePixel: /* nearest 9 neighbours */
4515 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy884f6002011-07-31 00:51:45 +00004516 {
cristyfb122372012-10-17 23:31:21 +00004517 ssize_t
4518 count;
anthonycf4e33d2012-06-08 07:33:23 +00004519
cristyfb122372012-10-17 23:31:21 +00004520 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004521 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 }
cristyfb122372012-10-17 23:31:21 +00004527 else
4528 if (interpolate == Average16InterpolatePixel)
4529 {
4530 count=4;
4531 x_offset--;
4532 y_offset--;
4533 }
cristy021216a2013-05-20 16:25:51 +00004534 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
4535 (size_t) count,exception);
cristy884f6002011-07-31 00:51:45 +00004536 if (p == (const Quantum *) NULL)
4537 {
4538 status=MagickFalse;
4539 break;
4540 }
cristy58ee5012013-05-26 23:58:44 +00004541 count*=count; /* Number of pixels to average */
cristy222b19c2011-08-04 01:35:11 +00004542 if ((traits & BlendPixelTrait) == 0)
cristy50e64b82012-06-22 17:46:19 +00004543 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004544 {
4545 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004546 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004547 }
4548 else
cristy50e64b82012-06-22 17:46:19 +00004549 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004550 {
4551 alpha[i]=QuantumScale*GetPixelAlpha(image,p+i*
4552 GetPixelChannels(image));
4553 pixels[i]=alpha[i]*p[i*GetPixelChannels(image)+channel];
4554 }
cristy50e64b82012-06-22 17:46:19 +00004555 for (i=0; i < (ssize_t) count; i++)
cristy884f6002011-07-31 00:51:45 +00004556 {
cristy3e3ec3a2012-11-03 23:11:06 +00004557 gamma=PerceptibleReciprocal(alpha[i])/count;
anthonycf4e33d2012-06-08 07:33:23 +00004558 *pixel+=gamma*pixels[i];
cristy884f6002011-07-31 00:51:45 +00004559 }
4560 break;
4561 }
anthonycf4e33d2012-06-08 07:33:23 +00004562 case BilinearInterpolatePixel:
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;
cristya19f1d72012-08-07 18:24:38 +00004579 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
anthonycf4e33d2012-06-08 07:33:23 +00004580 }
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])));
cristy3e3ec3a2012-11-03 23:11:06 +00004594 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00004595 *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 }
anthony5f78bca2012-10-05 06:51:00 +00004599 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 }
cristy58ee5012013-05-26 23:58:44 +00004620 gamma=1.0; /* number of pixels blended together (its variable) */
anthony5f78bca2012-10-05 06:51:00 +00004621 for (i=0; i <= 1L; i++) {
cristyfb122372012-10-17 23:31:21 +00004622 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];
anthony5f78bca2012-10-05 06:51:00 +00004639 }
cristyfb122372012-10-17 23:31:21 +00004640 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 }
anthony5f78bca2012-10-05 06:51:00 +00004647 if (channel != AlphaPixelChannel)
cristy58ee5012013-05-26 23:58:44 +00004648 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00004649 else
cristy58ee5012013-05-26 23:58:44 +00004650 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00004651 *pixel=gamma*pixels[0];
4652 break;
4653 }
anthonycf4e33d2012-06-08 07:33:23 +00004654 case CatromInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004655 {
cristya19f1d72012-08-07 18:24:38 +00004656 double
cristy380a11c2012-06-02 15:15:22 +00004657 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004658 cy[4];
cristy884f6002011-07-31 00:51:45 +00004659
cristy884f6002011-07-31 00:51:45 +00004660 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 }
cristy222b19c2011-08-04 01:35:11 +00004667 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004668 for (i=0; i < 16; i++)
4669 {
4670 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004671 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004672 }
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 }
cristya19f1d72012-08-07 18:24:38 +00004680 CatromWeights((double) (x-x_offset),&cx);
4681 CatromWeights((double) (y-y_offset),&cy);
4682 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004683 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004684 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])));
cristy380a11c2012-06-02 15:15:22 +00004688 *pixel=gamma*(cy[0]*(cx[0]*pixels[0]+cx[1]*pixels[1]+cx[2]*pixels[2]+
nicolasd32d5e52012-06-12 15:34:10 +00004689 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]));
cristy884f6002011-07-31 00:51:45 +00004693 break;
4694 }
cristy884f6002011-07-31 00:51:45 +00004695 case IntegerInterpolatePixel:
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 }
cristy0beccfa2011-09-25 20:47:53 +00004703 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004704 break;
4705 }
anthonycf4e33d2012-06-08 07:33:23 +00004706 case NearestInterpolatePixel:
cristy884f6002011-07-31 00:51:45 +00004707 {
anthonycf4e33d2012-06-08 07:33:23 +00004708 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);
cristy884f6002011-07-31 00:51:45 +00004711 if (p == (const Quantum *) NULL)
4712 {
4713 status=MagickFalse;
4714 break;
4715 }
cristy0beccfa2011-09-25 20:47:53 +00004716 *pixel=(double) GetPixelChannel(image,channel,p);
cristy884f6002011-07-31 00:51:45 +00004717 break;
4718 }
4719 case MeshInterpolatePixel:
4720 {
4721 PointInfo
4722 delta,
cristy94ea1632011-07-30 20:40:25 +00004723 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 }
cristy222b19c2011-08-04 01:35:11 +00004731 if ((traits & BlendPixelTrait) == 0)
cristy94ea1632011-07-30 20:40:25 +00004732 for (i=0; i < 4; i++)
4733 {
4734 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004735 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy94ea1632011-07-30 20:40:25 +00004736 }
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 }
cristy884f6002011-07-31 00:51:45 +00004744 delta.x=x-x_offset;
4745 delta.y=y-y_offset;
cristyebfaacf2013-06-24 16:22:40 +00004746 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));
cristy94ea1632011-07-30 20:40:25 +00004750 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]);
cristy3e3ec3a2012-11-03 23:11:06 +00004762 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004763 *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]);
cristy3e3ec3a2012-11-03 23:11:06 +00004773 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004774 *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]);
cristy3e3ec3a2012-11-03 23:11:06 +00004789 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004790 *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]);
cristy3e3ec3a2012-11-03 23:11:06 +00004801 gamma=PerceptibleReciprocal(gamma);
cristy94ea1632011-07-30 20:40:25 +00004802 *pixel=gamma*MeshInterpolate(&delta,pixels[3],pixels[2],
4803 pixels[1]);
4804 }
4805 }
cristya085a432011-07-30 01:39:32 +00004806 break;
4807 }
cristy884f6002011-07-31 00:51:45 +00004808 case SplineInterpolatePixel:
4809 {
cristya19f1d72012-08-07 18:24:38 +00004810 double
nicolasd32d5e52012-06-12 15:34:10 +00004811 cx[4],
nicolas6676f5a2012-06-12 16:01:15 +00004812 cy[4];
cristy884f6002011-07-31 00:51:45 +00004813
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 }
cristy222b19c2011-08-04 01:35:11 +00004821 if ((traits & BlendPixelTrait) == 0)
cristy884f6002011-07-31 00:51:45 +00004822 for (i=0; i < 16; i++)
4823 {
4824 alpha[i]=1.0;
cristya19f1d72012-08-07 18:24:38 +00004825 pixels[i]=(double) p[i*GetPixelChannels(image)+channel];
cristy884f6002011-07-31 00:51:45 +00004826 }
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 }
cristya19f1d72012-08-07 18:24:38 +00004834 SplineWeights((double) (x-x_offset),&cx);
4835 SplineWeights((double) (y-y_offset),&cy);
4836 gamma=(channel == AlphaPixelChannel ? (double) 1.0 :
cristy3e3ec3a2012-11-03 23:11:06 +00004837 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00004838 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]));
cristy884f6002011-07-31 00:51:45 +00004847 break;
4848 }
cristya085a432011-07-30 01:39:32 +00004849 }
4850 return(status);
4851}
4852
4853/*
4854%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4855% %
4856% %
4857% %
cristy5c4e2582011-09-11 19:21:03 +00004858% 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%
anthonycf4e33d2012-06-08 07:33:23 +00004868% Interpolation is restricted to just the current channel setting of the
4869% destination image into which the color is to be stored
4870%
cristy5c4e2582011-09-11 19:21:03 +00004871% 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%
anthonycf4e33d2012-06-08 07:33:23 +00004884% o destination: the destination image, for the interpolated color
cristy5c4e2582011-09-11 19:21:03 +00004885%
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*/
4895MagickExport MagickBooleanType InterpolatePixelChannels(const Image *source,
dirk39fee9a2016-01-09 12:09:47 +01004896 const CacheView_ *source_view,const Image *destination,
cristy5c4e2582011-09-11 19:21:03 +00004897 const PixelInterpolateMethod method,const double x,const double y,
4898 Quantum *pixel,ExceptionInfo *exception)
4899{
4900 MagickBooleanType
4901 status;
4902
cristya19f1d72012-08-07 18:24:38 +00004903 double
cristy5c4e2582011-09-11 19:21:03 +00004904 alpha[16],
4905 gamma,
4906 pixels[16];
4907
cristy5c4e2582011-09-11 19:21:03 +00004908 register const Quantum
4909 *p;
4910
cristy50e64b82012-06-22 17:46:19 +00004911 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004912 i;
4913
4914 ssize_t
4915 x_offset,
4916 y_offset;
4917
anthonycf4e33d2012-06-08 07:33:23 +00004918 PixelInterpolateMethod
4919 interpolate;
4920
cristy5c4e2582011-09-11 19:21:03 +00004921 assert(source != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00004922 assert(source->signature == MagickCoreSignature);
cristy5c4e2582011-09-11 19:21:03 +00004923 assert(source_view != (CacheView *) NULL);
4924 status=MagickTrue;
4925 x_offset=(ssize_t) floor(x);
4926 y_offset=(ssize_t) floor(y);
cristycfc71b12014-11-30 15:23:52 +00004927 interpolate=method;
4928 if (interpolate == UndefinedInterpolatePixel)
4929 interpolate=source->interpolate;
anthonycf4e33d2012-06-08 07:33:23 +00004930 switch (interpolate)
cristy5c4e2582011-09-11 19:21:03 +00004931 {
cristy58ee5012013-05-26 23:58:44 +00004932 case AverageInterpolatePixel: /* nearest 4 neighbours */
4933 case Average9InterpolatePixel: /* nearest 9 neighbours */
4934 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy5c4e2582011-09-11 19:21:03 +00004935 {
cristyfb122372012-10-17 23:31:21 +00004936 ssize_t
4937 count;
anthonycf4e33d2012-06-08 07:33:23 +00004938
cristyfb122372012-10-17 23:31:21 +00004939 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00004940 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 }
cristyfb122372012-10-17 23:31:21 +00004946 else
4947 if (interpolate == Average16InterpolatePixel)
4948 {
4949 count=4;
4950 x_offset--;
4951 y_offset--;
4952 }
cristy1b72b812013-04-19 00:57:44 +00004953 p=GetCacheViewVirtualPixels(source_view,x_offset,y_offset,(size_t) count,
4954 (size_t) count,exception);
cristy5c4e2582011-09-11 19:21:03 +00004955 if (p == (const Quantum *) NULL)
4956 {
4957 status=MagickFalse;
4958 break;
4959 }
cristy58ee5012013-05-26 23:58:44 +00004960 count*=count; /* Number of pixels to average */
cristy50e64b82012-06-22 17:46:19 +00004961 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00004962 {
4963 double
4964 sum;
4965
cristy50e64b82012-06-22 17:46:19 +00004966 register ssize_t
cristy5c4e2582011-09-11 19:21:03 +00004967 j;
4968
cristy5a23c552013-02-13 14:34:28 +00004969 PixelChannel channel=GetPixelChannelChannel(source,i);
4970 PixelTrait traits=GetPixelChannelTraits(source,channel);
4971 PixelTrait destination_traits=GetPixelChannelTraits(destination,
4972 channel);
cristy5c4e2582011-09-11 19:21:03 +00004973 if ((traits == UndefinedPixelTrait) ||
4974 (destination_traits == UndefinedPixelTrait))
4975 continue;
cristy50e64b82012-06-22 17:46:19 +00004976 for (j=0; j < (ssize_t) count; j++)
cristya19f1d72012-08-07 18:24:38 +00004977 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy4a7ae692011-12-14 12:24:11 +00004978 sum=0.0;
cristy5c4e2582011-09-11 19:21:03 +00004979 if ((traits & BlendPixelTrait) == 0)
4980 {
cristy50e64b82012-06-22 17:46:19 +00004981 for (j=0; j < (ssize_t) count; j++)
anthonycf4e33d2012-06-08 07:33:23 +00004982 sum+=pixels[j];
4983 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004984 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004985 continue;
4986 }
cristy50e64b82012-06-22 17:46:19 +00004987 for (j=0; j < (ssize_t) count; j++)
cristy5c4e2582011-09-11 19:21:03 +00004988 {
4989 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
4990 GetPixelChannels(source));
4991 pixels[j]*=alpha[j];
cristy3e3ec3a2012-11-03 23:11:06 +00004992 gamma=PerceptibleReciprocal(alpha[j]);
anthonycf4e33d2012-06-08 07:33:23 +00004993 sum+=gamma*pixels[j];
cristy5c4e2582011-09-11 19:21:03 +00004994 }
anthonycf4e33d2012-06-08 07:33:23 +00004995 sum/=count;
cristy4a7ae692011-12-14 12:24:11 +00004996 SetPixelChannel(destination,channel,ClampToQuantum(sum),pixel);
cristy5c4e2582011-09-11 19:21:03 +00004997 }
4998 break;
4999 }
anthonycf4e33d2012-06-08 07:33:23 +00005000 case BilinearInterpolatePixel:
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 }
cristy50e64b82012-06-22 17:46:19 +00005009 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
anthonycf4e33d2012-06-08 07:33:23 +00005010 {
5011 PointInfo
5012 delta,
5013 epsilon;
5014
cristy5a23c552013-02-13 14:34:28 +00005015 PixelChannel channel=GetPixelChannelChannel(source,i);
5016 PixelTrait traits=GetPixelChannelTraits(source,channel);
5017 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5018 channel);
anthonycf4e33d2012-06-08 07:33:23 +00005019 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;
cristya19f1d72012-08-07 18:24:38 +00005026 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];
anthonycf4e33d2012-06-08 07:33:23 +00005030 if ((traits & BlendPixelTrait) == 0)
5031 {
5032 gamma=((epsilon.y*(epsilon.x+delta.x)+delta.y*(epsilon.x+delta.x)));
cristy3e3ec3a2012-11-03 23:11:06 +00005033 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005034 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])));
cristy3e3ec3a2012-11-03 23:11:06 +00005051 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005052 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 }
anthony5f78bca2012-10-05 06:51:00 +00005058 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
cristy5a23c552013-02-13 14:34:28 +00005071 PixelChannel channel=GetPixelChannelChannel(source,i);
5072 PixelTrait traits=GetPixelChannelTraits(source,channel);
5073 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5074 channel);
anthony5f78bca2012-10-05 06:51:00 +00005075 if ((traits == UndefinedPixelTrait) ||
5076 (destination_traits == UndefinedPixelTrait))
5077 continue;
dirk7750eff2016-07-02 20:59:05 +02005078 if (source->alpha_trait != BlendPixelTrait)
anthony5f78bca2012-10-05 06:51:00 +00005079 for (j=0; j < 4; j++)
5080 {
5081 alpha[j]=1.0;
dirk7750eff2016-07-02 20:59:05 +02005082 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
anthony5f78bca2012-10-05 06:51:00 +00005083 }
5084 else
5085 for (j=0; j < 4; j++)
5086 {
5087 alpha[j]=QuantumScale*GetPixelAlpha(source,p+j*
5088 GetPixelChannels(source));
dirk7750eff2016-07-02 20:59:05 +02005089 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
5090 if (channel != AlphaPixelChannel)
5091 pixels[j]*=alpha[j];
anthony5f78bca2012-10-05 06:51:00 +00005092 }
cristyfb122372012-10-17 23:31:21 +00005093 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 {
cristy58ee5012013-05-26 23:58:44 +00005104 gamma=2.0; /* blend both pixels in row */
cristyfb122372012-10-17 23:31:21 +00005105 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];
anthony5f78bca2012-10-05 06:51:00 +00005113 }
cristyfb122372012-10-17 23:31:21 +00005114 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 }
dirk7750eff2016-07-02 20:59:05 +02005121 if (channel != AlphaPixelChannel)
cristy58ee5012013-05-26 23:58:44 +00005122 gamma=PerceptibleReciprocal(alpha[0]); /* (color) 1/alpha_weights */
anthony5f78bca2012-10-05 06:51:00 +00005123 else
cristy58ee5012013-05-26 23:58:44 +00005124 gamma=PerceptibleReciprocal(gamma); /* (alpha) 1/number_of_pixels */
anthony5f78bca2012-10-05 06:51:00 +00005125 SetPixelChannel(destination,channel,ClampToQuantum(gamma*pixels[0]),
cristyfb122372012-10-17 23:31:21 +00005126 pixel);
anthony5f78bca2012-10-05 06:51:00 +00005127 }
5128 break;
5129 }
anthonycf4e33d2012-06-08 07:33:23 +00005130 case CatromInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00005131 {
cristya19f1d72012-08-07 18:24:38 +00005132 double
cristy380a11c2012-06-02 15:15:22 +00005133 cx[4],
5134 cy[4];
cristy5c4e2582011-09-11 19:21:03 +00005135
cristy5c4e2582011-09-11 19:21:03 +00005136 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 }
cristy50e64b82012-06-22 17:46:19 +00005143 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005144 {
5145 register ssize_t
5146 j;
5147
cristy5a23c552013-02-13 14:34:28 +00005148 PixelChannel channel=GetPixelChannelChannel(source,i);
5149 PixelTrait traits=GetPixelChannelTraits(source,channel);
5150 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5151 channel);
cristy5c4e2582011-09-11 19:21:03 +00005152 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;
cristya19f1d72012-08-07 18:24:38 +00005159 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00005160 }
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 }
cristya19f1d72012-08-07 18:24:38 +00005168 CatromWeights((double) (x-x_offset),&cx);
5169 CatromWeights((double) (y-y_offset),&cy);
5170 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00005171 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00005172 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])));
cristy380a11c2012-06-02 15:15:22 +00005176 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]*
nicolasd32d5e52012-06-12 15:34:10 +00005180 pixels[11])+cy[3]*(cx[0]*pixels[12]+cx[1]*pixels[13]+cx[2]*
5181 pixels[14]+cx[3]*pixels[15]))),pixel);
cristy5c4e2582011-09-11 19:21:03 +00005182 }
5183 break;
5184 }
cristy5c4e2582011-09-11 19:21:03 +00005185 case IntegerInterpolatePixel:
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 }
cristy50e64b82012-06-22 17:46:19 +00005193 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005194 {
cristy5a23c552013-02-13 14:34:28 +00005195 PixelChannel channel=GetPixelChannelChannel(source,i);
5196 PixelTrait traits=GetPixelChannelTraits(source,channel);
5197 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5198 channel);
cristy5c4e2582011-09-11 19:21:03 +00005199 if ((traits == UndefinedPixelTrait) ||
5200 (destination_traits == UndefinedPixelTrait))
5201 continue;
cristy4a7ae692011-12-14 12:24:11 +00005202 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00005203 }
5204 break;
5205 }
anthonycf4e33d2012-06-08 07:33:23 +00005206 case NearestInterpolatePixel:
cristy5c4e2582011-09-11 19:21:03 +00005207 {
anthonycf4e33d2012-06-08 07:33:23 +00005208 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);
cristy5c4e2582011-09-11 19:21:03 +00005211 if (p == (const Quantum *) NULL)
5212 {
5213 status=MagickFalse;
5214 break;
5215 }
cristy50e64b82012-06-22 17:46:19 +00005216 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005217 {
cristy5a23c552013-02-13 14:34:28 +00005218 PixelChannel channel=GetPixelChannelChannel(source,i);
5219 PixelTrait traits=GetPixelChannelTraits(source,channel);
5220 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5221 channel);
cristy5c4e2582011-09-11 19:21:03 +00005222 if ((traits == UndefinedPixelTrait) ||
5223 (destination_traits == UndefinedPixelTrait))
5224 continue;
cristy4a7ae692011-12-14 12:24:11 +00005225 SetPixelChannel(destination,channel,p[i],pixel);
cristy5c4e2582011-09-11 19:21:03 +00005226 }
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 }
cristy50e64b82012-06-22 17:46:19 +00005237 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005238 {
5239 PointInfo
5240 delta,
5241 luminance;
5242
cristy5a23c552013-02-13 14:34:28 +00005243 PixelChannel channel=GetPixelChannelChannel(source,i);
5244 PixelTrait traits=GetPixelChannelTraits(source,channel);
5245 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5246 channel);
cristy5c4e2582011-09-11 19:21:03 +00005247 if ((traits == UndefinedPixelTrait) ||
5248 (destination_traits == UndefinedPixelTrait))
5249 continue;
cristya19f1d72012-08-07 18:24:38 +00005250 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];
cristy1861c902011-12-14 02:30:00 +00005254 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;
cristyebfaacf2013-06-24 16:22:40 +00005273 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*
cristyfb122372012-10-17 23:31:21 +00005277 GetPixelChannels(source))));
anthonycf4e33d2012-06-08 07:33:23 +00005278 if (luminance.x < luminance.y)
cristy1861c902011-12-14 02:30:00 +00005279 {
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]);
cristy3e3ec3a2012-11-03 23:11:06 +00005290 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005291 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5292 MeshInterpolate(&delta,pixels[2],pixels[3],pixels[0])),pixel);
cristy1861c902011-12-14 02:30:00 +00005293 }
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]);
cristy3e3ec3a2012-11-03 23:11:06 +00005301 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005302 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5303 MeshInterpolate(&delta,pixels[1],pixels[0],pixels[3])),pixel);
cristy1861c902011-12-14 02:30:00 +00005304 }
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]);
cristy3e3ec3a2012-11-03 23:11:06 +00005317 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005318 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5319 MeshInterpolate(&delta,pixels[0],pixels[1],pixels[2])),pixel);
cristy1861c902011-12-14 02:30:00 +00005320 }
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]);
cristy3e3ec3a2012-11-03 23:11:06 +00005329 gamma=PerceptibleReciprocal(gamma);
cristy4a7ae692011-12-14 12:24:11 +00005330 SetPixelChannel(destination,channel,ClampToQuantum(gamma*
5331 MeshInterpolate(&delta,pixels[3],pixels[2],pixels[1])),pixel);
cristy1861c902011-12-14 02:30:00 +00005332 }
5333 }
cristy5c4e2582011-09-11 19:21:03 +00005334 }
5335 break;
5336 }
5337 case SplineInterpolatePixel:
5338 {
cristya19f1d72012-08-07 18:24:38 +00005339 double
nicolasd32d5e52012-06-12 15:34:10 +00005340 cx[4],
5341 cy[4];
5342
cristy5c4e2582011-09-11 19:21:03 +00005343 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 }
cristy50e64b82012-06-22 17:46:19 +00005350 for (i=0; i < (ssize_t) GetPixelChannels(source); i++)
cristy5c4e2582011-09-11 19:21:03 +00005351 {
cristy5c4e2582011-09-11 19:21:03 +00005352 register ssize_t
5353 j;
5354
cristy5a23c552013-02-13 14:34:28 +00005355 PixelChannel channel=GetPixelChannelChannel(source,i);
5356 PixelTrait traits=GetPixelChannelTraits(source,channel);
5357 PixelTrait destination_traits=GetPixelChannelTraits(destination,
5358 channel);
cristy5c4e2582011-09-11 19:21:03 +00005359 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;
cristya19f1d72012-08-07 18:24:38 +00005366 pixels[j]=(double) p[j*GetPixelChannels(source)+i];
cristy5c4e2582011-09-11 19:21:03 +00005367 }
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 }
cristya19f1d72012-08-07 18:24:38 +00005375 SplineWeights((double) (x-x_offset),&cx);
5376 SplineWeights((double) (y-y_offset),&cy);
5377 gamma=((traits & BlendPixelTrait) ? (double) (1.0) :
cristy3e3ec3a2012-11-03 23:11:06 +00005378 PerceptibleReciprocal(cy[0]*(cx[0]*alpha[0]+cx[1]*alpha[1]+cx[2]*
nicolasd32d5e52012-06-12 15:34:10 +00005379 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);
cristy5c4e2582011-09-11 19:21:03 +00005389 }
5390 break;
5391 }
5392 }
5393 return(status);
5394}
5395
5396/*
5397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5398% %
5399% %
5400% %
cristy9075cdb2011-07-30 01:06:23 +00005401% I n t e r p o l a t e P i x e l I n f o %
cristy4c08aed2011-07-01 19:47:50 +00005402% %
5403% %
5404% %
5405%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5406%
cristy884f6002011-07-31 00:51:45 +00005407% 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.
cristy4c08aed2011-07-01 19:47:50 +00005410%
anthonycf4e33d2012-06-08 07:33:23 +00005411% Interpolation is restricted to just RGBKA channels.
5412%
cristy4c08aed2011-07-01 19:47:50 +00005413% The format of the InterpolatePixelInfo method is:
5414%
5415% MagickBooleanType InterpolatePixelInfo(const Image *image,
cristy5c4e2582011-09-11 19:21:03 +00005416% const CacheView *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005417% 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
5436static inline void AlphaBlendPixelInfo(const Image *image,
cristya19f1d72012-08-07 18:24:38 +00005437 const Quantum *pixel,PixelInfo *pixel_info,double *alpha)
cristy4c08aed2011-07-01 19:47:50 +00005438{
cristy17f11b02014-12-20 19:37:04 +00005439 if (image->alpha_trait == UndefinedPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005440 {
5441 *alpha=1.0;
cristya19f1d72012-08-07 18:24:38 +00005442 pixel_info->red=(double) GetPixelRed(image,pixel);
5443 pixel_info->green=(double) GetPixelGreen(image,pixel);
5444 pixel_info->blue=(double) GetPixelBlue(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005445 pixel_info->black=0.0;
5446 if (image->colorspace == CMYKColorspace)
cristya19f1d72012-08-07 18:24:38 +00005447 pixel_info->black=(double) GetPixelBlack(image,pixel);
5448 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005449 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));
cristya19f1d72012-08-07 18:24:38 +00005458 pixel_info->alpha=(double) GetPixelAlpha(image,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005459}
5460
cristy4c08aed2011-07-01 19:47:50 +00005461MagickExport MagickBooleanType InterpolatePixelInfo(const Image *image,
dirk39fee9a2016-01-09 12:09:47 +01005462 const CacheView_ *image_view,const PixelInterpolateMethod method,
cristy4c08aed2011-07-01 19:47:50 +00005463 const double x,const double y,PixelInfo *pixel,ExceptionInfo *exception)
5464{
5465 MagickBooleanType
5466 status;
5467
cristya19f1d72012-08-07 18:24:38 +00005468 double
cristy4c08aed2011-07-01 19:47:50 +00005469 alpha[16],
5470 gamma;
5471
cristy865d58d2011-07-09 00:44:52 +00005472 PixelInfo
5473 pixels[16];
5474
cristy4c08aed2011-07-01 19:47:50 +00005475 register const Quantum
5476 *p;
5477
cristy50e64b82012-06-22 17:46:19 +00005478 register ssize_t
cristy4c08aed2011-07-01 19:47:50 +00005479 i;
5480
5481 ssize_t
5482 x_offset,
5483 y_offset;
5484
anthonycf4e33d2012-06-08 07:33:23 +00005485 PixelInterpolateMethod
5486 interpolate;
5487
cristy4c08aed2011-07-01 19:47:50 +00005488 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00005489 assert(image->signature == MagickCoreSignature);
cristy4c08aed2011-07-01 19:47:50 +00005490 assert(image_view != (CacheView *) NULL);
5491 status=MagickTrue;
5492 x_offset=(ssize_t) floor(x);
5493 y_offset=(ssize_t) floor(y);
cristycfc71b12014-11-30 15:23:52 +00005494 interpolate=method;
5495 if (interpolate == UndefinedInterpolatePixel)
5496 interpolate=image->interpolate;
dirkccad00b2015-06-21 16:58:22 +00005497 (void) ResetMagickMemory(&pixels,0,sizeof(pixels));
anthonycf4e33d2012-06-08 07:33:23 +00005498 switch (interpolate)
cristy4c08aed2011-07-01 19:47:50 +00005499 {
cristy58ee5012013-05-26 23:58:44 +00005500 case AverageInterpolatePixel: /* nearest 4 neighbours */
5501 case Average9InterpolatePixel: /* nearest 9 neighbours */
5502 case Average16InterpolatePixel: /* nearest 16 neighbours */
cristy4c08aed2011-07-01 19:47:50 +00005503 {
cristyfb122372012-10-17 23:31:21 +00005504 ssize_t
5505 count;
anthonycf4e33d2012-06-08 07:33:23 +00005506
cristyfb122372012-10-17 23:31:21 +00005507 count=2; /* size of the area to average - default nearest 4 */
anthonycf4e33d2012-06-08 07:33:23 +00005508 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 }
cristy021216a2013-05-20 16:25:51 +00005520 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,(size_t) count,
5521 (size_t) count,exception);
cristy4c08aed2011-07-01 19:47:50 +00005522 if (p == (const Quantum *) NULL)
5523 {
5524 status=MagickFalse;
5525 break;
5526 }
cristy4c08aed2011-07-01 19:47:50 +00005527 pixel->red=0.0;
5528 pixel->green=0.0;
5529 pixel->blue=0.0;
cristy4c08aed2011-07-01 19:47:50 +00005530 pixel->black=0.0;
cristy865d58d2011-07-09 00:44:52 +00005531 pixel->alpha=0.0;
cristy58ee5012013-05-26 23:58:44 +00005532 count*=count; /* number of pixels - square of size */
cristy50e64b82012-06-22 17:46:19 +00005533 for (i=0; i < (ssize_t) count; i++)
cristy4c08aed2011-07-01 19:47:50 +00005534 {
anthonycf4e33d2012-06-08 07:33:23 +00005535 AlphaBlendPixelInfo(image,p,pixels,alpha);
cristy3e3ec3a2012-11-03 23:11:06 +00005536 gamma=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005537 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;
anthonycf4e33d2012-06-08 07:33:23 +00005542 p += GetPixelChannels(image);
cristy4c08aed2011-07-01 19:47:50 +00005543 }
anthonycf4e33d2012-06-08 07:33:23 +00005544 gamma=1.0/count; /* average weighting of each pixel in area */
cristyfb122372012-10-17 23:31:21 +00005545 pixel->red*=gamma;
5546 pixel->green*=gamma;
5547 pixel->blue*=gamma;
5548 pixel->black*=gamma;
5549 pixel->alpha*=gamma;
cristy4c08aed2011-07-01 19:47:50 +00005550 break;
5551 }
anthonycf4e33d2012-06-08 07:33:23 +00005552 case BackgroundInterpolatePixel:
5553 {
cristyfb122372012-10-17 23:31:21 +00005554 *pixel=image->background_color; /* Copy PixelInfo Structure */
anthonycf4e33d2012-06-08 07:33:23 +00005555 break;
5556 }
5557 case BilinearInterpolatePixel:
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])));
cristy3e3ec3a2012-11-03 23:11:06 +00005578 gamma=PerceptibleReciprocal(gamma);
anthonycf4e33d2012-06-08 07:33:23 +00005579 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)));
cristy3e3ec3a2012-11-03 23:11:06 +00005592 gamma=PerceptibleReciprocal(gamma);
cristy554f4e52015-01-12 01:29:13 +00005593 pixel->alpha=gamma*(epsilon.y*(epsilon.x*pixels[0].alpha+delta.x*
anthonycf4e33d2012-06-08 07:33:23 +00005594 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++)
cristye26356f2015-06-20 14:51:25 +00005607 {
5608 GetPixelInfoPixel(image,p+i*GetPixelChannels(image),pixels+i);
anthonycf4e33d2012-06-08 07:33:23 +00005609 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristye26356f2015-06-20 14:51:25 +00005610 }
cristyfb122372012-10-17 23:31:21 +00005611 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];
anthonycf4e33d2012-06-08 07:33:23 +00005635 }
cristyfb122372012-10-17 23:31:21 +00005636 else
5637 if ((x-x_offset) > 0.25)
5638 {
5639 gamma*=2.0; /* blend both rows */
cristy58ee5012013-05-26 23:58:44 +00005640 alpha[0]+= alpha[1]; /* add up alpha weights */
cristyfb122372012-10-17 23:31:21 +00005641 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;
cristy3e3ec3a2012-11-03 23:11:06 +00005648 alpha[0]=PerceptibleReciprocal(alpha[0]);
cristyfb122372012-10-17 23:31:21 +00005649 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 */
anthonycf4e33d2012-06-08 07:33:23 +00005654 break;
5655 }
5656 case CatromInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005657 {
cristya19f1d72012-08-07 18:24:38 +00005658 double
cristy380a11c2012-06-02 15:15:22 +00005659 cx[4],
5660 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005661
cristy4c08aed2011-07-01 19:47:50 +00005662 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 }
anthonycf4e33d2012-06-08 07:33:23 +00005669 for (i=0; i < 16L; i++)
5670 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005671 CatromWeights((double) (x-x_offset),&cx);
5672 CatromWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005673 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));
cristy380a11c2012-06-02 15:15:22 +00005692 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005693 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));
cristy4c08aed2011-07-01 19:47:50 +00005706 break;
5707 }
cristy4c08aed2011-07-01 19:47:50 +00005708 case IntegerInterpolatePixel:
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 }
cristy803640d2011-11-17 02:11:32 +00005716 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005717 break;
5718 }
5719 case MeshInterpolatePixel:
5720 {
5721 PointInfo
5722 delta,
5723 luminance;
5724
cristy94ea1632011-07-30 20:40:25 +00005725 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,2,2,exception);
cristy4c08aed2011-07-01 19:47:50 +00005726 if (p == (const Quantum *) NULL)
5727 {
5728 status=MagickFalse;
5729 break;
5730 }
cristy94ea1632011-07-30 20:40:25 +00005731 delta.x=x-x_offset;
5732 delta.y=y-y_offset;
cristyebfaacf2013-06-24 16:22:40 +00005733 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));
cristy5ce8df82011-07-07 14:52:23 +00005737 AlphaBlendPixelInfo(image,p,pixels+0,alpha+0);
cristy28474bf2011-09-11 23:32:52 +00005738 AlphaBlendPixelInfo(image,p+GetPixelChannels(image),pixels+1,alpha+1);
cristyed231572011-07-14 02:18:59 +00005739 AlphaBlendPixelInfo(image,p+2*GetPixelChannels(image),pixels+2,alpha+2);
5740 AlphaBlendPixelInfo(image,p+3*GetPixelChannels(image),pixels+3,alpha+3);
cristy4c08aed2011-07-01 19:47:50 +00005741 if (fabs(luminance.x) < fabs(luminance.y))
5742 {
5743 /*
5744 Diagonal 0-3 NW-SE.
5745 */
5746 if (delta.x <= delta.y)
5747 {
5748 /*
cristy94ea1632011-07-30 20:40:25 +00005749 Bottom-left triangle (pixel: 2, diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005750 */
5751 delta.y=1.0-delta.y;
5752 gamma=MeshInterpolate(&delta,alpha[2],alpha[3],alpha[0]);
cristy3e3ec3a2012-11-03 23:11:06 +00005753 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005754 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);
cristy4c08aed2011-07-01 19:47:50 +00005760 if (image->colorspace == CMYKColorspace)
5761 pixel->black=gamma*MeshInterpolate(&delta,pixels[2].black,
5762 pixels[3].black,pixels[0].black);
cristy94ea1632011-07-30 20:40:25 +00005763 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005764 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[2].alpha,
5765 pixels[3].alpha,pixels[0].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005766 }
5767 else
5768 {
5769 /*
cristy94ea1632011-07-30 20:40:25 +00005770 Top-right triangle (pixel:1 , diagonal: 0-3).
cristy4c08aed2011-07-01 19:47:50 +00005771 */
5772 delta.x=1.0-delta.x;
5773 gamma=MeshInterpolate(&delta,alpha[1],alpha[0],alpha[3]);
cristy3e3ec3a2012-11-03 23:11:06 +00005774 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005775 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);
cristy4c08aed2011-07-01 19:47:50 +00005781 if (image->colorspace == CMYKColorspace)
5782 pixel->black=gamma*MeshInterpolate(&delta,pixels[1].black,
5783 pixels[0].black,pixels[3].black);
cristy94ea1632011-07-30 20:40:25 +00005784 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005785 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[1].alpha,
5786 pixels[0].alpha,pixels[3].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005787 }
5788 }
5789 else
5790 {
5791 /*
5792 Diagonal 1-2 NE-SW.
5793 */
5794 if (delta.x <= (1.0-delta.y))
5795 {
5796 /*
cristy94ea1632011-07-30 20:40:25 +00005797 Top-left triangle (pixel: 0, diagonal: 1-2).
cristy4c08aed2011-07-01 19:47:50 +00005798 */
5799 gamma=MeshInterpolate(&delta,alpha[0],alpha[1],alpha[2]);
cristy3e3ec3a2012-11-03 23:11:06 +00005800 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005801 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);
cristy4c08aed2011-07-01 19:47:50 +00005807 if (image->colorspace == CMYKColorspace)
5808 pixel->black=gamma*MeshInterpolate(&delta,pixels[0].black,
5809 pixels[1].black,pixels[2].black);
cristy94ea1632011-07-30 20:40:25 +00005810 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005811 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[0].alpha,
5812 pixels[1].alpha,pixels[2].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005813 }
5814 else
5815 {
5816 /*
5817 Bottom-right triangle (pixel: 3, diagonal: 1-2).
5818 */
5819 delta.x=1.0-delta.x;
5820 delta.y=1.0-delta.y;
5821 gamma=MeshInterpolate(&delta,alpha[3],alpha[2],alpha[1]);
cristy3e3ec3a2012-11-03 23:11:06 +00005822 gamma=PerceptibleReciprocal(gamma);
cristy4c08aed2011-07-01 19:47:50 +00005823 pixel->red=gamma*MeshInterpolate(&delta,pixels[3].red,
5824 pixels[2].red,pixels[1].red);
5825 pixel->green=gamma*MeshInterpolate(&delta,pixels[3].green,
5826 pixels[2].green,pixels[1].green);
5827 pixel->blue=gamma*MeshInterpolate(&delta,pixels[3].blue,
5828 pixels[2].blue,pixels[1].blue);
cristy4c08aed2011-07-01 19:47:50 +00005829 if (image->colorspace == CMYKColorspace)
5830 pixel->black=gamma*MeshInterpolate(&delta,pixels[3].black,
5831 pixels[2].black,pixels[1].black);
cristy94ea1632011-07-30 20:40:25 +00005832 gamma=MeshInterpolate(&delta,1.0,1.0,1.0);
cristy865d58d2011-07-09 00:44:52 +00005833 pixel->alpha=gamma*MeshInterpolate(&delta,pixels[3].alpha,
5834 pixels[2].alpha,pixels[1].alpha);
cristy4c08aed2011-07-01 19:47:50 +00005835 }
5836 }
5837 break;
5838 }
anthonycf4e33d2012-06-08 07:33:23 +00005839 case NearestInterpolatePixel:
cristy4c08aed2011-07-01 19:47:50 +00005840 {
anthonycf4e33d2012-06-08 07:33:23 +00005841 x_offset=(ssize_t) floor(x+0.5);
5842 y_offset=(ssize_t) floor(y+0.5);
5843 p=GetCacheViewVirtualPixels(image_view,x_offset,y_offset,1,1,exception);
cristy4c08aed2011-07-01 19:47:50 +00005844 if (p == (const Quantum *) NULL)
5845 {
5846 status=MagickFalse;
5847 break;
5848 }
cristy803640d2011-11-17 02:11:32 +00005849 GetPixelInfoPixel(image,p,pixel);
cristy4c08aed2011-07-01 19:47:50 +00005850 break;
5851 }
5852 case SplineInterpolatePixel:
5853 {
cristya19f1d72012-08-07 18:24:38 +00005854 double
nicolasd32d5e52012-06-12 15:34:10 +00005855 cx[4],
5856 cy[4];
cristy4c08aed2011-07-01 19:47:50 +00005857
5858 p=GetCacheViewVirtualPixels(image_view,x_offset-1,y_offset-1,4,4,
5859 exception);
5860 if (p == (const Quantum *) NULL)
5861 {
5862 status=MagickFalse;
5863 break;
5864 }
anthonycf4e33d2012-06-08 07:33:23 +00005865 for (i=0; i < 16L; i++)
5866 AlphaBlendPixelInfo(image,p+i*GetPixelChannels(image),pixels+i,alpha+i);
cristya19f1d72012-08-07 18:24:38 +00005867 SplineWeights((double) (x-x_offset),&cx);
5868 SplineWeights((double) (y-y_offset),&cy);
cristyfb122372012-10-17 23:31:21 +00005869 pixel->red=(cy[0]*(cx[0]*pixels[0].red+cx[1]*pixels[1].red+cx[2]*
5870 pixels[2].red+cx[3]*pixels[3].red)+cy[1]*(cx[0]*pixels[4].red+cx[1]*
5871 pixels[5].red+cx[2]*pixels[6].red+cx[3]*pixels[7].red)+cy[2]*(cx[0]*
5872 pixels[8].red+cx[1]*pixels[9].red+cx[2]*pixels[10].red+cx[3]*
5873 pixels[11].red)+cy[3]*(cx[0]*pixels[12].red+cx[1]*pixels[13].red+cx[2]*
5874 pixels[14].red+cx[3]*pixels[15].red));
5875 pixel->green=(cy[0]*(cx[0]*pixels[0].green+cx[1]*pixels[1].green+cx[2]*
5876 pixels[2].green+cx[3]*pixels[3].green)+cy[1]*(cx[0]*pixels[4].green+
5877 cx[1]*pixels[5].green+cx[2]*pixels[6].green+cx[3]*pixels[7].green)+
5878 cy[2]*(cx[0]*pixels[8].green+cx[1]*pixels[9].green+cx[2]*
5879 pixels[10].green+cx[3]*pixels[11].green)+cy[3]*(cx[0]*pixels[12].green+
5880 cx[1]*pixels[13].green+cx[2]*pixels[14].green+cx[3]*pixels[15].green));
5881 pixel->blue=(cy[0]*(cx[0]*pixels[0].blue+cx[1]*pixels[1].blue+cx[2]*
5882 pixels[2].blue+cx[3]*pixels[3].blue)+cy[1]*(cx[0]*pixels[4].blue+cx[1]*
5883 pixels[5].blue+cx[2]*pixels[6].blue+cx[3]*pixels[7].blue)+cy[2]*(cx[0]*
5884 pixels[8].blue+cx[1]*pixels[9].blue+cx[2]*pixels[10].blue+cx[3]*
5885 pixels[11].blue)+cy[3]*(cx[0]*pixels[12].blue+cx[1]*pixels[13].blue+
5886 cx[2]*pixels[14].blue+cx[3]*pixels[15].blue));
nicolasd32d5e52012-06-12 15:34:10 +00005887 if (image->colorspace == CMYKColorspace)
cristyfb122372012-10-17 23:31:21 +00005888 pixel->black=(cy[0]*(cx[0]*pixels[0].black+cx[1]*pixels[1].black+cx[2]*
5889 pixels[2].black+cx[3]*pixels[3].black)+cy[1]*(cx[0]*pixels[4].black+
5890 cx[1]*pixels[5].black+cx[2]*pixels[6].black+cx[3]*pixels[7].black)+
5891 cy[2]*(cx[0]*pixels[8].black+cx[1]*pixels[9].black+cx[2]*
5892 pixels[10].black+cx[3]*pixels[11].black)+cy[3]*(cx[0]*
5893 pixels[12].black+cx[1]*pixels[13].black+cx[2]*pixels[14].black+cx[3]*
5894 pixels[15].black));
5895 pixel->alpha=(cy[0]*(cx[0]*pixels[0].alpha+cx[1]*pixels[1].alpha+cx[2]*
5896 pixels[2].alpha+cx[3]*pixels[3].alpha)+cy[1]*(cx[0]*pixels[4].alpha+
5897 cx[1]*pixels[5].alpha+cx[2]*pixels[6].alpha+cx[3]*pixels[7].alpha)+
5898 cy[2]*(cx[0]*pixels[8].alpha+cx[1]*pixels[9].alpha+cx[2]*
5899 pixels[10].alpha+cx[3]*pixels[11].alpha)+cy[3]*(cx[0]*pixels[12].alpha+
5900 cx[1]*pixels[13].alpha+cx[2]*pixels[14].alpha+cx[3]*pixels[15].alpha));
cristy4c08aed2011-07-01 19:47:50 +00005901 break;
5902 }
5903 }
5904 return(status);
5905}
5906
5907/*
5908%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5909% %
5910% %
5911% %
5912+ I s F u z z y E q u i v a l e n c e P i x e l %
5913% %
5914% %
5915% %
5916%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5917%
5918% IsFuzzyEquivalencePixel() returns MagickTrue if the distance between two
cristya0608292014-10-31 12:37:49 +00005919% pixels is less than the specified distance in a linear three (or four)
cristy4c08aed2011-07-01 19:47:50 +00005920% dimensional color space.
5921%
5922% The format of the IsFuzzyEquivalencePixel method is:
5923%
cristye4a40472011-12-22 02:56:19 +00005924% void IsFuzzyEquivalencePixel(const Image *source,const Quantum *p,
5925% const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005926%
5927% A description of each parameter follows:
5928%
cristye4a40472011-12-22 02:56:19 +00005929% o source: the source image.
cristy4c08aed2011-07-01 19:47:50 +00005930%
5931% o p: Pixel p.
5932%
cristye4a40472011-12-22 02:56:19 +00005933% o destination: the destination image.
5934%
cristy4c08aed2011-07-01 19:47:50 +00005935% o q: Pixel q.
5936%
5937*/
cristye4a40472011-12-22 02:56:19 +00005938MagickExport MagickBooleanType IsFuzzyEquivalencePixel(const Image *source,
5939 const Quantum *p,const Image *destination,const Quantum *q)
cristy4c08aed2011-07-01 19:47:50 +00005940{
cristya19f1d72012-08-07 18:24:38 +00005941 double
cristy4c08aed2011-07-01 19:47:50 +00005942 fuzz,
5943 pixel;
5944
cristya19f1d72012-08-07 18:24:38 +00005945 register double
cristy4c08aed2011-07-01 19:47:50 +00005946 distance,
5947 scale;
5948
cristya664f962015-01-09 00:25:16 +00005949 fuzz=GetFuzzyColorDistance(source,destination);
cristy4c08aed2011-07-01 19:47:50 +00005950 scale=1.0;
5951 distance=0.0;
dirkf0e5dc92015-11-21 12:35:35 +01005952 if (source->alpha_trait != UndefinedPixelTrait ||
5953 destination->alpha_trait != UndefinedPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00005954 {
5955 /*
5956 Transparencies are involved - set alpha distance
5957 */
cristy70e9f682013-03-12 22:31:22 +00005958 pixel=GetPixelAlpha(source,p)-(double) GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005959 distance=pixel*pixel;
5960 if (distance > fuzz)
5961 return(MagickFalse);
5962 /*
5963 Generate a alpha scaling factor to generate a 4D cone on colorspace
5964 Note that if one color is transparent, distance has no color component.
5965 */
dirkf0e5dc92015-11-21 12:35:35 +01005966 if (source->alpha_trait != UndefinedPixelTrait)
5967 scale=QuantumScale*GetPixelAlpha(source,p);
5968 if (destination->alpha_trait != UndefinedPixelTrait)
5969 scale*=QuantumScale*GetPixelAlpha(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005970 if (scale <= MagickEpsilon)
5971 return(MagickTrue);
5972 }
5973 /*
5974 RGB or CMY color cube
5975 */
5976 distance*=3.0; /* rescale appropriately */
5977 fuzz*=3.0;
cristya19f1d72012-08-07 18:24:38 +00005978 pixel=GetPixelRed(source,p)-(double) GetPixelRed(destination,q);
cristye4a40472011-12-22 02:56:19 +00005979 if ((source->colorspace == HSLColorspace) ||
5980 (source->colorspace == HSBColorspace) ||
5981 (source->colorspace == HWBColorspace))
cristy4c08aed2011-07-01 19:47:50 +00005982 {
5983 /*
5984 Compute an arc distance for hue. It should be a vector angle of
5985 'S'/'W' length with 'L'/'B' forming appropriate cones.
5986 */
5987 if (fabs((double) pixel) > (QuantumRange/2))
5988 pixel-=QuantumRange;
5989 pixel*=2;
5990 }
5991 distance+=scale*pixel*pixel;
5992 if (distance > fuzz)
5993 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005994 pixel=GetPixelGreen(source,p)-(double) GetPixelGreen(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005995 distance+=scale*pixel*pixel;
5996 if (distance > fuzz)
5997 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00005998 pixel=GetPixelBlue(source,p)-(double) GetPixelBlue(destination,q);
cristy4c08aed2011-07-01 19:47:50 +00005999 distance+=scale*pixel*pixel;
6000 if (distance > fuzz)
6001 return(MagickFalse);
6002 return(MagickTrue);
6003}
6004
6005/*
6006%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6007% %
6008% %
6009% %
6010+ I s F u z z y E q u i v a l e n c e P i x e l I n f o %
6011% %
6012% %
6013% %
6014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6015%
6016% IsFuzzyEquivalencePixelInfo() returns true if the distance between two
6017% colors is less than the specified distance in a linear three (or four)
6018% dimensional color space.
6019%
cristy5f95f4f2011-10-23 01:01:01 +00006020% This implements the equivalent of:
6021% fuzz < sqrt(color_distance^2 * u.a*v.a + alpha_distance^2)
cristy4c08aed2011-07-01 19:47:50 +00006022%
6023% Which produces a multi-dimensional cone for that colorspace along the
6024% transparency vector.
6025%
cristy5f95f4f2011-10-23 01:01:01 +00006026% For example for an RGB:
cristy4c08aed2011-07-01 19:47:50 +00006027% color_distance^2 = ( (u.r-v.r)^2 + (u.g-v.g)^2 + (u.b-v.b)^2 ) / 3
6028%
6029% See http://www.imagemagick.org/Usage/bugs/fuzz_distance/
6030%
6031% Hue colorspace distances need more work. Hue is not a distance, it is an
6032% angle!
6033%
6034% A check that q is in the same color space as p should be made and the
6035% appropriate mapping made. -- Anthony Thyssen 8 December 2010
6036%
6037% The format of the IsFuzzyEquivalencePixelInfo method is:
6038%
6039% MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6040% const PixelInfo *q)
6041%
6042% A description of each parameter follows:
6043%
6044% o p: Pixel p.
6045%
6046% o q: Pixel q.
6047%
6048*/
6049MagickExport MagickBooleanType IsFuzzyEquivalencePixelInfo(const PixelInfo *p,
6050 const PixelInfo *q)
6051{
cristya19f1d72012-08-07 18:24:38 +00006052 double
cristy4c08aed2011-07-01 19:47:50 +00006053 fuzz,
6054 pixel;
6055
cristya19f1d72012-08-07 18:24:38 +00006056 register double
cristy4c08aed2011-07-01 19:47:50 +00006057 scale,
6058 distance;
6059
cristy043a9812014-12-25 02:03:01 +00006060 fuzz=(double) MagickMax(MagickMax(p->fuzz,q->fuzz),(MagickRealType)
6061 MagickSQ1_2);
6062 fuzz*=fuzz;
cristy4c08aed2011-07-01 19:47:50 +00006063 scale=1.0;
6064 distance=0.0;
cristy17f11b02014-12-20 19:37:04 +00006065 if ((p->alpha_trait != UndefinedPixelTrait) ||
6066 (q->alpha_trait != UndefinedPixelTrait))
cristy4c08aed2011-07-01 19:47:50 +00006067 {
6068 /*
6069 Transparencies are involved - set alpha distance.
6070 */
cristy17f11b02014-12-20 19:37:04 +00006071 pixel=(p->alpha_trait != UndefinedPixelTrait ? p->alpha : OpaqueAlpha)-
6072 (q->alpha_trait != UndefinedPixelTrait ? q->alpha : OpaqueAlpha);
cristy4c08aed2011-07-01 19:47:50 +00006073 distance=pixel*pixel;
6074 if (distance > fuzz)
6075 return(MagickFalse);
6076 /*
6077 Generate a alpha scaling factor to generate a 4D cone on colorspace.
cristy5f95f4f2011-10-23 01:01:01 +00006078 If one color is transparent, distance has no color component.
cristy4c08aed2011-07-01 19:47:50 +00006079 */
cristy17f11b02014-12-20 19:37:04 +00006080 if (p->alpha_trait != UndefinedPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00006081 scale=(QuantumScale*p->alpha);
cristy17f11b02014-12-20 19:37:04 +00006082 if (q->alpha_trait != UndefinedPixelTrait)
cristy4c08aed2011-07-01 19:47:50 +00006083 scale*=(QuantumScale*q->alpha);
6084 if (scale <= MagickEpsilon )
6085 return(MagickTrue);
6086 }
6087 /*
6088 CMYK create a CMY cube with a multi-dimensional cone toward black.
6089 */
6090 if (p->colorspace == CMYKColorspace)
6091 {
6092 pixel=p->black-q->black;
6093 distance+=pixel*pixel*scale;
6094 if (distance > fuzz)
6095 return(MagickFalse);
cristya19f1d72012-08-07 18:24:38 +00006096 scale*=(double) (QuantumScale*(QuantumRange-p->black));
6097 scale*=(double) (QuantumScale*(QuantumRange-q->black));
cristy4c08aed2011-07-01 19:47:50 +00006098 }
6099 /*
6100 RGB or CMY color cube.
6101 */
6102 distance*=3.0; /* rescale appropriately */
6103 fuzz*=3.0;
6104 pixel=p->red-q->red;
6105 if ((p->colorspace == HSLColorspace) || (p->colorspace == HSBColorspace) ||
6106 (p->colorspace == HWBColorspace))
6107 {
cristy5f95f4f2011-10-23 01:01:01 +00006108 /*
cristy58ee5012013-05-26 23:58:44 +00006109 This calculates a arc distance for hue-- it should be a vector
6110 angle of 'S'/'W' length with 'L'/'B' forming appropriate cones.
6111 In other words this is a hack - Anthony.
cristy4c08aed2011-07-01 19:47:50 +00006112 */
6113 if (fabs((double) pixel) > (QuantumRange/2))
6114 pixel-=QuantumRange;
6115 pixel*=2;
6116 }
6117 distance+=pixel*pixel*scale;
6118 if (distance > fuzz)
6119 return(MagickFalse);
6120 pixel=p->green-q->green;
6121 distance+=pixel*pixel*scale;
6122 if (distance > fuzz)
6123 return(MagickFalse);
6124 pixel=p->blue-q->blue;
6125 distance+=pixel*pixel*scale;
6126 if (distance > fuzz)
6127 return(MagickFalse);
6128 return(MagickTrue);
6129}
6130
6131/*
6132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6133% %
6134% %
6135% %
cristy7ae16542013-05-15 22:41:24 +00006136% S e t P i x e l C h a n n e l M a s k %
cristy2b9582a2011-07-04 17:38:56 +00006137% %
6138% %
6139% %
6140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6141%
cristy7ae16542013-05-15 22:41:24 +00006142% SetPixelChannelMask() sets the pixel channel map from the specified channel
6143% mask.
cristy2b9582a2011-07-04 17:38:56 +00006144%
cristycf1296e2012-08-26 23:40:49 +00006145% The format of the SetPixelChannelMask method is:
cristy2b9582a2011-07-04 17:38:56 +00006146%
cristybcd59342015-06-07 14:07:19 +00006147% ChannelType SetPixelChannelMask(Image *image,
6148% const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00006149%
6150% A description of each parameter follows:
6151%
6152% o image: the image.
6153%
cristydfdb19e2012-03-21 22:22:24 +00006154% o channel_mask: the channel mask.
cristy2b9582a2011-07-04 17:38:56 +00006155%
6156*/
Cristy1461e332017-02-11 20:35:35 -05006157
6158static void LogPixelChannels(const Image *image)
6159{
6160 register ssize_t
6161 i;
6162
6163 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]",
6164 image->filename,image->channel_mask);
6165 for (i=0; i < (ssize_t) image->number_channels; i++)
6166 {
6167 char
6168 channel_name[MagickPathExtent],
6169 traits[MagickPathExtent];
6170
6171 const char
6172 *name;
6173
6174 PixelChannel
6175 channel;
6176
6177 channel=GetPixelChannelChannel(image,i);
6178 switch (channel)
6179 {
6180 case RedPixelChannel:
6181 {
6182 name="red";
6183 if (image->colorspace == CMYKColorspace)
6184 name="cyan";
6185 if (image->colorspace == GRAYColorspace)
6186 name="gray";
6187 break;
6188 }
6189 case GreenPixelChannel:
6190 {
6191 name="green";
6192 if (image->colorspace == CMYKColorspace)
6193 name="magenta";
6194 break;
6195 }
6196 case BluePixelChannel:
6197 {
6198 name="blue";
6199 if (image->colorspace == CMYKColorspace)
6200 name="yellow";
6201 break;
6202 }
6203 case BlackPixelChannel:
6204 {
6205 name="black";
6206 if (image->storage_class == PseudoClass)
6207 name="index";
6208 break;
6209 }
6210 case IndexPixelChannel:
6211 {
6212 name="index";
6213 break;
6214 }
6215 case AlphaPixelChannel:
6216 {
6217 name="alpha";
6218 break;
6219 }
6220 case ReadMaskPixelChannel:
6221 {
6222 name="read-mask";
6223 break;
6224 }
6225 case WriteMaskPixelChannel:
6226 {
6227 name="write-mask";
6228 break;
6229 }
6230 case MetaPixelChannel:
6231 {
6232 name="meta";
6233 break;
6234 }
6235 default:
6236 name="undefined";
6237 }
6238 if (image->colorspace == UndefinedColorspace)
6239 {
6240 (void) FormatLocaleString(channel_name,MagickPathExtent,"%.20g",
6241 (double) channel);
6242 name=(const char *) channel_name;
6243 }
6244 *traits='\0';
6245 if ((GetPixelChannelTraits(image,channel) & UpdatePixelTrait) != 0)
6246 (void) ConcatenateMagickString(traits,"update,",MagickPathExtent);
6247 if ((GetPixelChannelTraits(image,channel) & BlendPixelTrait) != 0)
6248 (void) ConcatenateMagickString(traits,"blend,",MagickPathExtent);
6249 if ((GetPixelChannelTraits(image,channel) & CopyPixelTrait) != 0)
6250 (void) ConcatenateMagickString(traits,"copy,",MagickPathExtent);
6251 if (*traits == '\0')
6252 (void) ConcatenateMagickString(traits,"undefined,",MagickPathExtent);
6253 traits[strlen(traits)-1]='\0';
6254 (void) LogMagickEvent(PixelEvent,GetMagickModule()," %.20g: %s (%s)",
6255 (double) i,name,traits);
6256 }
6257}
6258
cristybcd59342015-06-07 14:07:19 +00006259MagickExport ChannelType SetPixelChannelMask(Image *image,
cristy07a67852011-08-26 13:25:03 +00006260 const ChannelType channel_mask)
cristy2b9582a2011-07-04 17:38:56 +00006261{
cristy6a917d62011-08-24 17:31:30 +00006262#define GetChannelBit(mask,bit) (((size_t) (mask) >> (size_t) (bit)) & 0x01)
cristydafd2872011-07-24 22:06:13 +00006263
cristybcd59342015-06-07 14:07:19 +00006264 ChannelType
6265 mask;
6266
cristy2b9582a2011-07-04 17:38:56 +00006267 register ssize_t
6268 i;
6269
cristybcd59342015-06-07 14:07:19 +00006270 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +00006271 assert(image->signature == MagickCoreSignature);
cristy177e41c2012-04-15 15:08:25 +00006272 if (image->debug != MagickFalse)
cristyf30396d2014-09-28 16:01:53 +00006273 (void) LogMagickEvent(PixelEvent,GetMagickModule(),"%s[%08x]",
6274 image->filename,channel_mask);
cristybcd59342015-06-07 14:07:19 +00006275 mask=image->channel_mask;
cristy3c309812011-11-08 02:40:43 +00006276 image->channel_mask=channel_mask;
cristydafd2872011-07-24 22:06:13 +00006277 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
cristye2a912b2011-12-05 20:02:07 +00006278 {
cristy5a23c552013-02-13 14:34:28 +00006279 PixelChannel channel=GetPixelChannelChannel(image,i);
cristy17f11b02014-12-20 19:37:04 +00006280 if (GetChannelBit(channel_mask,channel) == 0)
6281 {
6282 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6283 continue;
6284 }
cristy62cc94b2014-12-19 00:30:56 +00006285 if (channel == AlphaPixelChannel)
cristy17f11b02014-12-20 19:37:04 +00006286 {
6287 if ((image->alpha_trait & CopyPixelTrait) != 0)
6288 {
6289 SetPixelChannelTraits(image,channel,CopyPixelTrait);
6290 continue;
6291 }
Cristy94812662017-02-12 08:23:32 -05006292 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
6293 continue;
cristy17f11b02014-12-20 19:37:04 +00006294 }
Cristy94812662017-02-12 08:23:32 -05006295 if (image->alpha_trait != UndefinedPixelTrait)
6296 {
6297 SetPixelChannelTraits(image,channel,(const PixelTrait)
6298 (UpdatePixelTrait | BlendPixelTrait));
6299 continue;
6300 }
cristy17f11b02014-12-20 19:37:04 +00006301 SetPixelChannelTraits(image,channel,UpdatePixelTrait);
cristye2a912b2011-12-05 20:02:07 +00006302 }
cristy1685e722011-09-06 00:04:19 +00006303 if (image->storage_class == PseudoClass)
cristy297e3a42012-08-26 21:27:29 +00006304 SetPixelChannelTraits(image,IndexPixelChannel,CopyPixelTrait);
cristy883fde12013-04-08 00:50:13 +00006305 if (image->read_mask != MagickFalse)
6306 SetPixelChannelTraits(image,ReadMaskPixelChannel,CopyPixelTrait);
6307 if (image->write_mask != MagickFalse)
6308 SetPixelChannelTraits(image,WriteMaskPixelChannel,CopyPixelTrait);
cristy6dcb9b82011-10-23 23:21:25 +00006309 if (image->debug != MagickFalse)
6310 LogPixelChannels(image);
cristybcd59342015-06-07 14:07:19 +00006311 return(mask);
cristy2b9582a2011-07-04 17:38:56 +00006312}
6313
6314/*
6315%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6316% %
6317% %
6318% %
cristy322d07d2012-03-18 21:17:23 +00006319% S e t P i x e l M e t a C h a n n e l s %
6320% %
6321% %
6322% %
6323%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6324%
6325% SetPixelMetaChannels() sets the image meta channels.
6326%
6327% The format of the SetPixelMetaChannels method is:
6328%
6329% MagickBooleanType SetPixelMetaChannels(Image *image,
6330% const size_t number_meta_channels,ExceptionInfo *exception)
6331%
6332% A description of each parameter follows:
6333%
6334% o image: the image.
6335%
6336% o number_meta_channels: the number of meta channels.
6337%
6338% o exception: return any errors or warnings in this structure.
6339%
6340*/
6341MagickExport MagickBooleanType SetPixelMetaChannels(Image *image,
6342 const size_t number_meta_channels,ExceptionInfo *exception)
6343{
6344 image->number_meta_channels=number_meta_channels;
Cristy29f8d572017-02-03 08:33:50 -05006345 InitializePixelChannelMap(image);
cristy322d07d2012-03-18 21:17:23 +00006346 return(SyncImagePixelCache(image,exception));
6347}