blob: d77d120d84eb046cc618b247759940bf59ff1318 [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 %
15% John Cristy %
16% October 1998 %
17% %
18% %
19% Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization %
20% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% http://www.imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
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"
49#include "MagickCore/constitute.h"
50#include "MagickCore/delegate.h"
51#include "MagickCore/geometry.h"
52#include "MagickCore/list.h"
53#include "MagickCore/magick.h"
54#include "MagickCore/memory_.h"
55#include "MagickCore/monitor.h"
56#include "MagickCore/option.h"
57#include "MagickCore/pixel.h"
58#include "MagickCore/pixel-accessor.h"
59#include "MagickCore/property.h"
60#include "MagickCore/quantum.h"
61#include "MagickCore/quantum-private.h"
62#include "MagickCore/resource_.h"
63#include "MagickCore/semaphore.h"
64#include "MagickCore/statistic.h"
65#include "MagickCore/stream.h"
66#include "MagickCore/string_.h"
67#include "MagickCore/string-private.h"
68#include "MagickCore/thread-private.h"
69#include "MagickCore/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000070
71/*
72 Define declarations.
73*/
74#define QuantumSignature 0xab
75
76/*
77 Forward declarations.
78*/
79static void
80 DestroyQuantumPixels(QuantumInfo *);
81
82/*
83%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84% %
85% %
86% %
87% A c q u i r e Q u a n t u m I n f o %
88% %
89% %
90% %
91%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
92%
93% AcquireQuantumInfo() allocates the QuantumInfo structure.
94%
95% The format of the AcquireQuantumInfo method is:
96%
97% QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
98%
99% A description of each parameter follows:
100%
101% o image_info: the image info.
102%
103% o image: the image.
104%
105*/
106
cristy22c16d02012-11-03 19:53:37 +0000107static inline size_t MagickMax(const size_t x,const size_t y)
cristy3ed852e2009-09-05 21:47:34 +0000108{
109 if (x > y)
110 return(x);
111 return(y);
112}
113
114MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
115 Image *image)
116{
117 MagickBooleanType
118 status;
119
120 QuantumInfo
121 *quantum_info;
122
cristy73bd4a52010-10-05 11:24:23 +0000123 quantum_info=(QuantumInfo *) AcquireMagickMemory(sizeof(*quantum_info));
cristy3ed852e2009-09-05 21:47:34 +0000124 if (quantum_info == (QuantumInfo *) NULL)
125 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
126 quantum_info->signature=MagickSignature;
127 GetQuantumInfo(image_info,quantum_info);
128 if (image == (const Image *) NULL)
129 return(quantum_info);
130 status=SetQuantumDepth(image,quantum_info,image->depth);
131 if (status == MagickFalse)
132 quantum_info=DestroyQuantumInfo(quantum_info);
cristy15f006f2012-02-06 13:46:56 +0000133 quantum_info->endian=image->endian;
cristy3ed852e2009-09-05 21:47:34 +0000134 return(quantum_info);
135}
136
137/*
138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
139% %
140% %
141% %
142+ A c q u i r e Q u a n t u m P i x e l s %
143% %
144% %
145% %
146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
147%
148% AcquireQuantumPixels() allocates the unsigned char structure.
149%
150% The format of the AcquireQuantumPixels method is:
151%
152% MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
153% const size_t extent)
154%
155% A description of each parameter follows:
156%
157% o quantum_info: the quantum info.
158%
159% o extent: the quantum info.
160%
161*/
162static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
163 const size_t extent)
164{
cristybb503372010-05-27 20:51:26 +0000165 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000166 i;
167
168 assert(quantum_info != (QuantumInfo *) NULL);
169 assert(quantum_info->signature == MagickSignature);
cristy9357bdd2012-07-30 12:28:34 +0000170 quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
cristy3ed852e2009-09-05 21:47:34 +0000171 quantum_info->pixels=(unsigned char **) AcquireQuantumMemory(
172 quantum_info->number_threads,sizeof(*quantum_info->pixels));
173 if (quantum_info->pixels == (unsigned char **) NULL)
174 return(MagickFalse);
175 quantum_info->extent=extent;
cristy5c6cd592012-04-23 00:57:38 +0000176 (void) ResetMagickMemory(quantum_info->pixels,0,quantum_info->number_threads*
177 sizeof(*quantum_info->pixels));
cristybb503372010-05-27 20:51:26 +0000178 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
cristy3ed852e2009-09-05 21:47:34 +0000179 {
180 quantum_info->pixels[i]=(unsigned char *) AcquireQuantumMemory(extent+1,
181 sizeof(**quantum_info->pixels));
cristy84787932009-10-06 19:18:19 +0000182 if (quantum_info->pixels[i] == (unsigned char *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000183 return(MagickFalse);
184 (void) ResetMagickMemory(quantum_info->pixels[i],0,(extent+1)*
185 sizeof(**quantum_info->pixels));
186 quantum_info->pixels[i][extent]=QuantumSignature;
187 }
188 return(MagickTrue);
189}
190
191/*
192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193% %
194% %
195% %
196% D e s t r o y Q u a n t u m I n f o %
197% %
198% %
199% %
200%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201%
202% DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
203% structure.
204%
205% The format of the DestroyQuantumInfo method is:
206%
207% QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
208%
209% A description of each parameter follows:
210%
211% o quantum_info: the quantum info.
212%
213*/
214MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
215{
216 assert(quantum_info != (QuantumInfo *) NULL);
217 assert(quantum_info->signature == MagickSignature);
218 if (quantum_info->pixels != (unsigned char **) NULL)
219 DestroyQuantumPixels(quantum_info);
220 if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
221 DestroySemaphoreInfo(&quantum_info->semaphore);
222 quantum_info->signature=(~MagickSignature);
223 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
224 return(quantum_info);
225}
226
227/*
228%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229% %
230% %
231% %
232+ D e s t r o y Q u a n t u m P i x e l s %
233% %
234% %
235% %
236%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237%
238% DestroyQuantumPixels() destroys the quantum pixels.
239%
240% The format of the DestroyQuantumPixels() method is:
241%
242% void DestroyQuantumPixels(QuantumInfo *quantum_info)
243%
244% A description of each parameter follows:
245%
246% o quantum_info: the quantum info.
247%
248*/
249static void DestroyQuantumPixels(QuantumInfo *quantum_info)
250{
cristybb503372010-05-27 20:51:26 +0000251 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000252 i;
253
cristy4362aac2010-10-06 18:52:08 +0000254 ssize_t
255 extent;
256
cristy3ed852e2009-09-05 21:47:34 +0000257 assert(quantum_info != (QuantumInfo *) NULL);
258 assert(quantum_info->signature == MagickSignature);
259 assert(quantum_info->pixels != (unsigned char **) NULL);
cristy55a91cd2010-12-01 00:57:40 +0000260 extent=(ssize_t) quantum_info->extent;
cristybb503372010-05-27 20:51:26 +0000261 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
cristyed6b55a2010-10-06 02:15:05 +0000262 if (quantum_info->pixels[i] != (unsigned char *) NULL)
263 {
264 /*
265 Did we overrun our quantum buffer?
266 */
cristy4362aac2010-10-06 18:52:08 +0000267 assert(quantum_info->pixels[i][extent] == QuantumSignature);
cristyed6b55a2010-10-06 02:15:05 +0000268 quantum_info->pixels[i]=(unsigned char *) RelinquishMagickMemory(
269 quantum_info->pixels[i]);
270 }
cristy3ed852e2009-09-05 21:47:34 +0000271 quantum_info->pixels=(unsigned char **) RelinquishMagickMemory(
272 quantum_info->pixels);
273}
274
275/*
276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277% %
278% %
279% %
280% G e t Q u a n t u m E x t e n t %
281% %
282% %
283% %
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285%
286% GetQuantumExtent() returns the quantum pixel buffer extent.
287%
288% The format of the GetQuantumExtent method is:
289%
290% size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
291% const QuantumType quantum_type)
292%
293% A description of each parameter follows:
294%
295% o image: the image.
296%
297% o quantum_info: the quantum info.
298%
299% o quantum_type: Declare which pixel components to transfer (red, green,
300% blue, opacity, RGB, or RGBA).
301%
302*/
303MagickExport size_t GetQuantumExtent(const Image *image,
304 const QuantumInfo *quantum_info,const QuantumType quantum_type)
305{
306 size_t
307 packet_size;
308
309 assert(quantum_info != (QuantumInfo *) NULL);
310 assert(quantum_info->signature == MagickSignature);
311 packet_size=1;
312 switch (quantum_type)
313 {
314 case GrayAlphaQuantum: packet_size=2; break;
315 case IndexAlphaQuantum: packet_size=2; break;
316 case RGBQuantum: packet_size=3; break;
cristy1f9852b2010-09-04 15:05:36 +0000317 case BGRQuantum: packet_size=3; break;
cristy3ed852e2009-09-05 21:47:34 +0000318 case RGBAQuantum: packet_size=4; break;
319 case RGBOQuantum: packet_size=4; break;
cristy1f9852b2010-09-04 15:05:36 +0000320 case BGRAQuantum: packet_size=4; break;
cristy3ed852e2009-09-05 21:47:34 +0000321 case CMYKQuantum: packet_size=4; break;
322 case CMYKAQuantum: packet_size=5; break;
323 default: break;
324 }
325 if (quantum_info->pack == MagickFalse)
cristyc9672a92010-01-06 00:57:45 +0000326 return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
327 return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
cristy3ed852e2009-09-05 21:47:34 +0000328}
329
330/*
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% %
333% %
334% %
cristy9d4918b2012-11-14 20:18:32 +0000335% G e t Q u a n t u m E n d i a n %
336% %
337% %
338% %
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340%
341% GetQuantumEndian() returns the quantum endian of the image.
342%
343% The endian of the GetQuantumEndian method is:
344%
345% EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
346%
347% A description of each parameter follows:
348%
349% o quantum_info: the quantum info.
350%
351*/
352MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
353{
354 assert(quantum_info != (QuantumInfo *) NULL);
355 assert(quantum_info->signature == MagickSignature);
356 return(quantum_info->endian);
357}
358
359/*
360%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361% %
362% %
363% %
cristye11d00a2011-12-06 18:03:25 +0000364% G e t Q u a n t u m F o r m a t %
365% %
366% %
367% %
368%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369%
370% GetQuantumFormat() returns the quantum format of the image.
371%
372% The format of the GetQuantumFormat method is:
373%
374% QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
375%
376% A description of each parameter follows:
377%
378% o quantum_info: the quantum info.
379%
380*/
381MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
382{
383 assert(quantum_info != (QuantumInfo *) NULL);
384 assert(quantum_info->signature == MagickSignature);
385 return(quantum_info->format);
386}
387
388/*
389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
390% %
391% %
392% %
cristy3ed852e2009-09-05 21:47:34 +0000393% G e t Q u a n t u m I n f o %
394% %
395% %
396% %
397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
398%
399% GetQuantumInfo() initializes the QuantumInfo structure to default values.
400%
401% The format of the GetQuantumInfo method is:
402%
403% GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
404%
405% A description of each parameter follows:
406%
407% o image_info: the image info.
408%
409% o quantum_info: the quantum info.
410%
411*/
412MagickExport void GetQuantumInfo(const ImageInfo *image_info,
413 QuantumInfo *quantum_info)
414{
415 const char
416 *option;
417
418 assert(quantum_info != (QuantumInfo *) NULL);
419 (void) ResetMagickMemory(quantum_info,0,sizeof(*quantum_info));
420 quantum_info->quantum=8;
421 quantum_info->maximum=1.0;
422 quantum_info->scale=QuantumRange;
423 quantum_info->pack=MagickTrue;
424 quantum_info->semaphore=AllocateSemaphoreInfo();
425 quantum_info->signature=MagickSignature;
426 if (image_info == (const ImageInfo *) NULL)
427 return;
428 option=GetImageOption(image_info,"quantum:format");
429 if (option != (char *) NULL)
cristy042ee782011-04-22 18:48:30 +0000430 quantum_info->format=(QuantumFormatType) ParseCommandOption(
cristy3ed852e2009-09-05 21:47:34 +0000431 MagickQuantumFormatOptions,MagickFalse,option);
432 option=GetImageOption(image_info,"quantum:minimum");
433 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000434 quantum_info->minimum=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000435 option=GetImageOption(image_info,"quantum:maximum");
436 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000437 quantum_info->maximum=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000438 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
439 quantum_info->scale=0.0;
440 else
441 if (quantum_info->minimum == quantum_info->maximum)
442 {
cristya19f1d72012-08-07 18:24:38 +0000443 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
cristy3ed852e2009-09-05 21:47:34 +0000444 quantum_info->minimum=0.0;
445 }
446 else
cristya19f1d72012-08-07 18:24:38 +0000447 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
cristy3ed852e2009-09-05 21:47:34 +0000448 quantum_info->minimum);
449 option=GetImageOption(image_info,"quantum:scale");
450 if (option != (char *) NULL)
cristydbdd0e32011-11-04 23:29:40 +0000451 quantum_info->scale=StringToDouble(option,(char **) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000452 option=GetImageOption(image_info,"quantum:polarity");
453 if (option != (char *) NULL)
454 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
455 MagickTrue : MagickFalse;
cristy32c68432012-01-12 15:06:28 +0000456 quantum_info->endian=image_info->endian;
457 ResetQuantumState(quantum_info);
cristy3ed852e2009-09-05 21:47:34 +0000458}
459
460/*
461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
462% %
463% %
464% %
465% G e t Q u a n t u m P i x e l s %
466% %
467% %
468% %
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470%
471% GetQuantumPixels() returns the quantum pixels.
472%
473% The format of the GetQuantumPixels method is:
474%
475% unsigned char *QuantumPixels GetQuantumPixels(
476% const QuantumInfo *quantum_info)
477%
478% A description of each parameter follows:
479%
480% o image: the image.
481%
482*/
483MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
484{
cristy5c9e6f22010-09-17 17:31:01 +0000485 const int
486 id = GetOpenMPThreadId();
cristy3ed852e2009-09-05 21:47:34 +0000487
488 assert(quantum_info != (QuantumInfo *) NULL);
489 assert(quantum_info->signature == MagickSignature);
cristy3ed852e2009-09-05 21:47:34 +0000490 return(quantum_info->pixels[id]);
491}
492
493/*
494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
495% %
496% %
497% %
498% G e t Q u a n t u m T y p e %
499% %
500% %
501% %
502%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
503%
504% GetQuantumType() returns the quantum type of the image.
505%
506% The format of the GetQuantumType method is:
507%
508% QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
509%
510% A description of each parameter follows:
511%
512% o image: the image.
513%
514*/
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;
cristy8a46d822012-08-28 23:32:39 +0000525 if (image->alpha_trait == BlendPixelTrait)
cristy3ed852e2009-09-05 21:47:34 +0000526 quantum_type=RGBAQuantum;
527 if (image->colorspace == CMYKColorspace)
528 {
529 quantum_type=CMYKQuantum;
cristy8a46d822012-08-28 23:32:39 +0000530 if (image->alpha_trait == BlendPixelTrait)
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;
cristy8a46d822012-08-28 23:32:39 +0000536 if (image->alpha_trait == BlendPixelTrait)
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;
cristy8a46d822012-08-28 23:32:39 +0000542 if (image->alpha_trait == BlendPixelTrait)
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{
656 MagickBooleanType
657 status;
658
659 /*
660 Allocate the quantum pixel buffer.
661 */
662 assert(image != (Image *) NULL);
663 assert(image->signature == MagickSignature);
664 if (image->debug != MagickFalse)
665 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
666 assert(quantum_info != (QuantumInfo *) NULL);
667 assert(quantum_info->signature == MagickSignature);
668 quantum_info->depth=depth;
669 if (quantum_info->format == FloatingPointQuantumFormat)
670 {
671 if (quantum_info->depth > 32)
672 quantum_info->depth=64;
673 else
cristyc9672a92010-01-06 00:57:45 +0000674 if (quantum_info->depth > 16)
675 quantum_info->depth=32;
676 else
677 quantum_info->depth=16;
cristy3ed852e2009-09-05 21:47:34 +0000678 }
cristy3ed852e2009-09-05 21:47:34 +0000679 if (quantum_info->pixels != (unsigned char **) NULL)
680 DestroyQuantumPixels(quantum_info);
cristya3274322010-05-14 23:22:12 +0000681 status=AcquireQuantumPixels(quantum_info,(6+quantum_info->pad)*image->columns*
cristy2dfdad32010-05-15 14:15:35 +0000682 ((quantum_info->depth+7)/8)); /* allow for CMYKA + RLE byte + pad */
cristy3ed852e2009-09-05 21:47:34 +0000683 return(status);
684}
685
686/*
687%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
688% %
689% %
690% %
cristy9d4918b2012-11-14 20:18:32 +0000691% S e t Q u a n t u m E n d i a n %
692% %
693% %
694% %
695%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696%
697% SetQuantumEndian() sets the quantum endian.
698%
699% The endian of the SetQuantumEndian method is:
700%
701% MagickBooleanType SetQuantumEndian(const Image *image,
702% QuantumInfo *quantum_info,const EndianType endian)
703%
704% A description of each parameter follows:
705%
706% o image: the image.
707%
708% o quantum_info: the quantum info.
709%
710% o endian: the quantum endian.
711%
712*/
713MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
714 QuantumInfo *quantum_info,const EndianType endian)
715{
716 assert(image != (Image *) NULL);
717 assert(image->signature == MagickSignature);
718 if (image->debug != MagickFalse)
719 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
720 assert(quantum_info != (QuantumInfo *) NULL);
721 assert(quantum_info->signature == MagickSignature);
722 quantum_info->endian=endian;
723 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
724}
725
726/*
727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728% %
729% %
730% %
cristy3ed852e2009-09-05 21:47:34 +0000731% S e t Q u a n t u m F o r m a t %
732% %
733% %
734% %
735%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736%
737% SetQuantumFormat() sets the quantum format.
738%
739% The format of the SetQuantumFormat method is:
740%
741% MagickBooleanType SetQuantumFormat(const Image *image,
742% QuantumInfo *quantum_info,const QuantumFormatType format)
743%
744% A description of each parameter follows:
745%
746% o image: the image.
747%
748% o quantum_info: the quantum info.
749%
750% o format: the quantum format.
751%
752*/
753MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
754 QuantumInfo *quantum_info,const QuantumFormatType format)
755{
756 assert(image != (Image *) NULL);
757 assert(image->signature == MagickSignature);
758 if (image->debug != MagickFalse)
759 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
760 assert(quantum_info != (QuantumInfo *) NULL);
761 assert(quantum_info->signature == MagickSignature);
762 quantum_info->format=format;
763 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
764}
765
766/*
767%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768% %
769% %
770% %
771% S e t Q u a n t u m I m a g e T y p e %
772% %
773% %
774% %
775%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
776%
777% SetQuantumImageType() sets the image type based on the quantum type.
778%
779% The format of the SetQuantumImageType method is:
780%
781% void ImageType SetQuantumImageType(Image *image,
782% const QuantumType quantum_type)
783%
784% A description of each parameter follows:
785%
786% o image: the image.
787%
788% o quantum_type: Declare which pixel components to transfer (red, green,
789% blue, opacity, RGB, or RGBA).
790%
791*/
792MagickExport void SetQuantumImageType(Image *image,
793 const QuantumType quantum_type)
794{
795 assert(image != (Image *) NULL);
796 assert(image->signature == MagickSignature);
797 if (image->debug != MagickFalse)
798 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
799 switch (quantum_type)
800 {
801 case IndexQuantum:
802 case IndexAlphaQuantum:
803 {
804 image->type=PaletteType;
805 break;
806 }
807 case GrayQuantum:
808 case GrayAlphaQuantum:
809 {
810 image->type=GrayscaleType;
811 if (image->depth == 1)
812 image->type=BilevelType;
813 break;
814 }
815 case CyanQuantum:
816 case MagentaQuantum:
817 case YellowQuantum:
818 case BlackQuantum:
819 case CMYKQuantum:
820 case CMYKAQuantum:
821 {
822 image->type=ColorSeparationType;
823 break;
824 }
825 default:
826 {
827 image->type=TrueColorType;
828 break;
829 }
830 }
831}
832
833/*
834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835% %
836% %
837% %
838% S e t Q u a n t u m P a c k %
839% %
840% %
841% %
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843%
844% SetQuantumPack() sets the quantum pack flag.
845%
846% The format of the SetQuantumPack method is:
847%
848% void SetQuantumPack(QuantumInfo *quantum_info,
849% const MagickBooleanType pack)
850%
851% A description of each parameter follows:
852%
853% o quantum_info: the quantum info.
854%
855% o pack: the pack flag.
856%
857*/
858MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
859 const MagickBooleanType pack)
860{
861 assert(quantum_info != (QuantumInfo *) NULL);
862 assert(quantum_info->signature == MagickSignature);
863 quantum_info->pack=pack;
864}
865
866
867/*
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869% %
870% %
871% %
872% S e t Q u a n t u m P a d %
873% %
874% %
875% %
876%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
877%
878% SetQuantumPad() sets the quantum pad.
879%
880% The format of the SetQuantumPad method is:
881%
882% MagickBooleanType SetQuantumPad(const Image *image,
cristybb503372010-05-27 20:51:26 +0000883% QuantumInfo *quantum_info,const size_t pad)
cristy3ed852e2009-09-05 21:47:34 +0000884%
885% A description of each parameter follows:
886%
887% o image: the image.
888%
889% o quantum_info: the quantum info.
890%
891% o pad: the quantum pad.
892%
893*/
894MagickExport MagickBooleanType SetQuantumPad(const Image *image,
cristybb503372010-05-27 20:51:26 +0000895 QuantumInfo *quantum_info,const size_t pad)
cristy3ed852e2009-09-05 21:47:34 +0000896{
897 assert(image != (Image *) NULL);
898 assert(image->signature == MagickSignature);
899 if (image->debug != MagickFalse)
900 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
901 assert(quantum_info != (QuantumInfo *) NULL);
902 assert(quantum_info->signature == MagickSignature);
903 quantum_info->pad=pad;
904 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
905}
906
907/*
908%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
909% %
910% %
911% %
912% S e t Q u a n t u m M i n I s W h i t e %
913% %
914% %
915% %
916%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
917%
918% SetQuantumMinIsWhite() sets the quantum min-is-white flag.
919%
920% The format of the SetQuantumMinIsWhite method is:
921%
922% void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
923% const MagickBooleanType min_is_white)
924%
925% A description of each parameter follows:
926%
927% o quantum_info: the quantum info.
928%
929% o min_is_white: the min-is-white flag.
930%
931*/
932MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
933 const MagickBooleanType min_is_white)
934{
935 assert(quantum_info != (QuantumInfo *) NULL);
936 assert(quantum_info->signature == MagickSignature);
937 quantum_info->min_is_white=min_is_white;
938}
939
940/*
941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942% %
943% %
944% %
945% S e t Q u a n t u m Q u a n t u m %
946% %
947% %
948% %
949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950%
951% SetQuantumQuantum() sets the quantum quantum.
952%
953% The format of the SetQuantumQuantum method is:
954%
955% void SetQuantumQuantum(QuantumInfo *quantum_info,
cristybb503372010-05-27 20:51:26 +0000956% const size_t quantum)
cristy3ed852e2009-09-05 21:47:34 +0000957%
958% A description of each parameter follows:
959%
960% o quantum_info: the quantum info.
961%
962% o quantum: the quantum quantum.
963%
964*/
965MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
cristybb503372010-05-27 20:51:26 +0000966 const size_t quantum)
cristy3ed852e2009-09-05 21:47:34 +0000967{
968 assert(quantum_info != (QuantumInfo *) NULL);
969 assert(quantum_info->signature == MagickSignature);
970 quantum_info->quantum=quantum;
971}
972
973/*
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975% %
976% %
977% %
978% S e t Q u a n t u m S c a l e %
979% %
980% %
981% %
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983%
984% SetQuantumScale() sets the quantum scale.
985%
986% The format of the SetQuantumScale method is:
987%
988% void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
989%
990% A description of each parameter follows:
991%
992% o quantum_info: the quantum info.
993%
994% o scale: the quantum scale.
995%
996*/
997MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
998{
999 assert(quantum_info != (QuantumInfo *) NULL);
1000 assert(quantum_info->signature == MagickSignature);
1001 quantum_info->scale=scale;
1002}