MagickCore 7.1.2-35
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/license/ %
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
116 QuantumInfo
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 BGROQuantum: channels=4; break;
327 case CMYKQuantum: channels=4; break;
328 case CMYKAQuantum: channels=5; break;
329 case MultispectralQuantum: channels=GetImageChannels(image); break;
330 case CbYCrAQuantum: channels=4; break;
331 case CbYCrQuantum: channels=3; break;
332 case CbYCrYQuantum: channels=4; break;
333 default: break;
334 }
335 if (quantum_info->pack == MagickFalse)
336 return((size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
337 (quantum_info->pad*image->columns));
338 return((size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
339 (quantum_info->pad*image->columns));
340}
341␌
342/*
343%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
344% %
345% %
346% %
347% G e t Q u a n t u m E n d i a n %
348% %
349% %
350% %
351%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
352%
353% GetQuantumEndian() returns the quantum endian of the image.
354%
355% The endian of the GetQuantumEndian method is:
356%
357% EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
358%
359% A description of each parameter follows:
360%
361% o quantum_info: the quantum info.
362%
363*/
364MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
365{
366 assert(quantum_info != (QuantumInfo *) NULL);
367 assert(quantum_info->signature == MagickCoreSignature);
368 return(quantum_info->endian);
369}
370␌
371/*
372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373% %
374% %
375% %
376% G e t Q u a n t u m F o r m a t %
377% %
378% %
379% %
380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381%
382% GetQuantumFormat() returns the quantum format of the image.
383%
384% The format of the GetQuantumFormat method is:
385%
386% QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
387%
388% A description of each parameter follows:
389%
390% o quantum_info: the quantum info.
391%
392*/
393MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
394{
395 assert(quantum_info != (QuantumInfo *) NULL);
396 assert(quantum_info->signature == MagickCoreSignature);
397 return(quantum_info->format);
398}
399␌
400/*
401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402% %
403% %
404% %
405% G e t Q u a n t u m I n f o %
406% %
407% %
408% %
409%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410%
411% GetQuantumInfo() initializes the QuantumInfo structure to default values.
412%
413% The format of the GetQuantumInfo method is:
414%
415% GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
416%
417% A description of each parameter follows:
418%
419% o image_info: the image info.
420%
421% o quantum_info: the quantum info.
422%
423*/
424MagickExport void GetQuantumInfo(const ImageInfo *image_info,
425 QuantumInfo *quantum_info)
426{
427 const char
428 *option;
429
430 assert(quantum_info != (QuantumInfo *) NULL);
431 (void) memset(quantum_info,0,sizeof(*quantum_info));
432 quantum_info->quantum=8;
433 quantum_info->maximum=1.0;
434 quantum_info->scale=QuantumRange;
435 quantum_info->pack=MagickTrue;
436 quantum_info->semaphore=AcquireSemaphoreInfo();
437 quantum_info->signature=MagickCoreSignature;
438 if (image_info == (const ImageInfo *) NULL)
439 return;
440 option=GetImageOption(image_info,"quantum:format");
441 if (option != (char *) NULL)
442 quantum_info->format=(QuantumFormatType) ParseCommandOption(
443 MagickQuantumFormatOptions,MagickFalse,option);
444 option=GetImageOption(image_info,"quantum:minimum");
445 if (option != (char *) NULL)
446 quantum_info->minimum=StringToDouble(option,(char **) NULL);
447 option=GetImageOption(image_info,"quantum:maximum");
448 if (option != (char *) NULL)
449 quantum_info->maximum=StringToDouble(option,(char **) NULL);
450 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
451 quantum_info->scale=0.0;
452 else
453 if (quantum_info->minimum == quantum_info->maximum)
454 {
455 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
456 quantum_info->minimum=0.0;
457 }
458 else
459 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
460 quantum_info->minimum);
461 option=GetImageOption(image_info,"quantum:scale");
462 if (option != (char *) NULL)
463 quantum_info->scale=StringToDouble(option,(char **) NULL);
464 option=GetImageOption(image_info,"quantum:polarity");
465 if (option != (char *) NULL)
466 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
467 MagickTrue : MagickFalse;
468 quantum_info->endian=image_info->endian;
469 ResetQuantumState(quantum_info);
470}
471␌
472/*
473%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
474% %
475% %
476% %
477% G e t Q u a n t u m P i x e l s %
478% %
479% %
480% %
481%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482%
483% GetQuantumPixels() returns the quantum pixels.
484%
485% The format of the GetQuantumPixels method is:
486%
487% unsigned char *QuantumPixels GetQuantumPixels(
488% const QuantumInfo *quantum_info)
489%
490% A description of each parameter follows:
491%
492% o image: the image.
493%
494*/
495MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
496{
497 const int
498 id = GetOpenMPThreadId();
499
500 assert(quantum_info != (QuantumInfo *) NULL);
501 assert(quantum_info->signature == MagickCoreSignature);
502 return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
503}
504␌
505/*
506%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
507% %
508% %
509% %
510% G e t Q u a n t u m T y p e %
511% %
512% %
513% %
514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515%
516% GetQuantumType() returns the quantum type of the image.
517%
518% The format of the GetQuantumType method is:
519%
520% QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
521%
522% A description of each parameter follows:
523%
524% o image: the image.
525%
526% o exception: return any errors or warnings in this structure.
527%
528*/
529MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
530{
531 QuantumType
532 quantum_type;
533
534 assert(image != (Image *) NULL);
535 assert(image->signature == MagickCoreSignature);
536 if (IsEventLogging() != MagickFalse)
537 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
538 (void) exception;
539 quantum_type=RGBQuantum;
540 if (image->alpha_trait != UndefinedPixelTrait)
541 quantum_type=RGBAQuantum;
542 if (image->colorspace == CMYKColorspace)
543 {
544 quantum_type=CMYKQuantum;
545 if (image->alpha_trait != UndefinedPixelTrait)
546 quantum_type=CMYKAQuantum;
547 }
548 if (IsGrayColorspace(image->colorspace) != MagickFalse)
549 {
550 quantum_type=GrayQuantum;
551 if (image->alpha_trait != UndefinedPixelTrait)
552 quantum_type=GrayAlphaQuantum;
553 }
554 if (image->storage_class == PseudoClass)
555 {
556 quantum_type=IndexQuantum;
557 if (image->alpha_trait != UndefinedPixelTrait)
558 quantum_type=IndexAlphaQuantum;
559 }
560 if (image->number_meta_channels != 0)
561 quantum_type=MultispectralQuantum;
562 return(quantum_type);
563}
564␌
565/*
566%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567% %
568% %
569% %
570+ R e s e t Q u a n t u m S t a t e %
571% %
572% %
573% %
574%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
575%
576% ResetQuantumState() resets the quantum state.
577%
578% The format of the ResetQuantumState method is:
579%
580% void ResetQuantumState(QuantumInfo *quantum_info)
581%
582% A description of each parameter follows:
583%
584% o quantum_info: the quantum info.
585%
586*/
587MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
588{
589 static const unsigned int mask[32] =
590 {
591 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
592 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
593 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
594 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
595 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
596 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
597 0x3fffffffU, 0x7fffffffU
598 };
599
600 assert(quantum_info != (QuantumInfo *) NULL);
601 assert(quantum_info->signature == MagickCoreSignature);
602 quantum_info->state.inverse_scale=1.0;
603 if (fabs(quantum_info->scale) >= MagickEpsilon)
604 quantum_info->state.inverse_scale/=quantum_info->scale;
605 quantum_info->state.pixel=0U;
606 quantum_info->state.bits=0U;
607 quantum_info->state.mask=mask;
608}
609␌
610/*
611%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612% %
613% %
614% %
615% S e t Q u a n t u m F o r m a t %
616% %
617% %
618% %
619%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
620%
621% SetQuantumAlphaType() sets the quantum format.
622%
623% The format of the SetQuantumAlphaType method is:
624%
625% void SetQuantumAlphaType(QuantumInfo *quantum_info,
626% const QuantumAlphaType type)
627%
628% A description of each parameter follows:
629%
630% o quantum_info: the quantum info.
631%
632% o type: the alpha type (e.g. associate).
633%
634*/
635MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
636 const QuantumAlphaType type)
637{
638 assert(quantum_info != (QuantumInfo *) NULL);
639 assert(quantum_info->signature == MagickCoreSignature);
640 quantum_info->alpha_type=type;
641}
642␌
643/*
644%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645% %
646% %
647% %
648% S e t Q u a n t u m D e p t h %
649% %
650% %
651% %
652%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
653%
654% SetQuantumDepth() sets the quantum depth.
655%
656% The format of the SetQuantumDepth method is:
657%
658% MagickBooleanType SetQuantumDepth(const Image *image,
659% QuantumInfo *quantum_info,const size_t depth)
660%
661% A description of each parameter follows:
662%
663% o image: the image.
664%
665% o quantum_info: the quantum info.
666%
667% o depth: the quantum depth.
668%
669*/
670MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
671 QuantumInfo *quantum_info,const size_t depth)
672{
673 /*
674 Allocate the quantum pixel buffer.
675 */
676 assert(image != (Image *) NULL);
677 assert(image->signature == MagickCoreSignature);
678 assert(quantum_info != (QuantumInfo *) NULL);
679 assert(quantum_info->signature == MagickCoreSignature);
680 if (IsEventLogging() != MagickFalse)
681 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
682 quantum_info->depth=MagickMin(depth,64);
683 if (quantum_info->format == FloatingPointQuantumFormat)
684 {
685 if (quantum_info->depth > 32)
686 quantum_info->depth=64;
687 else
688 if (quantum_info->depth > 24)
689 quantum_info->depth=32;
690 else
691 if (quantum_info->depth > 16)
692 quantum_info->depth=24;
693 else
694 quantum_info->depth=16;
695 }
696 return(SetQuantumExtent(image,quantum_info));
697}
698␌
699/*
700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701% %
702% %
703% %
704% S e t Q u a n t u m E n d i a n %
705% %
706% %
707% %
708%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709%
710% SetQuantumEndian() sets the quantum endian.
711%
712% The endian of the SetQuantumEndian method is:
713%
714% MagickBooleanType SetQuantumEndian(const Image *image,
715% QuantumInfo *quantum_info,const EndianType endian)
716%
717% A description of each parameter follows:
718%
719% o image: the image.
720%
721% o quantum_info: the quantum info.
722%
723% o endian: the quantum endian.
724%
725*/
726MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
727 QuantumInfo *quantum_info,const EndianType endian)
728{
729 assert(image != (Image *) NULL);
730 assert(image->signature == MagickCoreSignature);
731 assert(quantum_info != (QuantumInfo *) NULL);
732 assert(quantum_info->signature == MagickCoreSignature);
733 if (IsEventLogging() != MagickFalse)
734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
735 quantum_info->endian=endian;
736 return(SetQuantumExtent(image,quantum_info));
737}
738␌
739/*
740%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741% %
742% %
743% %
744% S e t Q u a n t u m E x t e n t %
745% %
746% %
747% %
748%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749%
750% SetQuantumExtent() sets the quantum pixel buffer extent.
751%
752% The format of the SetQuantumExtent method is:
753%
754% MagickBooleanType SetQuantumExtent(Image *image,
755% QuantumInfo *quantum_info)
756%
757% A description of each parameter follows:
758%
759% o image: the image.
760%
761% o quantum_info: the quantum info.
762%
763*/
764MagickExport MagickBooleanType SetQuantumExtent(const Image *image,
765 QuantumInfo *quantum_info)
766{
767 size_t
768 extent,
769 quantum;
770
771 /*
772 Speculative allocation since we don't yet know the quantum type.
773 */
774 assert(image != (Image *) NULL);
775 assert(image->signature == MagickCoreSignature);
776 assert(quantum_info != (QuantumInfo *) NULL);
777 assert(quantum_info->signature == MagickCoreSignature);
778 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
779 ((quantum_info->depth+7)/8)*sizeof(double);
780 extent=MagickMax(image->columns,image->rows)*quantum;
781 if ((MagickMax(image->columns,image->rows) != 0) &&
782 (quantum != (extent/MagickMax(image->columns,image->rows))))
783 return(MagickFalse);
784 if (quantum_info->pixels != (MemoryInfo **) NULL)
785 {
786 if (extent <= quantum_info->extent)
787 return(MagickTrue);
788 DestroyQuantumPixels(quantum_info);
789 }
790 return(AcquireQuantumPixels(quantum_info,extent));
791}
792␌
793/*
794%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795% %
796% %
797% %
798% S e t Q u a n t u m F o r m a t %
799% %
800% %
801% %
802%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803%
804% SetQuantumFormat() sets the quantum format.
805%
806% The format of the SetQuantumFormat method is:
807%
808% MagickBooleanType SetQuantumFormat(const Image *image,
809% QuantumInfo *quantum_info,const QuantumFormatType format)
810%
811% A description of each parameter follows:
812%
813% o image: the image.
814%
815% o quantum_info: the quantum info.
816%
817% o format: the quantum format.
818%
819*/
820MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
821 QuantumInfo *quantum_info,const QuantumFormatType format)
822{
823 assert(image != (Image *) NULL);
824 assert(image->signature == MagickCoreSignature);
825 assert(quantum_info != (QuantumInfo *) NULL);
826 assert(quantum_info->signature == MagickCoreSignature);
827 if (IsEventLogging() != MagickFalse)
828 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
829 quantum_info->format=format;
830 return(SetQuantumExtent(image,quantum_info));
831}
832␌
833/*
834%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835% %
836% %
837% %
838% S e t Q u a n t u m I m a g e T y p e %
839% %
840% %
841% %
842%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843%
844% SetQuantumImageType() sets the image type based on the quantum type.
845%
846% The format of the SetQuantumImageType method is:
847%
848% void ImageType SetQuantumImageType(Image *image,
849% const QuantumType quantum_type)
850%
851% A description of each parameter follows:
852%
853% o image: the image.
854%
855% o quantum_type: Declare which pixel components to transfer (red, green,
856% blue, opacity, RGB, or RGBA).
857%
858*/
859MagickExport void SetQuantumImageType(Image *image,
860 const QuantumType quantum_type)
861{
862 assert(image != (Image *) NULL);
863 assert(image->signature == MagickCoreSignature);
864 if (IsEventLogging() != MagickFalse)
865 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
866 switch (quantum_type)
867 {
868 case IndexQuantum:
869 case IndexAlphaQuantum:
870 {
871 image->type=PaletteType;
872 break;
873 }
874 case GrayQuantum:
875 case GrayAlphaQuantum:
876 {
877 image->type=GrayscaleType;
878 if (image->depth == 1)
879 image->type=BilevelType;
880 break;
881 }
882 case CyanQuantum:
883 case MagentaQuantum:
884 case YellowQuantum:
885 case BlackQuantum:
886 case CMYKQuantum:
887 case CMYKAQuantum:
888 case MultispectralQuantum:
889 {
890 image->type=ColorSeparationType;
891 break;
892 }
893 default:
894 {
895 image->type=TrueColorType;
896 break;
897 }
898 }
899}
900␌
901/*
902%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
903% %
904% %
905% %
906% S e t Q u a n t u m M e t a C h a n n e l %
907% %
908% %
909% %
910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
911%
912% SetQuantumMetaChannel() sets the quantum meta-channel that will exported or
913% imported when the quantum type is MultispectralQuantum. To unset the
914% meta-channel, set the meta-channel to -1.
915%
916% The format of the SetQuantumMetaChannel method is:
917%
918% void SetQuantumMetaChannel(const Image *image,QuantumInfo *quantum_info,
919% const ssize_t meta_channel)
920%
921% A description of each parameter follows:
922%
923% o image: the image.
924%
925% o quantum_info: the quantum info.
926%
927% o meta_channel: the meta channel.
928%
929*/
930MagickExport MagickBooleanType SetQuantumMetaChannel(const Image *image,
931 QuantumInfo *quantum_info, const ssize_t meta_channel)
932{
933 assert(quantum_info != (QuantumInfo *) NULL);
934 assert(quantum_info->signature == MagickCoreSignature);
935 if ((meta_channel < -1) ||
936 (meta_channel >= (ssize_t) image->number_meta_channels))
937 return(MagickFalse);
938 quantum_info->meta_channel=meta_channel+1;
939 return(MagickTrue);
940}
941␌
942/*
943%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
944% %
945% %
946% %
947% S e t Q u a n t u m P a c k %
948% %
949% %
950% %
951%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
952%
953% SetQuantumPack() sets the quantum pack flag.
954%
955% The format of the SetQuantumPack method is:
956%
957% void SetQuantumPack(QuantumInfo *quantum_info,
958% const MagickBooleanType pack)
959%
960% A description of each parameter follows:
961%
962% o quantum_info: the quantum info.
963%
964% o pack: the pack flag.
965%
966*/
967MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
968 const MagickBooleanType pack)
969{
970 assert(quantum_info != (QuantumInfo *) NULL);
971 assert(quantum_info->signature == MagickCoreSignature);
972 quantum_info->pack=pack;
973}
974␌
975/*
976%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977% %
978% %
979% %
980% S e t Q u a n t u m P a d %
981% %
982% %
983% %
984%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
985%
986% SetQuantumPad() sets the quantum pad.
987%
988% The format of the SetQuantumPad method is:
989%
990% MagickBooleanType SetQuantumPad(const Image *image,
991% QuantumInfo *quantum_info,const size_t pad)
992%
993% A description of each parameter follows:
994%
995% o image: the image.
996%
997% o quantum_info: the quantum info.
998%
999% o pad: the quantum pad.
1000%
1001*/
1002MagickExport MagickBooleanType SetQuantumPad(const Image *image,
1003 QuantumInfo *quantum_info,const size_t pad)
1004{
1005 assert(image != (Image *) NULL);
1006 assert(image->signature == MagickCoreSignature);
1007 assert(quantum_info != (QuantumInfo *) NULL);
1008 assert(quantum_info->signature == MagickCoreSignature);
1009 if (IsEventLogging() != MagickFalse)
1010 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1011 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
1012 return(MagickFalse);
1013 quantum_info->pad=pad;
1014 return(SetQuantumExtent(image,quantum_info));
1015}
1016␌
1017/*
1018%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1019% %
1020% %
1021% %
1022% S e t Q u a n t u m M i n I s W h i t e %
1023% %
1024% %
1025% %
1026%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1027%
1028% SetQuantumMinIsWhite() sets the quantum min-is-white flag.
1029%
1030% The format of the SetQuantumMinIsWhite method is:
1031%
1032% void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
1033% const MagickBooleanType min_is_white)
1034%
1035% A description of each parameter follows:
1036%
1037% o quantum_info: the quantum info.
1038%
1039% o min_is_white: the min-is-white flag.
1040%
1041*/
1042MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
1043 const MagickBooleanType min_is_white)
1044{
1045 assert(quantum_info != (QuantumInfo *) NULL);
1046 assert(quantum_info->signature == MagickCoreSignature);
1047 quantum_info->min_is_white=min_is_white;
1048}
1049␌
1050/*
1051%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1052% %
1053% %
1054% %
1055% S e t Q u a n t u m Q u a n t u m %
1056% %
1057% %
1058% %
1059%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1060%
1061% SetQuantumQuantum() sets the quantum quantum.
1062%
1063% The format of the SetQuantumQuantum method is:
1064%
1065% void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
1066%
1067% A description of each parameter follows:
1068%
1069% o quantum_info: the quantum info.
1070%
1071% o quantum: the quantum quantum.
1072%
1073*/
1074MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
1075 const size_t quantum)
1076{
1077 assert(quantum_info != (QuantumInfo *) NULL);
1078 assert(quantum_info->signature == MagickCoreSignature);
1079 quantum_info->quantum=quantum;
1080}
1081␌
1082/*
1083%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1084% %
1085% %
1086% %
1087% S e t Q u a n t u m S c a l e %
1088% %
1089% %
1090% %
1091%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1092%
1093% SetQuantumScale() sets the quantum scale.
1094%
1095% The format of the SetQuantumScale method is:
1096%
1097% void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1098%
1099% A description of each parameter follows:
1100%
1101% o quantum_info: the quantum info.
1102%
1103% o scale: the quantum scale.
1104%
1105*/
1106MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1107{
1108 assert(quantum_info != (QuantumInfo *) NULL);
1109 assert(quantum_info->signature == MagickCoreSignature);
1110 quantum_info->scale=scale;
1111}