blob: b7bee3907402892583aa7b7b88a51e77ffcc364b [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% QQQ U U AAA N N TTTTT U U M M %
7% Q Q U U A A NN N T U U MM MM %
8% Q Q U U AAAAA N N N T U U M M M %
9% Q QQ U U A A N NN T U U M M %
10% QQQQ UUU A A N N T UUU M M %
11% %
12% MagicCore Methods to Acquire / Destroy Quantum Pixels %
13% %
14% Software Design %
cristyde984cd2013-12-01 14:49:27 +000015% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000016% October 1998 %
17% %
18% %
cristyb56bb242014-11-25 17:12:48 +000019% Copyright 1999-2015 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +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% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
cristy4c08aed2011-07-01 19:47:50 +000041#include "MagickCore/studio.h"
42#include "MagickCore/attribute.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/color-private.h"
46#include "MagickCore/exception.h"
47#include "MagickCore/exception-private.h"
48#include "MagickCore/cache.h"
cristy16d9c1a2014-12-14 15:28:39 +000049#include "MagickCore/cache-private.h"
cristy4c08aed2011-07-01 19:47:50 +000050#include "MagickCore/constitute.h"
51#include "MagickCore/delegate.h"
52#include "MagickCore/geometry.h"
53#include "MagickCore/list.h"
54#include "MagickCore/magick.h"
55#include "MagickCore/memory_.h"
56#include "MagickCore/monitor.h"
57#include "MagickCore/option.h"
58#include "MagickCore/pixel.h"
59#include "MagickCore/pixel-accessor.h"
60#include "MagickCore/property.h"
61#include "MagickCore/quantum.h"
62#include "MagickCore/quantum-private.h"
63#include "MagickCore/resource_.h"
64#include "MagickCore/semaphore.h"
65#include "MagickCore/statistic.h"
66#include "MagickCore/stream.h"
67#include "MagickCore/string_.h"
68#include "MagickCore/string-private.h"
69#include "MagickCore/thread-private.h"
70#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000071
72/*
73 Define declarations.
74*/
75#define QuantumSignature 0xab
76
77/*
78 Forward declarations.
79*/
80static void
81 DestroyQuantumPixels(QuantumInfo *);
82
83/*
84%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
85% %
86% %
87% %
88% A c q u i r e Q u a n t u m I n f o %
89% %
90% %
91% %
92%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93%
94% AcquireQuantumInfo() allocates the QuantumInfo structure.
95%
96% The format of the AcquireQuantumInfo method is:
97%
cristy5f766ef2014-12-14 21:12:47 +000098% QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
cristy3ed852e2009-09-05 21:47:34 +000099%
100% A description of each parameter follows:
101%
102% o image_info: the image info.
103%
104% o image: the image.
105%
106*/
cristy3ed852e2009-09-05 21:47:34 +0000107MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
cristy5f766ef2014-12-14 21:12:47 +0000108 Image *image)
cristy3ed852e2009-09-05 21:47:34 +0000109{
110 MagickBooleanType
111 status;
112
113 QuantumInfo
114 *quantum_info;
115
cristy73bd4a52010-10-05 11:24:23 +0000116 quantum_info=(QuantumInfo *) AcquireMagickMemory(sizeof(*quantum_info));
cristy3ed852e2009-09-05 21:47:34 +0000117 if (quantum_info == (QuantumInfo *) NULL)
118 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
119 quantum_info->signature=MagickSignature;
120 GetQuantumInfo(image_info,quantum_info);
121 if (image == (const Image *) NULL)
122 return(quantum_info);
123 status=SetQuantumDepth(image,quantum_info,image->depth);
cristyc32a4022013-03-15 15:08:09 +0000124 quantum_info->endian=image->endian;
cristy3ed852e2009-09-05 21:47:34 +0000125 if (status == MagickFalse)
126 quantum_info=DestroyQuantumInfo(quantum_info);
127 return(quantum_info);
128}
129
130/*
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132% %
133% %
134% %
135+ A c q u i r e Q u a n t u m P i x e l s %
136% %
137% %
138% %
139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140%
cristy16d9c1a2014-12-14 15:28:39 +0000141% AcquireQuantumPixels() allocates the pixel staging areas.
cristy3ed852e2009-09-05 21:47:34 +0000142%
143% The format of the AcquireQuantumPixels method is:
144%
145% MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
146% const size_t extent)
147%
148% A description of each parameter follows:
149%
150% o quantum_info: the quantum info.
151%
152% o extent: the quantum info.
153%
154*/
155static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
156 const size_t extent)
157{
cristybb503372010-05-27 20:51:26 +0000158 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000159 i;
160
161 assert(quantum_info != (QuantumInfo *) NULL);
162 assert(quantum_info->signature == MagickSignature);
cristy9357bdd2012-07-30 12:28:34 +0000163 quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
cristy3ed852e2009-09-05 21:47:34 +0000164 quantum_info->pixels=(unsigned char **) AcquireQuantumMemory(
165 quantum_info->number_threads,sizeof(*quantum_info->pixels));
166 if (quantum_info->pixels == (unsigned char **) NULL)
167 return(MagickFalse);
168 quantum_info->extent=extent;
cristy5c6cd592012-04-23 00:57:38 +0000169 (void) ResetMagickMemory(quantum_info->pixels,0,quantum_info->number_threads*
170 sizeof(*quantum_info->pixels));
cristybb503372010-05-27 20:51:26 +0000171 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
cristy3ed852e2009-09-05 21:47:34 +0000172 {
173 quantum_info->pixels[i]=(unsigned char *) AcquireQuantumMemory(extent+1,
174 sizeof(**quantum_info->pixels));
cristy84787932009-10-06 19:18:19 +0000175 if (quantum_info->pixels[i] == (unsigned char *) NULL)
cristy16d9c1a2014-12-14 15:28:39 +0000176 {
177 while (--i >= 0)
178 quantum_info->pixels[i]=(unsigned char *) RelinquishMagickMemory(
179 quantum_info->pixels[i]);
180 return(MagickFalse);
181 }
cristy3ed852e2009-09-05 21:47:34 +0000182 (void) ResetMagickMemory(quantum_info->pixels[i],0,(extent+1)*
183 sizeof(**quantum_info->pixels));
184 quantum_info->pixels[i][extent]=QuantumSignature;
185 }
186 return(MagickTrue);
187}
188
189/*
190%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
191% %
192% %
193% %
194% D e s t r o y Q u a n t u m I n f o %
195% %
196% %
197% %
198%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
199%
200% DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
201% structure.
202%
203% The format of the DestroyQuantumInfo method is:
204%
205% QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
206%
207% A description of each parameter follows:
208%
209% o quantum_info: the quantum info.
210%
211*/
212MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
213{
214 assert(quantum_info != (QuantumInfo *) NULL);
215 assert(quantum_info->signature == MagickSignature);
216 if (quantum_info->pixels != (unsigned char **) NULL)
217 DestroyQuantumPixels(quantum_info);
218 if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
cristy3d162a92014-02-16 14:05:06 +0000219 RelinquishSemaphoreInfo(&quantum_info->semaphore);
cristy3ed852e2009-09-05 21:47:34 +0000220 quantum_info->signature=(~MagickSignature);
221 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
222 return(quantum_info);
223}
224
225/*
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227% %
228% %
229% %
230+ D e s t r o y Q u a n t u m P i x e l s %
231% %
232% %
233% %
234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235%
236% DestroyQuantumPixels() destroys the quantum pixels.
237%
238% The format of the DestroyQuantumPixels() method is:
239%
240% void DestroyQuantumPixels(QuantumInfo *quantum_info)
241%
242% A description of each parameter follows:
243%
244% o quantum_info: the quantum info.
245%
246*/
247static void DestroyQuantumPixels(QuantumInfo *quantum_info)
248{
cristybb503372010-05-27 20:51:26 +0000249 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000250 i;
251
cristy4362aac2010-10-06 18:52:08 +0000252 ssize_t
253 extent;
254
cristy3ed852e2009-09-05 21:47:34 +0000255 assert(quantum_info != (QuantumInfo *) NULL);
256 assert(quantum_info->signature == MagickSignature);
257 assert(quantum_info->pixels != (unsigned char **) NULL);
cristy55a91cd2010-12-01 00:57:40 +0000258 extent=(ssize_t) quantum_info->extent;
cristybb503372010-05-27 20:51:26 +0000259 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
cristyed6b55a2010-10-06 02:15:05 +0000260 if (quantum_info->pixels[i] != (unsigned char *) NULL)
261 {
262 /*
263 Did we overrun our quantum buffer?
264 */
cristy4362aac2010-10-06 18:52:08 +0000265 assert(quantum_info->pixels[i][extent] == QuantumSignature);
cristyed6b55a2010-10-06 02:15:05 +0000266 quantum_info->pixels[i]=(unsigned char *) RelinquishMagickMemory(
267 quantum_info->pixels[i]);
268 }
cristy3ed852e2009-09-05 21:47:34 +0000269 quantum_info->pixels=(unsigned char **) RelinquishMagickMemory(
270 quantum_info->pixels);
271}
272
273/*
274%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275% %
276% %
277% %
278% G e t Q u a n t u m E x t e n t %
279% %
280% %
281% %
282%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283%
284% GetQuantumExtent() returns the quantum pixel buffer extent.
285%
286% The format of the GetQuantumExtent method is:
287%
288% size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
289% const QuantumType quantum_type)
290%
291% A description of each parameter follows:
292%
293% o image: the image.
294%
295% o quantum_info: the quantum info.
296%
297% o quantum_type: Declare which pixel components to transfer (red, green,
298% blue, opacity, RGB, or RGBA).
299%
300*/
301MagickExport size_t GetQuantumExtent(const Image *image,
302 const QuantumInfo *quantum_info,const QuantumType quantum_type)
303{
304 size_t
305 packet_size;
306
307 assert(quantum_info != (QuantumInfo *) NULL);
308 assert(quantum_info->signature == MagickSignature);
309 packet_size=1;
310 switch (quantum_type)
311 {
312 case GrayAlphaQuantum: packet_size=2; break;
313 case IndexAlphaQuantum: packet_size=2; break;
314 case RGBQuantum: packet_size=3; break;
cristy1f9852b2010-09-04 15:05:36 +0000315 case BGRQuantum: packet_size=3; break;
cristy3ed852e2009-09-05 21:47:34 +0000316 case RGBAQuantum: packet_size=4; break;
317 case RGBOQuantum: packet_size=4; break;
cristy1f9852b2010-09-04 15:05:36 +0000318 case BGRAQuantum: packet_size=4; break;
cristy3ed852e2009-09-05 21:47:34 +0000319 case CMYKQuantum: packet_size=4; break;
320 case CMYKAQuantum: packet_size=5; break;
321 default: break;
322 }
323 if (quantum_info->pack == MagickFalse)
cristyc9672a92010-01-06 00:57:45 +0000324 return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
325 return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
cristy3ed852e2009-09-05 21:47:34 +0000326}
327
328/*
329%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
330% %
331% %
332% %
cristy9d4918b2012-11-14 20:18:32 +0000333% G e t Q u a n t u m E n d i a n %
334% %
335% %
336% %
337%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338%
339% GetQuantumEndian() returns the quantum endian of the image.
340%
341% The endian of the GetQuantumEndian method is:
342%
343% EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
344%
345% A description of each parameter follows:
346%
347% o quantum_info: the quantum info.
348%
349*/
350MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
351{
352 assert(quantum_info != (QuantumInfo *) NULL);
353 assert(quantum_info->signature == MagickSignature);
354 return(quantum_info->endian);
355}
356
357/*
358%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
359% %
360% %
361% %
cristye11d00a2011-12-06 18:03:25 +0000362% G e t Q u a n t u m F o r m a t %
363% %
364% %
365% %
366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367%
368% GetQuantumFormat() returns the quantum format of the image.
369%
370% The format of the GetQuantumFormat method is:
371%
372% QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
373%
374% A description of each parameter follows:
375%
376% o quantum_info: the quantum info.
377%
378*/
379MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
380{
381 assert(quantum_info != (QuantumInfo *) NULL);
382 assert(quantum_info->signature == MagickSignature);
383 return(quantum_info->format);
384}
385
386/*
387%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388% %
389% %
390% %
cristy3ed852e2009-09-05 21:47:34 +0000391% G e t Q u a n t u m I n f o %
392% %
393% %
394% %
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396%
397% GetQuantumInfo() initializes the QuantumInfo structure to default values.
398%
399% The format of the GetQuantumInfo method is:
400%
401% GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
402%
403% A description of each parameter follows:
404%
405% o image_info: the image info.
406%
407% o quantum_info: the quantum info.
408%
409*/
410MagickExport void GetQuantumInfo(const ImageInfo *image_info,
411 QuantumInfo *quantum_info)
412{
413 const char
414 *option;
415
416 assert(quantum_info != (QuantumInfo *) NULL);
417 (void) ResetMagickMemory(quantum_info,0,sizeof(*quantum_info));
418 quantum_info->quantum=8;
419 quantum_info->maximum=1.0;
420 quantum_info->scale=QuantumRange;
421 quantum_info->pack=MagickTrue;
cristy3d162a92014-02-16 14:05:06 +0000422 quantum_info->semaphore=AcquireSemaphoreInfo();
cristy3ed852e2009-09-05 21:47:34 +0000423 quantum_info->signature=MagickSignature;
424 if (image_info == (const ImageInfo *) NULL)
425 return;
426 option=GetImageOption(image_info,"quantum:format");
427 if (option != (char *) NULL)
cristy042ee782011-04-22 18:48:30 +0000428 quantum_info->format=(QuantumFormatType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +0000429 MagickQuantumFormatOptions,MagickFalse,option);
430 option=GetImageOption(image_info,"quantum:minimum");
431 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000432 quantum_info->minimum=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000433 option=GetImageOption(image_info,"quantum:maximum");
434 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000435 quantum_info->maximum=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000436 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
437 quantum_info->scale=0.0;
438 else
439 if (quantum_info->minimum == quantum_info->maximum)
440 {
cristya19f1d72012-08-07 18:24:38 +0000441 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
cristy3ed852e2009-09-05 21:47:34 +0000442 quantum_info->minimum=0.0;
443 }
444 else
cristya19f1d72012-08-07 18:24:38 +0000445 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
cristy3ed852e2009-09-05 21:47:34 +0000446 quantum_info->minimum);
447 option=GetImageOption(image_info,"quantum:scale");
448 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000449 quantum_info->scale=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000450 option=GetImageOption(image_info,"quantum:polarity");
451 if (option != (char *) NULL)
452 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
453 MagickTrue : MagickFalse;
cristy32c68432012-01-12 15:06:28 +0000454 quantum_info->endian=image_info->endian;
455 ResetQuantumState(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000456}
457
458/*
459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
460% %
461% %
462% %
463% G e t Q u a n t u m P i x e l s %
464% %
465% %
466% %
467%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468%
469% GetQuantumPixels() returns the quantum pixels.
470%
471% The format of the GetQuantumPixels method is:
472%
473% unsigned char *QuantumPixels GetQuantumPixels(
474% const QuantumInfo *quantum_info)
475%
476% A description of each parameter follows:
477%
478% o image: the image.
479%
480*/
481MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
482{
cristy5c9e6f22010-09-17 17:31:01 +0000483 const int
484 id = GetOpenMPThreadId();
cristy3ed852e2009-09-05 21:47:34 +0000485
486 assert(quantum_info != (QuantumInfo *) NULL);
487 assert(quantum_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +0000488 return(quantum_info->pixels[id]);
489}
490
491/*
492%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
493% %
494% %
495% %
496% G e t Q u a n t u m T y p e %
497% %
498% %
499% %
500%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501%
502% GetQuantumType() returns the quantum type of the image.
503%
504% The format of the GetQuantumType method is:
505%
506% QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
507%
508% A description of each parameter follows:
509%
510% o image: the image.
511%
cristy5b4868f2014-12-14 17:43:35 +0000512% o exception: return any errors or warnings in this structure.
513%
cristy3ed852e2009-09-05 21:47:34 +0000514*/
515MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
516{
517 QuantumType
518 quantum_type;
519
520 assert(image != (Image *) NULL);
521 assert(image->signature == MagickSignature);
522 if (image->debug != MagickFalse)
523 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
524 quantum_type=RGBQuantum;
cristy9f36ba72014-12-07 22:55:01 +0000525 if (image->alpha_trait != UndefinedPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000526 quantum_type=RGBAQuantum;
527 if (image->colorspace == CMYKColorspace)
528 {
529 quantum_type=CMYKQuantum;
cristy9f36ba72014-12-07 22:55:01 +0000530 if (image->alpha_trait != UndefinedPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000531 quantum_type=CMYKAQuantum;
532 }
cristy4c08aed2011-07-01 19:47:50 +0000533 if (IsImageGray(image,exception) != MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000534 {
535 quantum_type=GrayQuantum;
cristy9f36ba72014-12-07 22:55:01 +0000536 if (image->alpha_trait != UndefinedPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000537 quantum_type=GrayAlphaQuantum;
538 }
cristybdbf4b62012-05-13 22:22:59 +0000539 if (image->storage_class == PseudoClass)
540 {
541 quantum_type=IndexQuantum;
cristy9f36ba72014-12-07 22:55:01 +0000542 if (image->alpha_trait != UndefinedPixelTrait)
cristybdbf4b62012-05-13 22:22:59 +0000543 quantum_type=IndexAlphaQuantum;
544 }
cristy3ed852e2009-09-05 21:47:34 +0000545 return(quantum_type);
546}
547
548/*
549%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
550% %
551% %
552% %
cristy79630222012-01-14 01:38:37 +0000553+ R e s e t Q u a n t u m S t a t e %
cristy32c68432012-01-12 15:06:28 +0000554% %
555% %
556% %
557%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
558%
559% ResetQuantumState() resets the quantum state.
560%
561% The format of the ResetQuantumState method is:
562%
563% void ResetQuantumState(QuantumInfo *quantum_info)
564%
565% A description of each parameter follows:
566%
567% o quantum_info: the quantum info.
568%
569*/
cristy79630222012-01-14 01:38:37 +0000570MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
cristy32c68432012-01-12 15:06:28 +0000571{
572 static const unsigned int mask[32] =
573 {
574 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
575 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
576 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
577 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
578 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
579 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
580 0x3fffffffU, 0x7fffffffU
581 };
582
583 assert(quantum_info != (QuantumInfo *) NULL);
584 assert(quantum_info->signature == MagickSignature);
585 quantum_info->state.inverse_scale=1.0;
586 if (fabs(quantum_info->scale) >= MagickEpsilon)
587 quantum_info->state.inverse_scale/=quantum_info->scale;
588 quantum_info->state.pixel=0U;
589 quantum_info->state.bits=0U;
590 quantum_info->state.mask=mask;
591}
592
593/*
594%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
595% %
596% %
597% %
cristy3ed852e2009-09-05 21:47:34 +0000598% S e t Q u a n t u m F o r m a t %
599% %
600% %
601% %
602%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603%
604% SetQuantumAlphaType() sets the quantum format.
605%
606% The format of the SetQuantumAlphaType method is:
607%
608% void SetQuantumAlphaType(QuantumInfo *quantum_info,
609% const QuantumAlphaType type)
610%
611% A description of each parameter follows:
612%
613% o quantum_info: the quantum info.
614%
615% o type: the alpha type (e.g. associate).
616%
617*/
618MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
619 const QuantumAlphaType type)
620{
621 assert(quantum_info != (QuantumInfo *) NULL);
622 assert(quantum_info->signature == MagickSignature);
623 quantum_info->alpha_type=type;
624}
625
626/*
627%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
628% %
629% %
630% %
631% S e t Q u a n t u m D e p t h %
632% %
633% %
634% %
635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
636%
637% SetQuantumDepth() sets the quantum depth.
638%
639% The format of the SetQuantumDepth method is:
640%
641% MagickBooleanType SetQuantumDepth(const Image *image,
cristybb503372010-05-27 20:51:26 +0000642% QuantumInfo *quantum_info,const size_t depth)
cristy3ed852e2009-09-05 21:47:34 +0000643%
644% A description of each parameter follows:
645%
646% o image: the image.
647%
648% o quantum_info: the quantum info.
649%
650% o depth: the quantum depth.
651%
652*/
653MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
cristybb503372010-05-27 20:51:26 +0000654 QuantumInfo *quantum_info,const size_t depth)
cristy3ed852e2009-09-05 21:47:34 +0000655{
cristy56d88542014-12-01 01:13:30 +0000656 size_t
657 extent,
658 quantum;
cristy3ed852e2009-09-05 21:47:34 +0000659
660 /*
661 Allocate the quantum pixel buffer.
662 */
663 assert(image != (Image *) NULL);
664 assert(image->signature == MagickSignature);
665 if (image->debug != MagickFalse)
666 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
667 assert(quantum_info != (QuantumInfo *) NULL);
668 assert(quantum_info->signature == MagickSignature);
669 quantum_info->depth=depth;
670 if (quantum_info->format == FloatingPointQuantumFormat)
671 {
672 if (quantum_info->depth > 32)
673 quantum_info->depth=64;
674 else
cristyc9672a92010-01-06 00:57:45 +0000675 if (quantum_info->depth > 16)
676 quantum_info->depth=32;
677 else
678 quantum_info->depth=16;
cristy3ed852e2009-09-05 21:47:34 +0000679 }
cristy3ed852e2009-09-05 21:47:34 +0000680 if (quantum_info->pixels != (unsigned char **) NULL)
681 DestroyQuantumPixels(quantum_info);
cristy56d88542014-12-01 01:13:30 +0000682 quantum=(quantum_info->pad+6)*(quantum_info->depth+7)/8;
683 extent=image->columns*quantum;
684 if (quantum != (extent/image->columns))
685 return(MagickFalse);
686 return(AcquireQuantumPixels(quantum_info,extent));
cristy3ed852e2009-09-05 21:47:34 +0000687}
688
689/*
690%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
691% %
692% %
693% %
cristy9d4918b2012-11-14 20:18:32 +0000694% S e t Q u a n t u m E n d i a n %
695% %
696% %
697% %
698%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
699%
700% SetQuantumEndian() sets the quantum endian.
701%
702% The endian of the SetQuantumEndian method is:
703%
704% MagickBooleanType SetQuantumEndian(const Image *image,
705% QuantumInfo *quantum_info,const EndianType endian)
706%
707% A description of each parameter follows:
708%
709% o image: the image.
710%
711% o quantum_info: the quantum info.
712%
713% o endian: the quantum endian.
714%
715*/
716MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
717 QuantumInfo *quantum_info,const EndianType endian)
718{
719 assert(image != (Image *) NULL);
720 assert(image->signature == MagickSignature);
721 if (image->debug != MagickFalse)
722 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
723 assert(quantum_info != (QuantumInfo *) NULL);
724 assert(quantum_info->signature == MagickSignature);
725 quantum_info->endian=endian;
726 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
727}
728
729/*
730%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731% %
732% %
733% %
cristy3ed852e2009-09-05 21:47:34 +0000734% S e t Q u a n t u m F o r m a t %
735% %
736% %
737% %
738%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
739%
740% SetQuantumFormat() sets the quantum format.
741%
742% The format of the SetQuantumFormat method is:
743%
744% MagickBooleanType SetQuantumFormat(const Image *image,
745% QuantumInfo *quantum_info,const QuantumFormatType format)
746%
747% A description of each parameter follows:
748%
749% o image: the image.
750%
751% o quantum_info: the quantum info.
752%
753% o format: the quantum format.
754%
755*/
756MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
757 QuantumInfo *quantum_info,const QuantumFormatType format)
758{
759 assert(image != (Image *) NULL);
760 assert(image->signature == MagickSignature);
761 if (image->debug != MagickFalse)
762 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
763 assert(quantum_info != (QuantumInfo *) NULL);
764 assert(quantum_info->signature == MagickSignature);
765 quantum_info->format=format;
766 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
767}
768
769/*
770%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
771% %
772% %
773% %
774% S e t Q u a n t u m I m a g e T y p e %
775% %
776% %
777% %
778%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
779%
780% SetQuantumImageType() sets the image type based on the quantum type.
781%
782% The format of the SetQuantumImageType method is:
783%
784% void ImageType SetQuantumImageType(Image *image,
785% const QuantumType quantum_type)
786%
787% A description of each parameter follows:
788%
789% o image: the image.
790%
791% o quantum_type: Declare which pixel components to transfer (red, green,
792% blue, opacity, RGB, or RGBA).
793%
794*/
795MagickExport void SetQuantumImageType(Image *image,
796 const QuantumType quantum_type)
797{
798 assert(image != (Image *) NULL);
799 assert(image->signature == MagickSignature);
800 if (image->debug != MagickFalse)
801 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
802 switch (quantum_type)
803 {
804 case IndexQuantum:
805 case IndexAlphaQuantum:
806 {
807 image->type=PaletteType;
808 break;
809 }
810 case GrayQuantum:
811 case GrayAlphaQuantum:
812 {
813 image->type=GrayscaleType;
814 if (image->depth == 1)
815 image->type=BilevelType;
816 break;
817 }
818 case CyanQuantum:
819 case MagentaQuantum:
820 case YellowQuantum:
821 case BlackQuantum:
822 case CMYKQuantum:
823 case CMYKAQuantum:
824 {
825 image->type=ColorSeparationType;
826 break;
827 }
828 default:
829 {
830 image->type=TrueColorType;
831 break;
832 }
833 }
834}
835
836/*
837%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
838% %
839% %
840% %
841% S e t Q u a n t u m P a c k %
842% %
843% %
844% %
845%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
846%
847% SetQuantumPack() sets the quantum pack flag.
848%
849% The format of the SetQuantumPack method is:
850%
851% void SetQuantumPack(QuantumInfo *quantum_info,
852% const MagickBooleanType pack)
853%
854% A description of each parameter follows:
855%
856% o quantum_info: the quantum info.
857%
858% o pack: the pack flag.
859%
860*/
861MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
862 const MagickBooleanType pack)
863{
864 assert(quantum_info != (QuantumInfo *) NULL);
865 assert(quantum_info->signature == MagickSignature);
866 quantum_info->pack=pack;
867}
868
869
870/*
871%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872% %
873% %
874% %
875% S e t Q u a n t u m P a d %
876% %
877% %
878% %
879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880%
881% SetQuantumPad() sets the quantum pad.
882%
883% The format of the SetQuantumPad method is:
884%
885% MagickBooleanType SetQuantumPad(const Image *image,
cristybb503372010-05-27 20:51:26 +0000886% QuantumInfo *quantum_info,const size_t pad)
cristy3ed852e2009-09-05 21:47:34 +0000887%
888% A description of each parameter follows:
889%
890% o image: the image.
891%
892% o quantum_info: the quantum info.
893%
894% o pad: the quantum pad.
895%
896*/
897MagickExport MagickBooleanType SetQuantumPad(const Image *image,
cristybb503372010-05-27 20:51:26 +0000898 QuantumInfo *quantum_info,const size_t pad)
cristy3ed852e2009-09-05 21:47:34 +0000899{
900 assert(image != (Image *) NULL);
901 assert(image->signature == MagickSignature);
902 if (image->debug != MagickFalse)
903 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
904 assert(quantum_info != (QuantumInfo *) NULL);
905 assert(quantum_info->signature == MagickSignature);
906 quantum_info->pad=pad;
907 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
908}
909
910/*
911%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
912% %
913% %
914% %
915% S e t Q u a n t u m M i n I s W h i t e %
916% %
917% %
918% %
919%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
920%
921% SetQuantumMinIsWhite() sets the quantum min-is-white flag.
922%
923% The format of the SetQuantumMinIsWhite method is:
924%
925% void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
926% const MagickBooleanType min_is_white)
927%
928% A description of each parameter follows:
929%
930% o quantum_info: the quantum info.
931%
932% o min_is_white: the min-is-white flag.
933%
934*/
935MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
936 const MagickBooleanType min_is_white)
937{
938 assert(quantum_info != (QuantumInfo *) NULL);
939 assert(quantum_info->signature == MagickSignature);
940 quantum_info->min_is_white=min_is_white;
941}
942
943/*
944%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
945% %
946% %
947% %
948% S e t Q u a n t u m Q u a n t u m %
949% %
950% %
951% %
952%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
953%
954% SetQuantumQuantum() sets the quantum quantum.
955%
956% The format of the SetQuantumQuantum method is:
957%
958% void SetQuantumQuantum(QuantumInfo *quantum_info,
cristybb503372010-05-27 20:51:26 +0000959% const size_t quantum)
cristy3ed852e2009-09-05 21:47:34 +0000960%
961% A description of each parameter follows:
962%
963% o quantum_info: the quantum info.
964%
965% o quantum: the quantum quantum.
966%
967*/
968MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
cristybb503372010-05-27 20:51:26 +0000969 const size_t quantum)
cristy3ed852e2009-09-05 21:47:34 +0000970{
971 assert(quantum_info != (QuantumInfo *) NULL);
972 assert(quantum_info->signature == MagickSignature);
973 quantum_info->quantum=quantum;
974}
975
976/*
977%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
978% %
979% %
980% %
981% S e t Q u a n t u m S c a l e %
982% %
983% %
984% %
985%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
986%
987% SetQuantumScale() sets the quantum scale.
988%
989% The format of the SetQuantumScale method is:
990%
991% void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
992%
993% A description of each parameter follows:
994%
995% o quantum_info: the quantum info.
996%
997% o scale: the quantum scale.
998%
999*/
1000MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1001{
1002 assert(quantum_info != (QuantumInfo *) NULL);
1003 assert(quantum_info->signature == MagickSignature);
1004 quantum_info->scale=scale;
1005}