MagickCore 7.1.1
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
quantum.c
1/*
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% Cristy %
16% October 1998 %
17% %
18% %
19% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
20% dedicated to making software imaging solutions freely available. %
21% %
22% You may not use this file except in compliance with the License. You may %
23% obtain a copy of the License at %
24% %
25% https://imagemagick.org/script/license.php %
26% %
27% Unless required by applicable law or agreed to in writing, software %
28% distributed under the License is distributed on an "AS IS" BASIS, %
29% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30% See the License for the specific language governing permissions and %
31% limitations under the License. %
32% %
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34%
35%
36*/
37
38/*
39 Include declarations.
40*/
41#include "MagickCore/studio.h"
42#include "MagickCore/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/cache-private.h"
50#include "MagickCore/colorspace.h"
51#include "MagickCore/colorspace-private.h"
52#include "MagickCore/constitute.h"
53#include "MagickCore/delegate.h"
54#include "MagickCore/geometry.h"
55#include "MagickCore/list.h"
56#include "MagickCore/magick.h"
57#include "MagickCore/memory_.h"
58#include "MagickCore/memory-private.h"
59#include "MagickCore/monitor.h"
60#include "MagickCore/option.h"
61#include "MagickCore/pixel.h"
62#include "MagickCore/pixel-accessor.h"
63#include "MagickCore/property.h"
64#include "MagickCore/quantum.h"
65#include "MagickCore/quantum-private.h"
66#include "MagickCore/resource_.h"
67#include "MagickCore/semaphore.h"
68#include "MagickCore/statistic.h"
69#include "MagickCore/stream.h"
70#include "MagickCore/string_.h"
71#include "MagickCore/string-private.h"
72#include "MagickCore/thread-private.h"
73#include "MagickCore/utility.h"
74
75/*
76 Define declarations.
77*/
78#define QuantumSignature 0xab
79
80/*
81 Forward declarations.
82*/
83static void
84 DestroyQuantumPixels(QuantumInfo *);
85
86/*
87%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88% %
89% %
90% %
91% A c q u i r e Q u a n t u m I n f o %
92% %
93% %
94% %
95%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96%
97% AcquireQuantumInfo() allocates the QuantumInfo structure.
98%
99% The format of the AcquireQuantumInfo method is:
100%
101% QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
102%
103% A description of each parameter follows:
104%
105% o image_info: the image info.
106%
107% o image: the image.
108%
109*/
110MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
111 Image *image)
112{
113 MagickBooleanType
114 status;
115
117 *quantum_info;
118
119 quantum_info=(QuantumInfo *) AcquireCriticalMemory(sizeof(*quantum_info));
120 quantum_info->signature=MagickCoreSignature;
121 GetQuantumInfo(image_info,quantum_info);
122 if (image == (const Image *) NULL)
123 return(quantum_info);
124 status=SetQuantumDepth(image,quantum_info,image->depth);
125 quantum_info->endian=image->endian;
126 if (status == MagickFalse)
127 quantum_info=DestroyQuantumInfo(quantum_info);
128 return(quantum_info);
129}
130
131/*
132%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133% %
134% %
135% %
136+ A c q u i r e Q u a n t u m P i x e l s %
137% %
138% %
139% %
140%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141%
142% AcquireQuantumPixels() allocates the pixel staging areas.
143%
144% The format of the AcquireQuantumPixels method is:
145%
146% MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
147% const size_t extent)
148%
149% A description of each parameter follows:
150%
151% o quantum_info: the quantum info.
152%
153% o extent: the quantum info.
154%
155*/
156static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
157 const size_t extent)
158{
159 ssize_t
160 i;
161
162 assert(quantum_info != (QuantumInfo *) NULL);
163 assert(quantum_info->signature == MagickCoreSignature);
164 quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
165 quantum_info->pixels=(MemoryInfo **) AcquireQuantumMemory(
166 quantum_info->number_threads,sizeof(*quantum_info->pixels));
167 if (quantum_info->pixels == (MemoryInfo **) NULL)
168 return(MagickFalse);
169 quantum_info->extent=extent;
170 (void) memset(quantum_info->pixels,0,quantum_info->number_threads*
171 sizeof(*quantum_info->pixels));
172 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
173 {
174 unsigned char
175 *pixels;
176
177 quantum_info->pixels[i]=AcquireVirtualMemory(extent+1,sizeof(*pixels));
178 if (quantum_info->pixels[i] == (MemoryInfo *) NULL)
179 {
180 DestroyQuantumPixels(quantum_info);
181 return(MagickFalse);
182 }
183 pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
184 (void) memset(pixels,0,(extent+1)*sizeof(*pixels));
185 pixels[extent]=QuantumSignature;
186 }
187 return(MagickTrue);
188}
189
190/*
191%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192% %
193% %
194% %
195% D e s t r o y Q u a n t u m I n f o %
196% %
197% %
198% %
199%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200%
201% DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
202% structure.
203%
204% The format of the DestroyQuantumInfo method is:
205%
206% QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
207%
208% A description of each parameter follows:
209%
210% o quantum_info: the quantum info.
211%
212*/
213MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
214{
215 assert(quantum_info != (QuantumInfo *) NULL);
216 assert(quantum_info->signature == MagickCoreSignature);
217 if (quantum_info->pixels != (MemoryInfo **) NULL)
218 DestroyQuantumPixels(quantum_info);
219 if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
220 RelinquishSemaphoreInfo(&quantum_info->semaphore);
221 quantum_info->signature=(~MagickCoreSignature);
222 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
223 return(quantum_info);
224}
225
226/*
227%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228% %
229% %
230% %
231+ D e s t r o y Q u a n t u m P i x e l s %
232% %
233% %
234% %
235%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236%
237% DestroyQuantumPixels() destroys the quantum pixels.
238%
239% The format of the DestroyQuantumPixels() method is:
240%
241% void DestroyQuantumPixels(QuantumInfo *quantum_info)
242%
243% A description of each parameter follows:
244%
245% o quantum_info: the quantum info.
246%
247*/
248static void DestroyQuantumPixels(QuantumInfo *quantum_info)
249{
250 ssize_t
251 i;
252
253 assert(quantum_info != (QuantumInfo *) NULL);
254 assert(quantum_info->signature == MagickCoreSignature);
255 assert(quantum_info->pixels != (MemoryInfo **) NULL);
256 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
257 if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
258 {
259#ifndef NDEBUG
260 ssize_t
261 extent;
262
263 unsigned char
264 *pixels;
265
266 /*
267 Did we overrun our quantum buffer?
268 */
269 extent=(ssize_t) quantum_info->extent;
270 pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
271 assert(pixels[extent] == QuantumSignature);
272#endif
273 quantum_info->pixels[i]=RelinquishVirtualMemory(
274 quantum_info->pixels[i]);
275 }
276 quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
277 quantum_info->pixels);
278}
279
280/*
281%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282% %
283% %
284% %
285% G e t Q u a n t u m E x t e n t %
286% %
287% %
288% %
289%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290%
291% GetQuantumExtent() returns the quantum pixel buffer extent.
292%
293% The format of the GetQuantumExtent method is:
294%
295% size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
296% const QuantumType quantum_type)
297%
298% A description of each parameter follows:
299%
300% o image: the image.
301%
302% o quantum_info: the quantum info.
303%
304% o quantum_type: Declare which pixel components to transfer (red, green,
305% blue, opacity, RGB, or RGBA).
306%
307*/
308MagickExport size_t GetQuantumExtent(const Image *image,
309 const QuantumInfo *quantum_info,const QuantumType quantum_type)
310{
311 size_t
312 channels;
313
314 assert(quantum_info != (QuantumInfo *) NULL);
315 assert(quantum_info->signature == MagickCoreSignature);
316 channels=1;
317 switch (quantum_type)
318 {
319 case GrayAlphaQuantum: channels=2; break;
320 case IndexAlphaQuantum: channels=2; break;
321 case RGBQuantum: channels=3; break;
322 case BGRQuantum: channels=3; break;
323 case RGBAQuantum: channels=4; break;
324 case RGBOQuantum: channels=4; break;
325 case BGRAQuantum: channels=4; break;
326 case CMYKQuantum: channels=4; break;
327 case CMYKAQuantum: channels=5; break;
328 case MultispectralQuantum: channels=GetImageChannels(image); break;
329 case CbYCrAQuantum: channels=4; break;
330 case CbYCrQuantum: channels=3; break;
331 case CbYCrYQuantum: channels=4; break;
332 default: break;
333 }
334 if (quantum_info->pack == MagickFalse)
335 return((size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
336 (quantum_info->pad*image->columns));
337 return((size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
338 (quantum_info->pad*image->columns));
339}
340
341/*
342%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343% %
344% %
345% %
346% G e t Q u a n t u m E n d i a n %
347% %
348% %
349% %
350%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351%
352% GetQuantumEndian() returns the quantum endian of the image.
353%
354% The endian of the GetQuantumEndian method is:
355%
356% EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
357%
358% A description of each parameter follows:
359%
360% o quantum_info: the quantum info.
361%
362*/
363MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
364{
365 assert(quantum_info != (QuantumInfo *) NULL);
366 assert(quantum_info->signature == MagickCoreSignature);
367 return(quantum_info->endian);
368}
369
370/*
371%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372% %
373% %
374% %
375% G e t Q u a n t u m F o r m a t %
376% %
377% %
378% %
379%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380%
381% GetQuantumFormat() returns the quantum format of the image.
382%
383% The format of the GetQuantumFormat method is:
384%
385% QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
386%
387% A description of each parameter follows:
388%
389% o quantum_info: the quantum info.
390%
391*/
392MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
393{
394 assert(quantum_info != (QuantumInfo *) NULL);
395 assert(quantum_info->signature == MagickCoreSignature);
396 return(quantum_info->format);
397}
398
399/*
400%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401% %
402% %
403% %
404% G e t Q u a n t u m I n f o %
405% %
406% %
407% %
408%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409%
410% GetQuantumInfo() initializes the QuantumInfo structure to default values.
411%
412% The format of the GetQuantumInfo method is:
413%
414% GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
415%
416% A description of each parameter follows:
417%
418% o image_info: the image info.
419%
420% o quantum_info: the quantum info.
421%
422*/
423MagickExport void GetQuantumInfo(const ImageInfo *image_info,
424 QuantumInfo *quantum_info)
425{
426 const char
427 *option;
428
429 assert(quantum_info != (QuantumInfo *) NULL);
430 (void) memset(quantum_info,0,sizeof(*quantum_info));
431 quantum_info->quantum=8;
432 quantum_info->maximum=1.0;
433 quantum_info->scale=QuantumRange;
434 quantum_info->pack=MagickTrue;
435 quantum_info->semaphore=AcquireSemaphoreInfo();
436 quantum_info->signature=MagickCoreSignature;
437 if (image_info == (const ImageInfo *) NULL)
438 return;
439 option=GetImageOption(image_info,"quantum:format");
440 if (option != (char *) NULL)
441 quantum_info->format=(QuantumFormatType) ParseCommandOption(
442 MagickQuantumFormatOptions,MagickFalse,option);
443 option=GetImageOption(image_info,"quantum:minimum");
444 if (option != (char *) NULL)
445 quantum_info->minimum=StringToDouble(option,(char **) NULL);
446 option=GetImageOption(image_info,"quantum:maximum");
447 if (option != (char *) NULL)
448 quantum_info->maximum=StringToDouble(option,(char **) NULL);
449 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
450 quantum_info->scale=0.0;
451 else
452 if (quantum_info->minimum == quantum_info->maximum)
453 {
454 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
455 quantum_info->minimum=0.0;
456 }
457 else
458 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
459 quantum_info->minimum);
460 option=GetImageOption(image_info,"quantum:scale");
461 if (option != (char *) NULL)
462 quantum_info->scale=StringToDouble(option,(char **) NULL);
463 option=GetImageOption(image_info,"quantum:polarity");
464 if (option != (char *) NULL)
465 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
466 MagickTrue : MagickFalse;
467 quantum_info->endian=image_info->endian;
468 ResetQuantumState(quantum_info);
469}
470
471/*
472%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473% %
474% %
475% %
476% G e t Q u a n t u m P i x e l s %
477% %
478% %
479% %
480%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481%
482% GetQuantumPixels() returns the quantum pixels.
483%
484% The format of the GetQuantumPixels method is:
485%
486% unsigned char *QuantumPixels GetQuantumPixels(
487% const QuantumInfo *quantum_info)
488%
489% A description of each parameter follows:
490%
491% o image: the image.
492%
493*/
494MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
495{
496 const int
497 id = GetOpenMPThreadId();
498
499 assert(quantum_info != (QuantumInfo *) NULL);
500 assert(quantum_info->signature == MagickCoreSignature);
501 return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
502}
503
504/*
505%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506% %
507% %
508% %
509% G e t Q u a n t u m T y p e %
510% %
511% %
512% %
513%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514%
515% GetQuantumType() returns the quantum type of the image.
516%
517% The format of the GetQuantumType method is:
518%
519% QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
520%
521% A description of each parameter follows:
522%
523% o image: the image.
524%
525% o exception: return any errors or warnings in this structure.
526%
527*/
528MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
529{
530 QuantumType
531 quantum_type;
532
533 assert(image != (Image *) NULL);
534 assert(image->signature == MagickCoreSignature);
535 if (IsEventLogging() != MagickFalse)
536 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
537 (void) exception;
538 quantum_type=RGBQuantum;
539 if (image->alpha_trait != UndefinedPixelTrait)
540 quantum_type=RGBAQuantum;
541 if (image->colorspace == CMYKColorspace)
542 {
543 quantum_type=CMYKQuantum;
544 if (image->alpha_trait != UndefinedPixelTrait)
545 quantum_type=CMYKAQuantum;
546 }
547 if (IsGrayColorspace(image->colorspace) != MagickFalse)
548 {
549 quantum_type=GrayQuantum;
550 if (image->alpha_trait != UndefinedPixelTrait)
551 quantum_type=GrayAlphaQuantum;
552 }
553 if (image->storage_class == PseudoClass)
554 {
555 quantum_type=IndexQuantum;
556 if (image->alpha_trait != UndefinedPixelTrait)
557 quantum_type=IndexAlphaQuantum;
558 }
559 if (image->number_meta_channels != 0)
560 quantum_type=MultispectralQuantum;
561 return(quantum_type);
562}
563
564/*
565%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
566% %
567% %
568% %
569+ R e s e t Q u a n t u m S t a t e %
570% %
571% %
572% %
573%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574%
575% ResetQuantumState() resets the quantum state.
576%
577% The format of the ResetQuantumState method is:
578%
579% void ResetQuantumState(QuantumInfo *quantum_info)
580%
581% A description of each parameter follows:
582%
583% o quantum_info: the quantum info.
584%
585*/
586MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
587{
588 static const unsigned int mask[32] =
589 {
590 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
591 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
592 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
593 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
594 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
595 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
596 0x3fffffffU, 0x7fffffffU
597 };
598
599 assert(quantum_info != (QuantumInfo *) NULL);
600 assert(quantum_info->signature == MagickCoreSignature);
601 quantum_info->state.inverse_scale=1.0;
602 if (fabs(quantum_info->scale) >= MagickEpsilon)
603 quantum_info->state.inverse_scale/=quantum_info->scale;
604 quantum_info->state.pixel=0U;
605 quantum_info->state.bits=0U;
606 quantum_info->state.mask=mask;
607}
608
609/*
610%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611% %
612% %
613% %
614% S e t Q u a n t u m F o r m a t %
615% %
616% %
617% %
618%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619%
620% SetQuantumAlphaType() sets the quantum format.
621%
622% The format of the SetQuantumAlphaType method is:
623%
624% void SetQuantumAlphaType(QuantumInfo *quantum_info,
625% const QuantumAlphaType type)
626%
627% A description of each parameter follows:
628%
629% o quantum_info: the quantum info.
630%
631% o type: the alpha type (e.g. associate).
632%
633*/
634MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
635 const QuantumAlphaType type)
636{
637 assert(quantum_info != (QuantumInfo *) NULL);
638 assert(quantum_info->signature == MagickCoreSignature);
639 quantum_info->alpha_type=type;
640}
641
642/*
643%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644% %
645% %
646% %
647% S e t Q u a n t u m D e p t h %
648% %
649% %
650% %
651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652%
653% SetQuantumDepth() sets the quantum depth.
654%
655% The format of the SetQuantumDepth method is:
656%
657% MagickBooleanType SetQuantumDepth(const Image *image,
658% QuantumInfo *quantum_info,const size_t depth)
659%
660% A description of each parameter follows:
661%
662% o image: the image.
663%
664% o quantum_info: the quantum info.
665%
666% o depth: the quantum depth.
667%
668*/
669MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
670 QuantumInfo *quantum_info,const size_t depth)
671{
672 size_t
673 extent,
674 quantum;
675
676 /*
677 Allocate the quantum pixel buffer.
678 */
679 assert(image != (Image *) NULL);
680 assert(image->signature == MagickCoreSignature);
681 assert(quantum_info != (QuantumInfo *) NULL);
682 assert(quantum_info->signature == MagickCoreSignature);
683 if (IsEventLogging() != MagickFalse)
684 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
685 quantum_info->depth=MagickMin(depth,64);
686 if (quantum_info->format == FloatingPointQuantumFormat)
687 {
688 if (quantum_info->depth > 32)
689 quantum_info->depth=64;
690 else
691 if (quantum_info->depth > 24)
692 quantum_info->depth=32;
693 else
694 if (quantum_info->depth > 16)
695 quantum_info->depth=24;
696 else
697 quantum_info->depth=16;
698 }
699 /*
700 Speculative allocation since we don't yet know the quantum type.
701 */
702 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
703 ((quantum_info->depth+7)/8)*sizeof(double);
704 extent=MagickMax(image->columns,image->rows)*quantum;
705 if ((MagickMax(image->columns,image->rows) != 0) &&
706 (quantum != (extent/MagickMax(image->columns,image->rows))))
707 return(MagickFalse);
708 if (quantum_info->pixels != (MemoryInfo **) NULL)
709 {
710 if (extent <= quantum_info->extent)
711 return(MagickTrue);
712 DestroyQuantumPixels(quantum_info);
713 }
714 return(AcquireQuantumPixels(quantum_info,extent));
715}
716
717/*
718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719% %
720% %
721% %
722% S e t Q u a n t u m E n d i a n %
723% %
724% %
725% %
726%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727%
728% SetQuantumEndian() sets the quantum endian.
729%
730% The endian of the SetQuantumEndian method is:
731%
732% MagickBooleanType SetQuantumEndian(const Image *image,
733% QuantumInfo *quantum_info,const EndianType endian)
734%
735% A description of each parameter follows:
736%
737% o image: the image.
738%
739% o quantum_info: the quantum info.
740%
741% o endian: the quantum endian.
742%
743*/
744MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
745 QuantumInfo *quantum_info,const EndianType endian)
746{
747 assert(image != (Image *) NULL);
748 assert(image->signature == MagickCoreSignature);
749 assert(quantum_info != (QuantumInfo *) NULL);
750 assert(quantum_info->signature == MagickCoreSignature);
751 if (IsEventLogging() != MagickFalse)
752 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
753 quantum_info->endian=endian;
754 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
755}
756
757/*
758%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759% %
760% %
761% %
762% S e t Q u a n t u m F o r m a t %
763% %
764% %
765% %
766%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767%
768% SetQuantumFormat() sets the quantum format.
769%
770% The format of the SetQuantumFormat method is:
771%
772% MagickBooleanType SetQuantumFormat(const Image *image,
773% QuantumInfo *quantum_info,const QuantumFormatType format)
774%
775% A description of each parameter follows:
776%
777% o image: the image.
778%
779% o quantum_info: the quantum info.
780%
781% o format: the quantum format.
782%
783*/
784MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
785 QuantumInfo *quantum_info,const QuantumFormatType format)
786{
787 assert(image != (Image *) NULL);
788 assert(image->signature == MagickCoreSignature);
789 assert(quantum_info != (QuantumInfo *) NULL);
790 assert(quantum_info->signature == MagickCoreSignature);
791 if (IsEventLogging() != MagickFalse)
792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
793 quantum_info->format=format;
794 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
795}
796
797/*
798%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799% %
800% %
801% %
802% S e t Q u a n t u m I m a g e T y p e %
803% %
804% %
805% %
806%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807%
808% SetQuantumImageType() sets the image type based on the quantum type.
809%
810% The format of the SetQuantumImageType method is:
811%
812% void ImageType SetQuantumImageType(Image *image,
813% const QuantumType quantum_type)
814%
815% A description of each parameter follows:
816%
817% o image: the image.
818%
819% o quantum_type: Declare which pixel components to transfer (red, green,
820% blue, opacity, RGB, or RGBA).
821%
822*/
823MagickExport void SetQuantumImageType(Image *image,
824 const QuantumType quantum_type)
825{
826 assert(image != (Image *) NULL);
827 assert(image->signature == MagickCoreSignature);
828 if (IsEventLogging() != MagickFalse)
829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
830 switch (quantum_type)
831 {
832 case IndexQuantum:
833 case IndexAlphaQuantum:
834 {
835 image->type=PaletteType;
836 break;
837 }
838 case GrayQuantum:
839 case GrayAlphaQuantum:
840 {
841 image->type=GrayscaleType;
842 if (image->depth == 1)
843 image->type=BilevelType;
844 break;
845 }
846 case CyanQuantum:
847 case MagentaQuantum:
848 case YellowQuantum:
849 case BlackQuantum:
850 case CMYKQuantum:
851 case CMYKAQuantum:
852 case MultispectralQuantum:
853 {
854 image->type=ColorSeparationType;
855 break;
856 }
857 default:
858 {
859 image->type=TrueColorType;
860 break;
861 }
862 }
863}
864
865/*
866%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867% %
868% %
869% %
870% S e t Q u a n t u m P a c k %
871% %
872% %
873% %
874%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875%
876% SetQuantumPack() sets the quantum pack flag.
877%
878% The format of the SetQuantumPack method is:
879%
880% void SetQuantumPack(QuantumInfo *quantum_info,
881% const MagickBooleanType pack)
882%
883% A description of each parameter follows:
884%
885% o quantum_info: the quantum info.
886%
887% o pack: the pack flag.
888%
889*/
890MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
891 const MagickBooleanType pack)
892{
893 assert(quantum_info != (QuantumInfo *) NULL);
894 assert(quantum_info->signature == MagickCoreSignature);
895 quantum_info->pack=pack;
896}
897
898/*
899%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900% %
901% %
902% %
903% S e t Q u a n t u m P a d %
904% %
905% %
906% %
907%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908%
909% SetQuantumPad() sets the quantum pad.
910%
911% The format of the SetQuantumPad method is:
912%
913% MagickBooleanType SetQuantumPad(const Image *image,
914% QuantumInfo *quantum_info,const size_t pad)
915%
916% A description of each parameter follows:
917%
918% o image: the image.
919%
920% o quantum_info: the quantum info.
921%
922% o pad: the quantum pad.
923%
924*/
925MagickExport MagickBooleanType SetQuantumPad(const Image *image,
926 QuantumInfo *quantum_info,const size_t pad)
927{
928 assert(image != (Image *) NULL);
929 assert(image->signature == MagickCoreSignature);
930 assert(quantum_info != (QuantumInfo *) NULL);
931 assert(quantum_info->signature == MagickCoreSignature);
932 if (IsEventLogging() != MagickFalse)
933 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
934 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
935 return(MagickFalse);
936 quantum_info->pad=pad;
937 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
938}
939
940/*
941%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942% %
943% %
944% %
945% S e t Q u a n t u m M i n I s W h i t e %
946% %
947% %
948% %
949%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950%
951% SetQuantumMinIsWhite() sets the quantum min-is-white flag.
952%
953% The format of the SetQuantumMinIsWhite method is:
954%
955% void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
956% const MagickBooleanType min_is_white)
957%
958% A description of each parameter follows:
959%
960% o quantum_info: the quantum info.
961%
962% o min_is_white: the min-is-white flag.
963%
964*/
965MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
966 const MagickBooleanType min_is_white)
967{
968 assert(quantum_info != (QuantumInfo *) NULL);
969 assert(quantum_info->signature == MagickCoreSignature);
970 quantum_info->min_is_white=min_is_white;
971}
972
973/*
974%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975% %
976% %
977% %
978% S e t Q u a n t u m Q u a n t u m %
979% %
980% %
981% %
982%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983%
984% SetQuantumQuantum() sets the quantum quantum.
985%
986% The format of the SetQuantumQuantum method is:
987%
988% void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
989%
990% A description of each parameter follows:
991%
992% o quantum_info: the quantum info.
993%
994% o quantum: the quantum quantum.
995%
996*/
997MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
998 const size_t quantum)
999{
1000 assert(quantum_info != (QuantumInfo *) NULL);
1001 assert(quantum_info->signature == MagickCoreSignature);
1002 quantum_info->quantum=quantum;
1003}
1004
1005/*
1006%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1007% %
1008% %
1009% %
1010% S e t Q u a n t u m S c a l e %
1011% %
1012% %
1013% %
1014%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015%
1016% SetQuantumScale() sets the quantum scale.
1017%
1018% The format of the SetQuantumScale method is:
1019%
1020% void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1021%
1022% A description of each parameter follows:
1023%
1024% o quantum_info: the quantum info.
1025%
1026% o scale: the quantum scale.
1027%
1028*/
1029MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1030{
1031 assert(quantum_info != (QuantumInfo *) NULL);
1032 assert(quantum_info->signature == MagickCoreSignature);
1033 quantum_info->scale=scale;
1034}